diff options
author | David P <megver83@parabola.nu> | 2020-08-25 18:35:00 -0400 |
---|---|---|
committer | David P <megver83@parabola.nu> | 2020-08-25 19:30:56 -0400 |
commit | ea8efb8444c0fd31948c55efe0ec010945df9ac8 (patch) | |
tree | fcb4032675550ce4a9613d0b9546e662067f91a6 | |
parent | 7fed176391e60b175273bebe818bc20310900f05 (diff) |
sync with archiso
Imported changes:
4b40193 (HEAD -> master, tag: v47.1, origin/master, origin/HEAD) Add missing declaration of override_install_dir
d90184a (tag: v47) Pass profile directory as parameter to mkarchiso
e2c5b45 archiso/mkarchiso: reduce duplication and add more info messages
Signed-off-by: David P <megver83@parabola.nu>
-rw-r--r-- | README.rst | 8 | ||||
-rwxr-xr-x | configs/baseline/build.sh | 2 | ||||
-rwxr-xr-x | configs/lxde-openrc/build.sh | 2 | ||||
-rwxr-xr-x | configs/releng-openrc/build.sh | 2 | ||||
-rwxr-xr-x | configs/releng/build.sh | 2 | ||||
-rwxr-xr-x | configs/talkingparabola/build.sh | 2 | ||||
-rwxr-xr-x | parabolaiso/mkparabolaiso | 462 |
7 files changed, 277 insertions, 203 deletions
@@ -49,7 +49,7 @@ be lost on update). The examples below will assume an unmodified profile in a system location (unless noted otherwise). -It is advised to check the help information of the **mkparabolaiso**: +It is advised to consult the help output of **mkparabolaiso**: .. code:: bash @@ -60,7 +60,7 @@ Create images with packaged parabolaiso .. code:: bash - mkparabolaiso -B path/to/profile -w path/to/work_dir -o path/to/out_dir build_profile + mkparabolaiso -w path/to/work_dir -o path/to/out_dir path/to/profile Create images with local clone ------------------------------ @@ -69,7 +69,7 @@ Clone this repository and run: .. code:: bash - ./parabolaiso/mkparabolaiso -B path/to/profile -w path/to/work_dir -o path/to/out_dir build_profile + ./parabolaiso/mkparabolaiso -w path/to/work_dir -o path/to/out_dir path/to/profile Testing ======= @@ -91,7 +91,7 @@ Run the following to boot the iso using UEFI: .. code:: bash - run_parabolaiso -i path/to/an/parabola.iso -u + run_parabolaiso -u -i path/to/an/parabola.iso The script can of course also be executed from this repository: diff --git a/configs/baseline/build.sh b/configs/baseline/build.sh index 9a9f654..075d752 100755 --- a/configs/baseline/build.sh +++ b/configs/baseline/build.sh @@ -4,4 +4,4 @@ printf '\n[%s] WARNING: %s\n\n' "mkparabolaiso" "build.sh scripts are deprecated! Please use mkparabolaiso directly." >&2 _buildsh_path="$(realpath -- "$0")" -exec mkparabolaiso "$@" -B "${_buildsh_path%/*}" build_profile +exec mkparabolaiso "$@" "${_buildsh_path%/*}" diff --git a/configs/lxde-openrc/build.sh b/configs/lxde-openrc/build.sh index 9a9f654..075d752 100755 --- a/configs/lxde-openrc/build.sh +++ b/configs/lxde-openrc/build.sh @@ -4,4 +4,4 @@ printf '\n[%s] WARNING: %s\n\n' "mkparabolaiso" "build.sh scripts are deprecated! Please use mkparabolaiso directly." >&2 _buildsh_path="$(realpath -- "$0")" -exec mkparabolaiso "$@" -B "${_buildsh_path%/*}" build_profile +exec mkparabolaiso "$@" "${_buildsh_path%/*}" diff --git a/configs/releng-openrc/build.sh b/configs/releng-openrc/build.sh index 9a9f654..075d752 100755 --- a/configs/releng-openrc/build.sh +++ b/configs/releng-openrc/build.sh @@ -4,4 +4,4 @@ printf '\n[%s] WARNING: %s\n\n' "mkparabolaiso" "build.sh scripts are deprecated! Please use mkparabolaiso directly." >&2 _buildsh_path="$(realpath -- "$0")" -exec mkparabolaiso "$@" -B "${_buildsh_path%/*}" build_profile +exec mkparabolaiso "$@" "${_buildsh_path%/*}" diff --git a/configs/releng/build.sh b/configs/releng/build.sh index 9a9f654..075d752 100755 --- a/configs/releng/build.sh +++ b/configs/releng/build.sh @@ -4,4 +4,4 @@ printf '\n[%s] WARNING: %s\n\n' "mkparabolaiso" "build.sh scripts are deprecated! Please use mkparabolaiso directly." >&2 _buildsh_path="$(realpath -- "$0")" -exec mkparabolaiso "$@" -B "${_buildsh_path%/*}" build_profile +exec mkparabolaiso "$@" "${_buildsh_path%/*}" diff --git a/configs/talkingparabola/build.sh b/configs/talkingparabola/build.sh index 9a9f654..075d752 100755 --- a/configs/talkingparabola/build.sh +++ b/configs/talkingparabola/build.sh @@ -4,4 +4,4 @@ printf '\n[%s] WARNING: %s\n\n' "mkparabolaiso" "build.sh scripts are deprecated! Please use mkparabolaiso directly." >&2 _buildsh_path="$(realpath -- "$0")" -exec mkparabolaiso "$@" -B "${_buildsh_path%/*}" build_profile +exec mkparabolaiso "$@" "${_buildsh_path%/*}" diff --git a/parabolaiso/mkparabolaiso b/parabolaiso/mkparabolaiso index 51251f5..8d7c710 100755 --- a/parabolaiso/mkparabolaiso +++ b/parabolaiso/mkparabolaiso @@ -20,17 +20,23 @@ img_name="${app_name}.iso" sfs_mode="sfs" sfs_comp="xz" gpg_key="" +override_gpg_key="" # profile defaults profile="" iso_name="${app_name}" iso_label="${app_name^^}" +override_iso_label="" iso_publisher="${app_name}" +override_iso_publisher="" iso_application="${app_name} iso" +override_iso_application="" iso_version="" install_dir="${app_name}" -arch="${arch:-$(uname -m)}" +override_install_dir="" +arch="${arch:-$(uname -m)}" # leave $(uname -m) only in parabolaiso v49+ pacman_conf="/etc/pacman.conf" +override_pacman_conf="" bootmodes=() @@ -39,14 +45,13 @@ bootmodes=() _msg_info() { local _msg="${1}" [[ "${quiet}" == "y" ]] || printf '[%s] INFO: %s\n' "${app_name}" "${_msg}" - } # Show a WARNING message # $1: message string _msg_warning() { local _msg="${1}" - printf '\n[%s] WARNING: %s\n\n' "${app_name}" "${_msg}" >&2 + printf '[%s] WARNING: %s\n' "${app_name}" "${_msg}" >&2 } # Show an ERROR message then exit with status @@ -55,14 +60,14 @@ _msg_warning() { _msg_error() { local _msg="${1}" local _error=${2} - printf '\n[%s] ERROR: %s\n\n' "${app_name}" "${_msg}" >&2 + printf '[%s] ERROR: %s\n' "${app_name}" "${_msg}" >&2 if (( _error > 0 )); then exit "${_error}" fi } _chroot_init() { - mkdir -p -- "${airootfs_dir}" + install -d -m 0755 -o 0 -g 0 -- "${airootfs_dir}" _pacman base syslinux } @@ -72,96 +77,146 @@ _chroot_run() { _mount_airootfs() { trap "_umount_airootfs" EXIT HUP INT TERM - mkdir -p -- "${work_dir}/mnt/airootfs" - _msg_info "Mounting '${airootfs_dir}.img' on '${work_dir}/mnt/airootfs'" + install -d -m 0755 -- "${work_dir}/mnt/airootfs" + _msg_info "Mounting '${airootfs_dir}.img' on '${work_dir}/mnt/airootfs'..." mount -- "${airootfs_dir}.img" "${work_dir}/mnt/airootfs" _msg_info "Done!" } _umount_airootfs() { - _msg_info "Unmounting '${work_dir}/mnt/airootfs'" + _msg_info "Unmounting '${work_dir}/mnt/airootfs'..." umount -d -- "${work_dir}/mnt/airootfs" _msg_info "Done!" rmdir -- "${work_dir}/mnt/airootfs" trap - EXIT HUP INT TERM } +_mount_efibootimg() { + trap "_umount_efibootimg" EXIT HUP INT TERM + install -d -m 0755 -- "${work_dir}/mnt/efiboot" + _msg_info "Mounting '${isofs_dir}/EFI/parabolaiso/efiboot.img' on '${work_dir}/mnt/efiboot'..." + mount -- "${isofs_dir}/EFI/parabolaiso/efiboot.img" "${work_dir}/mnt/efiboot" + _msg_info "Done!" +} + +_umount_efibootimg() { + _msg_info "Unmounting '${work_dir}/mnt/efiboot'..." + umount -d -- "${work_dir}/mnt/efiboot" + _msg_info "Done!" + rmdir -- "${work_dir}/mnt/efiboot" + trap - EXIT HUP INT TERM +} + # Show help usage, with an exit status. # $1: exit status number. -_usage () { +_usage() { IFS='' read -r -d '' usagetext <<ENDUSAGETEXT || true -usage ${app_name} [options] command <command options> - general options: - -B <profile_dir> Directory of the parabolaiso profile to build - -p PACKAGE(S) Package(s) to install, can be used multiple times - -C <file> Config file for pacman. - Default: '${pacman_conf}' - -L <label> Set a label for the disk - Default: '${iso_label}' - -P <publisher> Set a publisher for the disk - Default: '${iso_publisher}' - -A <application> Set an application name for the disk - Default: '${iso_application}' - -D <install_dir> Set an install_dir. All files will by located here. - Default: '${install_dir}' - NOTE: Max 8 characters, use only [a-z0-9] - -w <work_dir> Set the working directory - Default: '${work_dir}' - -o <out_dir> Set the output directory - Default: '${out_dir}' - -s <sfs_mode> Set SquashFS image mode (img or sfs) - img: prepare airootfs.sfs for dm-snapshot usage - sfs: prepare airootfs.sfs for overlayfs usage - Default: '${sfs_mode}' - -c <comp_type> Set SquashFS compression type (gzip, lzma, lzo, xz, zstd) - Default: '${sfs_comp}' - -v Enable verbose output - -h This message - commands: - build_profile - build an iso image from a profile +usage ${app_name} [options] <profile_dir or legacy_command> + options: + -A <application> Set an application name for the ISO + Default: '${iso_application}' + -C <file> pacman configuration file. + Default: '${pacman_conf}' + -D <install_dir> Set an install_dir. All files will by located here. + Default: '${install_dir}' + NOTE: Max 8 characters, use only [a-z0-9] + -L <label> Set the ISO volume label + Default: '${iso_label}' + -P <publisher> Set the ISO publisher + Default: '${iso_publisher}' + -c <comp_type> Set SquashFS compression type (gzip, lzma, lzo, xz, zstd) + Default: '${sfs_comp}' + -g <gpg_key> Set the GPG key to be used for signing the sqashfs image + -h This message + -o <out_dir> Set the output directory + Default: '${out_dir}' + -p PACKAGE(S) Package(s) to install, can be used multiple times + -r <run_cmd> Set a command to be run in chroot (only relevant for for command_run) + NOTE: Deprecated, will be removed with parabolaiso v49 + -s <sfs_mode> Set SquashFS image mode (img or sfs) + img: prepare airootfs.sfs for dm-snapshot usage + sfs: prepare airootfs.sfs for overlayfs usage + Default: '${sfs_mode}' + -v Enable verbose output + -w <work_dir> Set the working directory + Default: '${work_dir}' + + profile_dir: Directory of the parabolaiso profile to build + + legacy_command: Legacy build.sh command + NOTE: Deprecated, will be removed with parabolaiso v49 + command_init + initialize a chroot for building + command_install + install packages to the chroot + command_run + run a command in the chroot + command_prepare + cleanup and prepare the airootfs + command_pkglist + create a list of packages installed on the medium + command_iso + create the ISO ENDUSAGETEXT - printf '%s\n' "${usagetext}" + printf '%s' "${usagetext}" exit "${1}" } # Shows configuration according to command mode. -# $1: init | install | run | prepare | iso -_show_config () { +# $1: build_profile | init | install | run | prepare | iso +_show_config() { local _mode="$1" - printf '\n' - _msg_info "Configuration settings" + _msg_info "${app_name} configuration settings" _msg_info " Command: ${command_name}" _msg_info " Architecture: ${arch}" _msg_info " Working directory: ${work_dir}" _msg_info " Installation directory: ${install_dir}" case "${_mode}" in + build_profile) + _msg_info " Output directory: ${out_dir}" + _msg_info " GPG key: ${gpg_key:-None}" + _msg_info " Profile: ${profile}" + _msg_info "Pacman configuration file: ${pacman_conf}" + _msg_info " Image file name: ${img_name}" + _msg_info " ISO volume label: ${iso_label}" + _msg_info " ISO publisher: ${iso_publisher}" + _msg_info " ISO application: ${iso_application}" + _msg_info " Boot modes: ${bootmodes[*]}" + _msg_info " Packages: ${pkg_list[*]}" + if [[ "${arch}" == "dual" ]]; then + _msg_info " Packages (x86_64): ${pkg_list_x86_64[*]:-None}" + _msg_info " Packages (i686): ${pkg_list_i686[*]:-None}" + fi + ;; init) - _msg_info " Pacman config file: ${pacman_conf}" + _msg_info "Pacman configuration file: ${pacman_conf}" ;; install) - _msg_info " Pacman config file: ${pacman_conf}" + _msg_info " GPG key: ${gpg_key:-None}" + _msg_info "Pacman configuration file: ${pacman_conf}" _msg_info " Packages: ${pkg_list[*]}" ;; run) _msg_info " Run command: ${run_cmd}" ;; prepare) + _msg_info " GPG key: ${gpg_key:-None}" ;; pkglist) ;; iso) - _msg_info " Image name: ${img_name}" - _msg_info " Disk label: ${iso_label}" - _msg_info " Disk publisher: ${iso_publisher}" - _msg_info " Disk application: ${iso_application}" + _msg_info " Output directory: ${out_dir}" + _msg_info " Image file name: ${img_name}" + _msg_info " ISO volume label: ${iso_label}" + _msg_info " ISO publisher: ${iso_publisher}" + _msg_info " ISO application: ${iso_application}" ;; esac - printf '\n' + [[ "${quiet}" == "y" ]] || printf '\n' } # Install desired packages to airootfs -_pacman () { +_pacman() { _msg_info "Installing packages to '${airootfs_dir}/'..." if [[ "${quiet}" = "y" ]]; then @@ -170,11 +225,11 @@ _pacman () { pacstrap -C "${pacman_conf}" -c -G -M -- "${airootfs_dir}" --arch "${arch}" "$@" fi - _msg_info "Packages installed successfully!" + _msg_info "Done! Packages installed successfully." } # Cleanup airootfs -_cleanup () { +_cleanup() { _msg_info "Cleaning up what we can on airootfs..." # Delete all files in /boot @@ -203,37 +258,37 @@ _cleanup () { fi # Delete package pacman related files. find "${work_dir}" \( -name '*.pacnew' -o -name '*.pacsave' -o -name '*.pacorig' \) -delete - _msg_info "Done!" # Create an empty /etc/machine-id printf '' > "${airootfs_dir}/etc/machine-id" + + _msg_info "Done!" } # Makes a ext4 filesystem inside a SquashFS from a source directory. -_mkairootfs_img () { +_mkairootfs_img() { if [[ ! -e "${airootfs_dir}" ]]; then _msg_error "The path '${airootfs_dir}' does not exist" 1 fi - _msg_info "Creating ext4 image of 32GiB..." - truncate -s 32G -- "${airootfs_dir}.img" + _msg_info "Creating ext4 image of 32 GiB..." if [[ "${quiet}" == "y" ]]; then - mkfs.ext4 -q -O '^has_journal,^resize_inode' -E 'lazy_itable_init=0' -m 0 -F -- "${airootfs_dir}.img" + mkfs.ext4 -q -O '^has_journal,^resize_inode' -E 'lazy_itable_init=0' -m 0 -F -- "${airootfs_dir}.img" 32G else - mkfs.ext4 -O '^has_journal,^resize_inode' -E 'lazy_itable_init=0' -m 0 -F -- "${airootfs_dir}.img" + mkfs.ext4 -O '^has_journal,^resize_inode' -E 'lazy_itable_init=0' -m 0 -F -- "${airootfs_dir}.img" 32G fi - tune2fs -c 0 -i 0 -- "${airootfs_dir}.img" &> /dev/null + tune2fs -c 0 -i 0 -- "${airootfs_dir}.img" > /dev/null _msg_info "Done!" _mount_airootfs _msg_info "Copying '${airootfs_dir}/' to '${work_dir}/mnt/airootfs/'..." cp -aT -- "${airootfs_dir}/" "${work_dir}/mnt/airootfs/" - chown root:root -- "${work_dir}/mnt/airootfs/" + chown -- 0:0 "${work_dir}/mnt/airootfs/" _msg_info "Done!" _umount_airootfs - mkdir -p -- "${isofs_dir}/${install_dir}/${arch}" + install -d -m 0755 -- "${isofs_dir}/${install_dir}/${arch}" _msg_info "Creating SquashFS image, this may take some time..." if [[ "${quiet}" = "y" ]]; then mksquashfs "${airootfs_dir}.img" "${isofs_dir}/${install_dir}/${arch}/airootfs.sfs" -noappend \ - -comp "${sfs_comp}" -no-progress &> /dev/null + -comp "${sfs_comp}" -no-progress > /dev/null else mksquashfs "${airootfs_dir}.img" "${isofs_dir}/${install_dir}/${arch}/airootfs.sfs" -noappend \ -comp "${sfs_comp}" @@ -243,16 +298,16 @@ _mkairootfs_img () { } # Makes a SquashFS filesystem from a source directory. -_mkairootfs_sfs () { +_mkairootfs_sfs() { if [[ ! -e "${airootfs_dir}" ]]; then _msg_error "The path '${airootfs_dir}' does not exist" 1 fi - mkdir -p -- "${isofs_dir}/${install_dir}/${arch}" + install -d -m 0755 -- "${isofs_dir}/${install_dir}/${arch}" _msg_info "Creating SquashFS image, this may take some time..." if [[ "${quiet}" = "y" ]]; then mksquashfs "${airootfs_dir}" "${isofs_dir}/${install_dir}/${arch}/airootfs.sfs" -noappend \ - -comp "${sfs_comp}" -no-progress &> /dev/null + -comp "${sfs_comp}" -no-progress > /dev/null else mksquashfs "${airootfs_dir}" "${isofs_dir}/${install_dir}/${arch}/airootfs.sfs" -noappend \ -comp "${sfs_comp}" @@ -260,7 +315,7 @@ _mkairootfs_sfs () { _msg_info "Done!" } -_mkchecksum () { +_mkchecksum() { _msg_info "Creating checksum file for self-test..." cd -- "${isofs_dir}/${install_dir}/${arch}" sha512sum airootfs.sfs > airootfs.sha512 @@ -268,8 +323,8 @@ _mkchecksum () { _msg_info "Done!" } -_mksignature () { - _msg_info "Creating signature file..." +_mksignature() { + _msg_info "Signing SquashFS image..." cd -- "${isofs_dir}/${install_dir}/${arch}" gpg --detach-sign --default-key "${gpg_key}" airootfs.sfs cd -- "${OLDPWD}" @@ -294,10 +349,12 @@ _make_pacman_conf() { # Prepare working directory and copy custom airootfs files (airootfs) _make_custom_airootfs() { - mkdir -m 755 -- "${airootfs_dir}" - local passwd=() + + install -d -m 0755 -o 0 -g 0 -- "${airootfs_dir}" + if [[ -d "${profile}/airootfs" ]]; then + _msg_info "Copying custom custom airootfs files and setting up user home directories..." cp -af --no-preserve=ownership -- "${profile}/airootfs/." "${airootfs_dir}" [[ -e "${airootfs_dir}/etc/shadow" ]] && chmod -f 0400 -- "${airootfs_dir}/etc/shadow" @@ -317,6 +374,7 @@ _make_custom_airootfs() { fi done < "${airootfs_dir}/etc/passwd" fi + _msg_info "Done!" fi } @@ -338,23 +396,26 @@ _make_packages() { # Customize installation (airootfs) _make_customize_airootfs() { local passwd=() + if [[ -e "${profile}/airootfs/etc/passwd" ]]; then + _msg_info "Copying /etc/skel/* to user homes..." while IFS=':' read -a passwd -r; do - if [[ "${passwd[5]}" == '/' ]]; then - continue - fi + [[ "${passwd[5]}" == '/' ]] && continue + [[ -z "${passwd[5]}" ]] && continue cp -RdT --preserve=mode,timestamps,links -- "${airootfs_dir}/etc/skel" "${airootfs_dir}${passwd[5]}" chown -hR -- "${passwd[2]}:${passwd[3]}" "${airootfs_dir}${passwd[5]}" done < "${profile}/airootfs/etc/passwd" + _msg_info "Done!" fi if [[ -e "${airootfs_dir}/root/customize_airootfs.sh" ]]; then + _msg_info "Running customize_airootfs.sh in '${airootfs_dir}' chroot..." _msg_warning "customize_airootfs.sh is deprecated! Support for it will be removed in a future parabolaiso version." local run_cmd="/root/customize_airootfs.sh" - local work_dir="${work_dir}/${arch}" - command_run + _chroot_run rm -- "${airootfs_dir}/root/customize_airootfs.sh" + _msg_info "Done! customize_airootfs.sh run successfully." fi } @@ -372,14 +433,19 @@ _make_bootmodes() { # Prepare kernel/initramfs ${install_dir}/boot/ _make_boot_on_iso() { - mkdir -p -- "${isofs_dir}/${install_dir}/boot/${arch}" + local airootfs_dir="${work_dir}/${arch}/airootfs" + + _msg_info "Preparing kernel and intramfs for the ISO 9660 file system..." + install -d -m 0755 -- "${isofs_dir}/${install_dir}/boot/${arch}" install -m 0644 -- "${airootfs_dir}/boot/parabolaiso.img" "${isofs_dir}/${install_dir}/boot/${arch}/" install -m 0644 -- "${airootfs_dir}/boot/vmlinuz-linux-libre" "${isofs_dir}/${install_dir}/boot/${arch}/" + _msg_info "Done!" } # Prepare /${install_dir}/boot/syslinux _make_boot_bios.syslinux.mbr() { - mkdir -p "${isofs_dir}/${install_dir}/boot/syslinux" + _msg_info "Setting up SYSLINUX for BIOS booting from a disk..." + install -d -m 0755 -- "${isofs_dir}/${install_dir}/boot/syslinux" for _cfg in "${profile}/syslinux/"*.cfg; do sed "s|%PARABOLAISO_LABEL%|${iso_label}|g; s|%INSTALL_DIR%|${install_dir}|g; @@ -395,15 +461,14 @@ _make_boot_bios.syslinux.mbr() { if [[ "${arch}" == "dual" ]]; then for arch in i686 x86_64; do - local airootfs_dir="${work_dir}/${arch}/airootfs" - _make_boot_on_iso + _run_once _make_boot_on_iso done else - _make_boot_on_iso + _run_once _make_boot_on_iso fi _uname_r=$(file -b "${isofs_dir}/${install_dir}/boot/${arch}/vmlinuz-linux-libre" | awk 'f{print;f=0} /version/{f=1}' RS=' ') - mkdir -p "${isofs_dir}/${install_dir}/boot/syslinux/hdt" + install -d -m 0755 -- "${isofs_dir}/${install_dir}/boot/syslinux/hdt" gzip -c -9 "${airootfs_dir}/usr/share/hwdata/pci.ids" > \ "${isofs_dir}/${install_dir}/boot/syslinux/hdt/pciids.gz" gzip -c -9 "${airootfs_dir}/usr/lib/modules/${_uname_r}/modules.alias" > \ @@ -413,15 +478,17 @@ _make_boot_bios.syslinux.mbr() { if [[ -e "${airootfs_dir}/boot/memtest86+/memtest.bin" ]]; then # rename for PXE: https://wiki.parabola.nu/index.php/Syslinux#Using_memtest install -m 0644 -- "${airootfs_dir}/boot/memtest86+/memtest.bin" "${isofs_dir}/${install_dir}/boot/memtest" - mkdir -p "${isofs_dir}/${install_dir}/boot/licenses/memtest86+/" + install -d -m 0755 -- "${isofs_dir}/${install_dir}/boot/licenses/memtest86+/" install -m 0644 -- "${airootfs_dir}/usr/share/licenses/common/GPL2/license.txt" \ "${isofs_dir}/${install_dir}/boot/licenses/memtest86+/" fi + _msg_info "Done! SYSLINUX set up for BIOS booting from a disk successfully." } # Prepare /isolinux _make_boot_bios.syslinux.eltorito() { - mkdir -p "${isofs_dir}/isolinux" + _msg_info "Setting up SYSLINUX for BIOS booting from an optical disc..." + install -d -m 0755 -- "${isofs_dir}/isolinux" sed "s|%PARABOLAISO_LABEL%|${iso_label}|g; s|%INSTALL_DIR%|${install_dir}|g; s|%ARCH%|${arch}|g" \ @@ -432,15 +499,18 @@ _make_boot_bios.syslinux.eltorito() { # isolinux.cfg loads syslinux.cfg _run_once _make_boot_bios.syslinux.mbr + + _msg_info "Done! SYSLINUX set up for BIOS booting from an optical disc successfully." } # Prepare /EFI on ISO-9660 _make_efi() { - mkdir -p "${isofs_dir}/EFI/BOOT" + _msg_info "Preparing an /EFI directory for the ISO 9660 file system..." + install -d -m 0755 -- "${isofs_dir}/EFI/BOOT" install -m 0644 -- "${airootfs_dir}/usr/lib/systemd/boot/efi/systemd-bootx64.efi" \ "${isofs_dir}/EFI/BOOT/BOOTx64.EFI" - mkdir -p "${isofs_dir}/loader/entries" + install -d -m 0755 -- "${isofs_dir}/loader/entries" install -m 0644 -- "${profile}/efiboot/loader/loader.conf" "${isofs_dir}/loader/" sed "s|%PARABOLAISO_LABEL%|${iso_label}|g; @@ -457,17 +527,19 @@ _make_efi() { } _make_refind_efi() { - mkdir -p "${isofs_dir}/EFI/boot/entries" + _msg_info "Preparing an /EFI directory for the ISO 9660 file system..." + install -d -m 0755 -- "${isofs_dir}/EFI/BOOT" install -m 0644 -- "${airootfs_dir}/usr/share/refind/refind_x64.efi" \ - "${isofs_dir}/EFI/boot/bootx64.efi" + "${isofs_dir}/EFI/BOOT/BOOTx64.EFI" - install -m 0644 -- "${profile}/efiboot/EFI/boot/refind.conf" "${isofs_dir}/EFI/boot/" + install -d -m 0755 -- "${isofs_dir}/EFI/BOOT/entries" + install -m 0644 -- "${profile}/efiboot/EFI/BOOT/refind.conf" "${isofs_dir}/EFI/BOOT/" sed "s|%PARABOLAISO_LABEL%|${iso_label}|g; s|%INSTALL_DIR%|${install_dir}|g; s|%ARCH%|${arch}|g" \ - "${profile}/efiboot/EFI/boot/entries/parabolaiso-x86_64-usb.conf" > \ - "${isofs_dir}/EFI/boot/entries/parabolaiso-x86_64.conf" + "${profile}/efiboot/EFI/BOOT/entries/parabolaiso-x86_64-usb.conf" > \ + "${isofs_dir}/EFI/BOOT/entries/parabolaiso-x86_64.conf" # edk2-shell based UEFI shell # shellx64.efi is picked up automatically when on / @@ -478,71 +550,77 @@ _make_refind_efi() { # Prepare kernel/initramfs on efiboot.img _make_boot_on_fat() { - mkdir -p "${work_dir}/efiboot/EFI/parabolaiso" - install -m 0644 -- "${airootfs_dir}/boot/vmlinuz-linux-libre" "${work_dir}/efiboot/EFI/parabolaiso/" - install -m 0644 -- "${isofs_dir}/${install_dir}/boot/${arch}/parabolaiso.img" "${work_dir}/efiboot/EFI/parabolaiso/" + _msg_info "Preparing kernel and intramfs for the FAT file system..." + install -d -m 0755 -- "${work_dir}/mnt/efiboot/EFI/parabolaiso" + install -m 0644 -- "${airootfs_dir}/boot/vmlinuz-linux-libre" "${work_dir}/mnt/efiboot/EFI/parabolaiso/" + install -m 0644 -- "${airootfs_dir}/boot/parabolaiso.img" "${work_dir}/mnt/efiboot/EFI/parabolaiso/" + _msg_info "Done!" } # Prepare efiboot.img::/EFI for EFI boot mode _make_boot_uefi-x64.systemd-boot.esp() { - mkdir -p "${isofs_dir}/EFI/parabolaiso" + _msg_info "Setting up systemd-boot for UEFI booting..." + install -d -m 0755 -- "${isofs_dir}/EFI/parabolaiso" mkfs.fat -C -n parabolaiso_EFI "${isofs_dir}/EFI/parabolaiso/efiboot.img" 65536 - mkdir -p "${work_dir}/efiboot" - mount "${isofs_dir}/EFI/parabolaiso/efiboot.img" "${work_dir}/efiboot" + _mount_efibootimg - mkdir -p "${work_dir}/efiboot/EFI/BOOT" + install -d -m 0755 -- "${work_dir}/mnt/efiboot/EFI/BOOT" install -m 0644 -- "${airootfs_dir}/usr/lib/systemd/boot/efi/systemd-bootx64.efi" \ - "${work_dir}/efiboot/EFI/BOOT/BOOTx64.EFI" + "${work_dir}/mnt/efiboot/EFI/BOOT/BOOTx64.EFI" - mkdir -p "${work_dir}/efiboot/loader/entries" - install -m 0644 -- "${profile}/efiboot/loader/loader.conf" "${work_dir}/efiboot/loader/" + install -d -m 0755 -- "${work_dir}/mnt/efiboot/loader/entries" + install -m 0644 -- "${profile}/efiboot/loader/loader.conf" "${work_dir}/mnt/efiboot/loader/" sed "s|%PARABOLAISO_LABEL%|${iso_label}|g; s|%INSTALL_DIR%|${install_dir}|g; s|%ARCH%|${arch}|g" \ "${profile}/efiboot/loader/entries/parabolaiso-x86_64-cd.conf" > \ - "${work_dir}/efiboot/loader/entries/parabolaiso-x86_64.conf" + "${work_dir}/mnt/efiboot/loader/entries/parabolaiso-x86_64.conf" # shellx64.efi is picked up automatically when on / if [[ -e "${airootfs_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" ]]; then - install -m 0644 -- "${airootfs_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" "${work_dir}/efiboot/shellx64.efi" + install -m 0644 -- "${airootfs_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" "${work_dir}/mnt/efiboot/shellx64.efi" fi # Copy kernel and initramfs - _make_boot_on_fat + _run_once _make_boot_on_fat + + _umount_efibootimg - umount -d "${work_dir}/efiboot" + _msg_info "Done! systemd-boot set up for UEFI booting successfully." } _make_boot_uefi-x64.refind.esp() { - mkdir -p "${isofs_dir}/EFI/parabolaiso" + _msg_info "Setting up rEFInd for UEFI booting..." + install -d -m 0755 -- "${isofs_dir}/EFI/parabolaiso" mkfs.fat -C -n parabolaiso_EFI "${isofs_dir}/EFI/parabolaiso/efiboot.img" 65536 - mkdir -p "${work_dir}/efiboot" - mount "${isofs_dir}/EFI/parabolaiso/efiboot.img" "${work_dir}/efiboot" + _mount_efibootimg - mkdir -p "${work_dir}/efiboot/EFI/boot/entries" + install -d -m 0755 -- "${work_dir}/mnt/efiboot/EFI/BOOT/entries" install -m 0644 -- "${airootfs_dir}/usr/share/refind/refind_x64.efi" \ - "${work_dir}/efiboot/EFI/boot/bootx64.efi" + "${work_dir}/mnt/efiboot/EFI/BOOT/BOOTx64.EFI" - install -m 0644 -- "${profile}/efiboot/EFI/boot/refind.conf" "${work_dir}/efiboot/EFI/boot/" + install -m 0644 -- "${profile}/efiboot/EFI/BOOT/refind.conf" "${work_dir}/mnt/efiboot/EFI/BOOT/" sed "s|%PARABOLAISO_LABEL%|${iso_label}|g; s|%INSTALL_DIR%|${install_dir}|g; s|%ARCH%|${arch}|g" \ - "${profile}/efiboot/EFI/boot/entries/parabolaiso-x86_64-cd.conf" > \ - "${work_dir}/efiboot/EFI/boot/entries/parabolaiso-x86_64.conf" + "${profile}/efiboot/EFI/BOOT/entries/parabolaiso-x86_64-cd.conf" > \ + "${work_dir}/mnt/efiboot/EFI/BOOT/entries/parabolaiso-x86_64.conf" # shellx64.efi is picked up automatically when on / if [[ -e "${airootfs_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" ]]; then - install -m 0644 -- "${airootfs_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" "${work_dir}/efiboot/shellx64.efi" + install -m 0644 -- "${airootfs_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" "${work_dir}/mnt/efiboot/shellx64.efi" fi # Copy kernel and initramfs - _make_boot_on_fat + _run_once _make_boot_on_fat + + _umount_efibootimg - umount -d "${work_dir}/efiboot" + _msg_info "Done! rEFInd set up for UEFI booting successfully." } # Prepare efiboot.img::/EFI for "El Torito" EFI boot mode @@ -575,6 +653,8 @@ _make_prepare() { _make_iso() { local xorrisofs_options=() + [[ -d "${out_dir}" ]] || install -d -- "${out_dir}" + if [[ "${quiet}" == "y" ]]; then xorrisofs_options+=('-quiet') fi @@ -617,11 +697,12 @@ _make_iso() { "${xorrisofs_options[@]}" \ -output "${out_dir}/${img_name}" \ "${isofs_dir}/" - _msg_info "Done! | $(du -h -- "${out_dir}/${img_name}")" + _msg_info "Done!" + du -h -- "${out_dir}/${img_name}" } # Read profile's values from profiledef.sh -_read_profile () { +_read_profile() { if [[ -z "${profile}" ]]; then _msg_error "No profile specified!" 1 fi @@ -630,10 +711,11 @@ _read_profile () { elif [[ ! -e "${profile}/profiledef.sh" ]]; then _msg_error "Profile '${profile}' is missing 'profiledef.sh'!" 1 else + cd -- "${profile}" + # Source profile's variables # shellcheck source=configs/releng/profiledef.sh . "${profile}/profiledef.sh" - cd -- "${profile}" if [[ "${arch}" == "dual" ]]; then # Resolve paths @@ -646,9 +728,6 @@ _read_profile () { if [[ "${pkgs##*/}" = "packages.both" ]]; then [[ -e "${pkgs}" ]] || _msg_error "File '${pkgs}' does not exist!" 1 mapfile -t pkg_list < <(sed '/^[[:blank:]]*#.*/d;s/#.*//;/^[[:blank:]]*$/d' "${pkgs}") - if (( ${#pkg_list[@]} == 0 )); then - _msg_error "'${pkgs}' does not list any packages!" 1 - fi elif [[ -e "${pkgs}" ]]; then mapfile -t "pkg_list_${pkgs##*.}" < <(sed '/^[[:blank:]]*#.*/d;s/#.*//;/^[[:blank:]]*$/d' "${pkgs}") fi @@ -661,43 +740,32 @@ _read_profile () { # Enumerate packages [[ -e "${packages}" ]] || _msg_error "File '${packages}' does not exist!" 1 mapfile -t pkg_list < <(sed '/^[[:blank:]]*#.*/d;s/#.*//;/^[[:blank:]]*$/d' "${packages}") - if (( ${#pkg_list[@]} == 0 )); then - _msg_error "'${packages}' does not list any packages!" 1 - fi fi cd -- "${OLDPWD}" fi } -_set_up_directories() { - local directory - for directory in "${work_dir}" "${out_dir}" "${work_dir}/${arch}" "${isofs_dir}" "${isofs_dir}/${install_dir}"; do - [[ -d "${directory}" ]] || mkdir -m 0755 -- "${directory}" - done -} - -_print_settings() { - _msg_info "${app_name} configuration settings" - _msg_info " Command: ${command_name}" - _msg_info " Working directory: ${work_dir}" - _msg_info " Output directory: ${out_dir}" - _msg_info " GPG key: ${gpg_key:-None}" - _msg_info "Profile configuration settings" - _msg_info " Profile: ${profile}" - _msg_info " Architecture: ${arch}" - _msg_info " Image name: ${img_name}" - _msg_info " Disk label: ${iso_label}" - _msg_info " Disk publisher: ${iso_publisher}" - _msg_info " Disk application: ${iso_application}" - _msg_info " Installation directory: ${install_dir}" - _msg_info " Pacman config file: ${pacman_conf}" - _msg_info " Packages: ${pkg_list[*]}" - if [[ "${arch}" == "dual" ]]; then - _msg_info " Packages (x86_64): ${pkg_list_x86_64[*]:-None}" - _msg_info " Packages (i686): ${pkg_list_i686[*]:-None}" +# set overrides from mkparabolaiso option parameters, if present +_set_overrides() { + if [[ -n "$override_iso_label" ]]; then + iso_label="$override_iso_label" + fi + if [[ -n "$override_iso_publisher" ]]; then + iso_publisher="$override_iso_publisher" + fi + if [[ -n "$override_iso_application" ]]; then + iso_application="$override_iso_application" + fi + if [[ -n "$override_install_dir" ]]; then + install_dir="$override_install_dir" + fi + if [[ -n "$override_pacman_conf" ]]; then + pacman_conf="$override_pacman_conf" + fi + if [[ -n "$override_gpg_key" ]]; then + gpg_key="$override_gpg_key" fi - _msg_info " Boot modes: ${bootmodes[*]}" } _export_gpg_publickey() { @@ -708,18 +776,19 @@ _export_gpg_publickey() { _make_pkglist() { + install -d -m 0755 -- "${isofs_dir}/${install_dir}" _msg_info "Creating a list of installed packages on live-enviroment..." pacman -Q --sysroot "${airootfs_dir}" > "${isofs_dir}/${install_dir}/pkglist.${arch}.txt" _msg_info "Done!" } -command_pkglist () { - _show_config pkglist +command_pkglist() { + _show_config "${FUNCNAME[0]#command_}" _make_pkglist } # Create an ISO9660 filesystem from "iso" directory. -command_iso () { +command_iso() { bootmodes=('bios.syslinux.mbr' 'bios.syslinux.eltorito') # If exists, add an EFI "El Torito" boot image (FAT filesystem) to ISO-9660 image. @@ -731,14 +800,13 @@ command_iso () { fi fi - _show_config iso - mkdir -p -- "${out_dir}" + _show_config "${FUNCNAME[0]#command_}" _make_iso } # create airootfs.sfs filesystem, and push it in "iso" directory. -command_prepare () { - _show_config prepare +command_prepare() { + _show_config "${FUNCNAME[0]#command_}" _cleanup _make_prepare @@ -746,7 +814,7 @@ command_prepare () { # Install packages on airootfs. # A basic check to avoid double execution/reinstallation is done via hashing package names. -command_install () { +command_install() { if [[ ! -f "${pacman_conf}" ]]; then _msg_error "Pacman config file '${pacman_conf}' does not exist" 1 fi @@ -756,18 +824,18 @@ command_install () { _usage 1 fi - _show_config install + _show_config "${FUNCNAME[0]#command_}" _make_packages } command_init() { - _show_config init + _show_config "${FUNCNAME[0]#command_}" _chroot_init } command_run() { - _show_config run + _show_config "${FUNCNAME[0]#command_}" _chroot_run } @@ -779,10 +847,11 @@ command_build_profile() { img_name="${iso_name}-${iso_version}-${arch}.iso" if [[ "${arch}" == "dual" ]]; then - _print_settings - for arch in i686 x86_64; do - _run_once _set_up_directories - done + _show_config "${FUNCNAME[0]#command_}" + + # Create working directory + [[ -d "${work_dir}" ]] || install -d -- "${work_dir}" + _run_once _make_pacman_conf _run_once _export_gpg_publickey for arch in i686 x86_64; do @@ -795,6 +864,7 @@ command_build_profile() { _run_once _make_customize_airootfs done for arch in i686 x86_64; do + airootfs_dir="${work_dir}/${arch}/airootfs" _run_once _make_pkglist done arch="dual" @@ -806,8 +876,11 @@ command_build_profile() { done _run_once _make_iso else - _print_settings - _run_once _set_up_directories + _show_config "${FUNCNAME[0]#command_}" + + # Create working directory + [[ -d "${work_dir}" ]] || install -d -- "${work_dir}" + _run_once _make_pacman_conf _run_once _export_gpg_publickey _run_once _make_custom_airootfs @@ -821,27 +894,22 @@ command_build_profile() { fi } -while getopts 'B:p:r:C:L:P:A:D:w:o:s:c:g:dvh' arg; do +while getopts 'p:r:C:L:P:A:D:w:o:s:c:g:vh?' arg; do case "${arg}" in - B) - profile="$(realpath -- "${OPTARG}")" - _read_profile - ;; p) read -r -a opt_pkg_list <<< "${OPTARG}" pkg_list+=("${opt_pkg_list[@]}") ;; - r) run_cmd="${OPTARG}" ;; - C) pacman_conf="$(realpath -- "${OPTARG}")" ;; - L) iso_label="${OPTARG}" ;; - P) iso_publisher="${OPTARG}" ;; - A) iso_application="${OPTARG}" ;; - D) install_dir="${OPTARG}" ;; + C) override_pacman_conf="$(realpath -- "${OPTARG}")" ;; + L) override_iso_label="${OPTARG}" ;; + P) override_iso_publisher="${OPTARG}" ;; + A) override_iso_application="${OPTARG}" ;; + D) override_install_dir="${OPTARG}" ;; w) work_dir="$(realpath -- "${OPTARG}")" ;; o) out_dir="$(realpath -- "${OPTARG}")" ;; s) sfs_mode="${OPTARG}" ;; c) sfs_comp="${OPTARG}" ;; - g) gpg_key="${OPTARG}" ;; + g) override_gpg_key="${OPTARG}" ;; v) quiet="n" ;; h|?) _usage 0 ;; *) @@ -863,46 +931,52 @@ if (( $# < 1 )); then fi command_name="${1}" -# Set directory path defaults +# Set directory path defaults for legacy commands airootfs_dir="${work_dir}/airootfs" isofs_dir="${work_dir}/iso" case "${command_name}" in init) - _msg_warning "The '${command_name}' command is deprecated!" + _msg_warning "The '${command_name}' command is deprecated! It will be removed with parabolaiso v49." + _set_overrides command_init ;; install) - _msg_warning "The '${command_name}' command is deprecated!" + _msg_warning "The '${command_name}' command is deprecated! It will be removed with parabolaiso v49." + _set_overrides command_install ;; run) - _msg_warning "The '${command_name}' command is deprecated!" + _msg_warning "The '${command_name}' command is deprecated! It will be removed with parabolaiso v49." command_run ;; prepare) - _msg_warning "The '${command_name}' command is deprecated!" + _msg_warning "The '${command_name}' command is deprecated! It will be removed with parabolaiso v49." + _set_overrides command_prepare ;; pkglist) - _msg_warning "The '${command_name}' command is deprecated!" + _msg_warning "The '${command_name}' command is deprecated! It will be removed with parabolaiso v49." command_pkglist ;; iso) - _msg_warning "The '${command_name}' command is deprecated!" + _msg_warning "The '${command_name}' command is deprecated! It will be removed with parabolaiso v49." if (( $# < 2 )); then _msg_error "No image specified" 0 _usage 1 fi img_name="${2}" + _set_overrides command_iso ;; - build_profile) - command_build_profile - ;; *) - _msg_error "Invalid command name '${command_name}'" 0 - _usage 1 + # NOTE: we call read_profile here, assuming that the first non-option parameter is a profile directory + # This way we can retain backwards compatibility with legacy build.sh scripts until we deprecate the old way of + # calling mkparabolaiso with named parameters in v49 + profile="$(realpath -- "${command_name}")" + _read_profile + _set_overrides + command_build_profile ;; esac |