summaryrefslogtreecommitdiff
path: root/parabolaiso
diff options
context:
space:
mode:
authorDavid P <megver83@parabola.nu>2021-06-30 16:22:12 -0400
committerDavid P <megver83@parabola.nu>2021-07-05 16:57:40 -0400
commit47dd6e46e5bb03f6968d5f34e12434d0007c702e (patch)
tree2a60c531abd6af414796cbc899a54290862269b0 /parabolaiso
parent79b988553b2707aed9fba21dd53033a7a011af6f (diff)
sync with archiso v54v54
Imported changes: 28ab118 (tag: v54) Add changelog for v54 9827cb1 ci: Use environment variables to override build settings cde7296 ci: Consolidate build-host script 8e44a8b ci: consolidate build script d0d4fa5 configs/releng/airootfs/etc/systemd/system/pacman-init.service: don't hardcode the keyrings 3678bba configs/releng/packages.x86_64: explicitly add wanted packages instead of relying on pulling them in as dependencies bd2b861 configs/*: add VM guest packages and enable their services f86cb0f ci: Expand parallel matrix with build modes 5630a23 ci: build based on buildmodes 6b11d7b mkarchiso: Also create package list for netboot ace88aa Update project documentation related to netboot 4d1e898 docs: Add netboot to buildmodes documentation d54bf63 mkarchiso: Add buildmode to export netboot artifacts 1fed84c Extend project overview with info on bootstrap images 1630d76 docs: Add documentation for buildmodes and bootstrap build mode 2cac539 mkarchiso: Implement buildmodes that allow building bootstrap images 535bc3c baseline: Add bootstrap packages file b7fd696 baseline: Add buildmodes to profiledef.sh 6afa695 releng: Add buildmodes to profiledef.sh 9c84b7c releng: Add packages file for bootstrap image 2a07aa2 Increase timeout for initial prompt in build VM 4b14350 Use QEMU 6.x options c58b44f Use QEMU 6.x options Parabola changes: * add dual architecture support for bootstrap buildmode by creating two separated tarballs * sync openrc profiles with releng updates * disable haveged initscript since we removed it from the packages list * add speakup_soft kernel module in openrc profiles to make espeakup work TODO: * add braille support for GUI lxde-openrc (w/orca?) NOTE: We don't have/use CI (Arch uses GitLab), so we don't import those changes Signed-off-by: David P <megver83@parabola.nu>
Diffstat (limited to 'parabolaiso')
-rwxr-xr-xparabolaiso/mkparabolaiso594
1 files changed, 449 insertions, 145 deletions
diff --git a/parabolaiso/mkparabolaiso b/parabolaiso/mkparabolaiso
index 6f04947..db49ba7 100755
--- a/parabolaiso/mkparabolaiso
+++ b/parabolaiso/mkparabolaiso
@@ -14,10 +14,10 @@ app_name="${0##*/}"
# Define global variables. All of them will be overwritten later
pkg_list=()
+bootstrap_pkg_list=()
quiet=""
work_dir=""
out_dir=""
-img_name=""
gpg_key=""
iso_name=""
iso_label=""
@@ -29,9 +29,15 @@ arch=""
pacman_conf=""
packages=""
packages_dual=""
+bootstrap_packages=""
+bootstrap_packages_dual=""
+pacstrap_dir=""
+buildmodes=()
bootmodes=()
airootfs_image_type=""
airootfs_image_tool_options=()
+cert_list=()
+sign_netboot_artifacts=""
declare -A file_permissions=()
@@ -64,8 +70,8 @@ _msg_error() {
_mount_airootfs() {
trap "_umount_airootfs" EXIT HUP INT TERM
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 "Mounting '${pacstrap_dir}.img' on '${work_dir}/mnt/airootfs'..."
+ mount -- "${pacstrap_dir}.img" "${work_dir}/mnt/airootfs"
_msg_info "Done!"
}
@@ -94,11 +100,17 @@ usage: ${app_name} [options] <profile_dir>
Default: '${iso_label}'
-P <publisher> Set the ISO publisher
Default: '${iso_publisher}'
+ -c [cert ..] Provide certificates for codesigning of netboot artifacts
+ Multiple files are provided as quoted, space delimited list.
+ The first file is considered as the signing certificate,
+ the second as the key.
-g <gpg_key> Set the PGP key ID to be used for signing the rootfs image
-h This message
+ -m [mode ..] Build mode(s) to use (valid modes are: 'bootstrap', 'iso' and 'netboot').
+ Multiple build modes are provided as quoted, space delimited list.
-o <out_dir> Set the output directory
Default: '${out_dir}'
- -p PACKAGE(S) Package(s) to install.
+ -p [package ..] Package(s) to install.
Multiple packages are provided as quoted, space delimited list.
-v Enable verbose output
-w <work_dir> Set the working directory
@@ -120,42 +132,46 @@ _show_config() {
_msg_info " Installation directory: ${install_dir}"
_msg_info " Build date: ${build_date}"
_msg_info " Output directory: ${out_dir}"
+ _msg_info " Current build mode: ${buildmode}"
+ _msg_info " Build modes: ${buildmodes[*]}"
_msg_info " GPG key: ${gpg_key:-None}"
+ _msg_info "Code signing certificates: ${cert_list[*]}"
_msg_info " Profile: ${profile}"
_msg_info "Pacman configuration file: ${pacman_conf}"
- _msg_info " Image file name: ${img_name}"
+ _msg_info " Image file name: ${image_name:-None}"
_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[*]}"
+ _msg_info " Packages File: ${buildmode_packages}"
+ _msg_info " Packages: ${buildmode_pkg_list[*]}"
if [[ "${arch}" == "dual" ]]; then
- _msg_info " Packages (x86_64): ${pkg_list_x86_64[*]:-None}"
- _msg_info " Packages (i686): ${pkg_list_i686[*]:-None}"
+ _msg_info " Packages (i686): ${buildmode_pkg_list_i686[*]:-None}"
+ _msg_info " Packages (x86_64): ${buildmode_pkg_list_x86_64[*]:-None}"
fi
}
# Cleanup airootfs
-_cleanup_airootfs() {
- _msg_info "Cleaning up what we can on ${arch} airootfs..."
+_cleanup_pacstrap_dir() {
+ _msg_info "Cleaning up in ${arch} pacstrap location..."
# Delete all files in /boot
- [[ -d "${airootfs_dir}/boot" ]] && find "${airootfs_dir}/boot" -mindepth 1 -delete
+ [[ -d "${pacstrap_dir}/boot" ]] && find "${pacstrap_dir}/boot" -mindepth 1 -delete
# Delete pacman database sync cache files (*.tar.gz)
- [[ -d "${airootfs_dir}/var/lib/pacman" ]] && find "${airootfs_dir}/var/lib/pacman" -maxdepth 1 -type f -delete
+ [[ -d "${pacstrap_dir}/var/lib/pacman" ]] && find "${pacstrap_dir}/var/lib/pacman" -maxdepth 1 -type f -delete
# Delete pacman database sync cache
- [[ -d "${airootfs_dir}/var/lib/pacman/sync" ]] && find "${airootfs_dir}/var/lib/pacman/sync" -delete
+ [[ -d "${pacstrap_dir}/var/lib/pacman/sync" ]] && find "${pacstrap_dir}/var/lib/pacman/sync" -delete
# Delete pacman package cache
- [[ -d "${airootfs_dir}/var/cache/pacman/pkg" ]] && find "${airootfs_dir}/var/cache/pacman/pkg" -type f -delete
+ [[ -d "${pacstrap_dir}/var/cache/pacman/pkg" ]] && find "${pacstrap_dir}/var/cache/pacman/pkg" -type f -delete
# Delete all log files, keeps empty dirs.
- [[ -d "${airootfs_dir}/var/log" ]] && find "${airootfs_dir}/var/log" -type f -delete
+ [[ -d "${pacstrap_dir}/var/log" ]] && find "${pacstrap_dir}/var/log" -type f -delete
# Delete all temporary files and dirs
- [[ -d "${airootfs_dir}/var/tmp" ]] && find "${airootfs_dir}/var/tmp" -mindepth 1 -delete
+ [[ -d "${pacstrap_dir}/var/tmp" ]] && find "${pacstrap_dir}/var/tmp" -mindepth 1 -delete
# Delete package pacman related files.
find "${work_dir}" \( -name '*.pacnew' -o -name '*.pacsave' -o -name '*.pacorig' \) -delete
# Create an empty /etc/machine-id
- rm -f -- "${airootfs_dir}/etc/machine-id"
- printf '' > "${airootfs_dir}/etc/machine-id"
+ rm -f -- "${pacstrap_dir}/etc/machine-id"
+ printf '' > "${pacstrap_dir}/etc/machine-id"
_msg_info "Done!"
}
@@ -171,36 +187,36 @@ _run_mksquashfs() {
# Makes a ext4 filesystem inside a SquashFS from a source directory.
_mkairootfs_ext4+squashfs() {
- [[ -e "${airootfs_dir}" ]] || _msg_error "The path '${airootfs_dir}' does not exist" 1
+ [[ -e "${pacstrap_dir}" ]] || _msg_error "The path '${pacstrap_dir}' does not exist" 1
_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" 32G
+ mkfs.ext4 -q -O '^has_journal,^resize_inode' -E 'lazy_itable_init=0' -m 0 -F -- "${pacstrap_dir}.img" 32G
else
- mkfs.ext4 -O '^has_journal,^resize_inode' -E 'lazy_itable_init=0' -m 0 -F -- "${airootfs_dir}.img" 32G
+ mkfs.ext4 -O '^has_journal,^resize_inode' -E 'lazy_itable_init=0' -m 0 -F -- "${pacstrap_dir}.img" 32G
fi
- tune2fs -c 0 -i 0 -- "${airootfs_dir}.img" > /dev/null
+ tune2fs -c 0 -i 0 -- "${pacstrap_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/"
+ _msg_info "Copying '${pacstrap_dir}/' to '${work_dir}/mnt/airootfs/'..."
+ cp -aT -- "${pacstrap_dir}/" "${work_dir}/mnt/airootfs/"
chown -- 0:0 "${work_dir}/mnt/airootfs/"
_msg_info "Done!"
_umount_airootfs
install -d -m 0755 -- "${isofs_dir}/${install_dir}/${arch}"
_msg_info "Creating SquashFS image, this may take some time..."
- _run_mksquashfs "${airootfs_dir}.img"
+ _run_mksquashfs "${pacstrap_dir}.img"
_msg_info "Done!"
- rm -- "${airootfs_dir}.img"
+ rm -- "${pacstrap_dir}.img"
}
# Makes a SquashFS filesystem from a source directory.
_mkairootfs_squashfs() {
- [[ -e "${airootfs_dir}" ]] || _msg_error "The path '${airootfs_dir}' does not exist" 1
+ [[ -e "${pacstrap_dir}" ]] || _msg_error "The path '${pacstrap_dir}' does not exist" 1
install -d -m 0755 -- "${isofs_dir}/${install_dir}/${arch}"
_msg_info "Creating ${arch} SquashFS image, this may take some time..."
- _run_mksquashfs "${airootfs_dir}"
+ _run_mksquashfs "${pacstrap_dir}"
_msg_info "Done!"
}
@@ -219,14 +235,14 @@ _mkchecksum() {
# Makes an EROFS file system from a source directory.
_mkairootfs_erofs() {
local fsuuid
- [[ -e "${airootfs_dir}" ]] || _msg_error "The path '${airootfs_dir}' does not exist" 1
+ [[ -e "${pacstrap_dir}" ]] || _msg_error "The path '${pacstrap_dir}' does not exist" 1
install -d -m 0755 -- "${isofs_dir}/${install_dir}/${arch}"
local image_path="${isofs_dir}/${install_dir}/${arch}/airootfs.erofs"
# Generate reproducible file system UUID from SOURCE_DATE_EPOCH
fsuuid="$(uuidgen --sha1 --namespace 93a870ff-8565-4cf3-a67b-f47299271a96 --name "${SOURCE_DATE_EPOCH}")"
_msg_info "Creating EROFS image, this may take some time..."
- mkfs.erofs -U "${fsuuid}" "${airootfs_image_tool_options[@]}" -- "${image_path}" "${airootfs_dir}"
+ mkfs.erofs -U "${fsuuid}" "${airootfs_image_tool_options[@]}" -- "${image_path}" "${pacstrap_dir}"
_msg_info "Done!"
}
@@ -245,9 +261,9 @@ _mksignature() {
# Helper function to run functions only one time.
_run_once() {
- if [[ ! -e "${work_dir}/build.${1}_${arch}" ]]; then
+ if [[ ! -e "${work_dir}/${run_once_mode}.${1}" ]]; then
"$1"
- touch "${work_dir}/build.${1}_${arch}"
+ touch "${work_dir}/${run_once_mode}.${1}_${arch}"
fi
}
@@ -257,7 +273,11 @@ _run_dual() {
if [[ "${arch}" == "dual" ]]; then
local arch
for arch in i686 x86_64; do
- airootfs_dir="${work_dir}/${arch}/airootfs"
+ if [[ "${buildmode}" == "bootstrap" ]]; then
+ pacstrap_dir="${work_dir}/${arch}/bootstrap/root.${arch}"
+ else
+ pacstrap_dir="${work_dir}/${arch}/airootfs"
+ fi
for cmd in "$@"; do
${cmd}
done
@@ -283,7 +303,7 @@ _make_pacman_conf() {
_cache_dirs="${_system_cache_dirs}"
fi
- _msg_info "Copying custom pacman.conf to work directory..."
+ _msg_info "Copying custom pacman.conf to ${arch} work directory..."
_msg_info "Using pacman CacheDir: ${_cache_dirs}"
# take the profile pacman.conf and strip all settings that would break in chroot when using pacman -r
# append CacheDir and HookDir to [options] section
@@ -291,7 +311,7 @@ _make_pacman_conf() {
# see `man 8 pacman` for further info
setarch "${arch}" pacman-conf --config "${pacman_conf}" | \
sed "/CacheDir/d;/DBPath/d;/HookDir/d;/LogFile/d;/RootDir/d;/\[options\]/a CacheDir = ${_cache_dirs}
- /\[options\]/a HookDir = ${airootfs_dir}/etc/pacman.d/hooks/" > "${work_dir}/pacman_${arch}.conf"
+ /\[options\]/a HookDir = ${pacstrap_dir}/etc/pacman.d/hooks/" > "${work_dir}/${buildmode}.pacman.conf.${arch}"
}
# Prepare working directory and copy custom airootfs files (airootfs)
@@ -299,27 +319,27 @@ _make_custom_airootfs() {
local passwd=()
local filename permissions
- install -d -m 0755 -o 0 -g 0 -- "${airootfs_dir}"
+ install -d -m 0755 -o 0 -g 0 -- "${pacstrap_dir}"
if [[ -d "${profile}/airootfs" ]]; then
_msg_info "Copying custom airootfs files..."
- cp -af --no-preserve=ownership,mode -- "${profile}/airootfs/." "${airootfs_dir}"
+ cp -af --no-preserve=ownership,mode -- "${profile}/airootfs/." "${pacstrap_dir}"
# Set ownership and mode for files and directories
for filename in "${!file_permissions[@]}"; do
IFS=':' read -ra permissions <<< "${file_permissions["${filename}"]}"
- # Prevent file path traversal outside of $airootfs_dir
- if [[ "$(realpath -q -- "${airootfs_dir}${filename}")" != "${airootfs_dir}"* ]]; then
- _msg_error "Failed to set permissions on '${airootfs_dir}${filename}'. Outside of valid path." 1
+ # Prevent file path traversal outside of $pacstrap_dir
+ if [[ "$(realpath -q -- "${pacstrap_dir}${filename}")" != "${pacstrap_dir}"* ]]; then
+ _msg_error "Failed to set permissions on '${pacstrap_dir}${filename}'. Outside of valid path." 1
# Warn if the file does not exist
- elif [[ ! -e "${airootfs_dir}${filename}" ]]; then
- _msg_warning "Cannot change permissions of '${airootfs_dir}${filename}'. The file or directory does not exist."
+ elif [[ ! -e "${pacstrap_dir}${filename}" ]]; then
+ _msg_warning "Cannot change permissions of '${pacstrap_dir}${filename}'. The file or directory does not exist."
else
if [[ "${filename: -1}" == "/" ]]; then
- chown -fhR -- "${permissions[0]}:${permissions[1]}" "${airootfs_dir}${filename}"
- chmod -fR -- "${permissions[2]}" "${airootfs_dir}${filename}"
+ chown -fhR -- "${permissions[0]}:${permissions[1]}" "${pacstrap_dir}${filename}"
+ chmod -fR -- "${permissions[2]}" "${pacstrap_dir}${filename}"
else
- chown -fh -- "${permissions[0]}:${permissions[1]}" "${airootfs_dir}${filename}"
- chmod -f -- "${permissions[2]}" "${airootfs_dir}${filename}"
+ chown -fh -- "${permissions[0]}:${permissions[1]}" "${pacstrap_dir}${filename}"
+ chmod -f -- "${permissions[2]}" "${pacstrap_dir}${filename}"
fi
fi
done
@@ -329,10 +349,10 @@ _make_custom_airootfs() {
# Install desired packages to airootfs
_make_packages() {
- _msg_info "Installing packages to '${airootfs_dir}/'..."
+ _msg_info "Installing packages to '${pacstrap_dir}/'..."
- local pkg_list_arch
- eval "pkg_list_arch=(\${pkg_list_${arch}[@]})"
+ local buildmode_pkg_list_arch
+ eval "buildmode_pkg_list_arch=(\${buildmode_pkg_list_${arch}[@]})"
if [[ -n "${gpg_key}" ]]; then
exec {PARABOLAISO_GNUPG_FD}<>"${work_dir}/pubkey.gpg"
@@ -340,9 +360,9 @@ _make_packages() {
fi
if [[ "${quiet}" = "y" ]]; then
- pacstrap -C "${work_dir}/pacman_${arch}.conf" -c -G -M -- "${airootfs_dir}" "${pkg_list[@]}" "${pkg_list_arch[@]}" &> /dev/null
+ pacstrap -C "${work_dir}/${buildmode}.pacman.conf.${arch}" -c -G -M -- "${pacstrap_dir}" "${buildmode_pkg_list[@]}" "${buildmode_pkg_list_arch[@]}" &> /dev/null
else
- pacstrap -C "${work_dir}/pacman_${arch}.conf" -c -G -M -- "${airootfs_dir}" "${pkg_list[@]}" "${pkg_list_arch[@]}"
+ pacstrap -C "${work_dir}/${buildmode}.pacman.conf.${arch}" -c -G -M -- "${pacstrap_dir}" "${buildmode_pkg_list[@]}" "${buildmode_pkg_list_arch[@]}"
fi
if [[ -n "${gpg_key}" ]]; then
@@ -365,27 +385,27 @@ _make_customize_airootfs() {
# Skip invalid home directories
[[ "${passwd[5]}" == '/' ]] && continue
[[ -z "${passwd[5]}" ]] && continue
- # Prevent path traversal outside of $airootfs_dir
- if [[ "$(realpath -q -- "${airootfs_dir}${passwd[5]}")" == "${airootfs_dir}"* ]]; then
- if [[ ! -d "${airootfs_dir}${passwd[5]}" ]]; then
- install -d -m 0750 -o "${passwd[2]}" -g "${passwd[3]}" -- "${airootfs_dir}${passwd[5]}"
+ # Prevent path traversal outside of $pacstrap_dir
+ if [[ "$(realpath -q -- "${pacstrap_dir}${passwd[5]}")" == "${pacstrap_dir}"* ]]; then
+ if [[ ! -d "${pacstrap_dir}${passwd[5]}" ]]; then
+ install -d -m 0750 -o "${passwd[2]}" -g "${passwd[3]}" -- "${pacstrap_dir}${passwd[5]}"
fi
- cp -dnRT --preserve=mode,timestamps,links -- "${airootfs_dir}/etc/skel/." "${airootfs_dir}${passwd[5]}"
- chmod -f 0750 -- "${airootfs_dir}${passwd[5]}"
- chown -hR -- "${passwd[2]}:${passwd[3]}" "${airootfs_dir}${passwd[5]}"
+ cp -dnRT --preserve=mode,timestamps,links -- "${pacstrap_dir}/etc/skel/." "${pacstrap_dir}${passwd[5]}"
+ chmod -f 0750 -- "${pacstrap_dir}${passwd[5]}"
+ chown -hR -- "${passwd[2]}:${passwd[3]}" "${pacstrap_dir}${passwd[5]}"
else
- _msg_error "Failed to set permissions on '${airootfs_dir}${passwd[5]}'. Outside of valid path." 1
+ _msg_error "Failed to set permissions on '${pacstrap_dir}${passwd[5]}'. Outside of valid path." 1
fi
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..."
+ if [[ -e "${pacstrap_dir}/root/customize_airootfs.sh" ]]; then
+ _msg_info "Running customize_airootfs.sh in '${pacstrap_dir}' chroot..."
_msg_warning "customize_airootfs.sh is deprecated! Support for it will be removed in a future parabolaiso version."
- chmod -f -- +x "${airootfs_dir}/root/customize_airootfs.sh"
- eval -- arch-chroot "${airootfs_dir}" "/root/customize_airootfs.sh"
- rm -- "${airootfs_dir}/root/customize_airootfs.sh"
+ chmod -f -- +x "${pacstrap_dir}/root/customize_airootfs.sh"
+ eval -- arch-chroot "${pacstrap_dir}" "/root/customize_airootfs.sh"
+ rm -- "${pacstrap_dir}/root/customize_airootfs.sh"
_msg_info "Done! customize_airootfs.sh run successfully."
fi
}
@@ -402,8 +422,8 @@ _make_bootmodes() {
_make_boot_on_iso9660() {
_msg_info "Preparing ${arch} kernel and initramfs for the ISO 9660 file system..."
install -d -m 0755 -- "${isofs_dir}/${install_dir}/boot/${arch}"
- install -m 0644 -- "${airootfs_dir}/boot/initramfs-"*".img" "${isofs_dir}/${install_dir}/boot/${arch}/"
- install -m 0644 -- "${airootfs_dir}/boot/vmlinuz-"* "${isofs_dir}/${install_dir}/boot/${arch}/"
+ install -m 0644 -- "${pacstrap_dir}/boot/initramfs-"*".img" "${isofs_dir}/${install_dir}/boot/${arch}/"
+ install -m 0644 -- "${pacstrap_dir}/boot/vmlinuz-"* "${isofs_dir}/${install_dir}/boot/${arch}/"
_msg_info "Done!"
}
@@ -420,28 +440,28 @@ _make_bootmode_bios.syslinux.mbr() {
if [[ -e "${profile}/syslinux/splash.png" ]]; then
install -m 0644 -- "${profile}/syslinux/splash.png" "${isofs_dir}/syslinux/"
fi
- install -m 0644 -- "${airootfs_dir}/usr/lib/syslinux/bios/"*.c32 "${isofs_dir}/syslinux/"
- install -m 0644 -- "${airootfs_dir}/usr/lib/syslinux/bios/lpxelinux.0" "${isofs_dir}/syslinux/"
- install -m 0644 -- "${airootfs_dir}/usr/lib/syslinux/bios/memdisk" "${isofs_dir}/syslinux/"
+ install -m 0644 -- "${pacstrap_dir}/usr/lib/syslinux/bios/"*.c32 "${isofs_dir}/syslinux/"
+ install -m 0644 -- "${pacstrap_dir}/usr/lib/syslinux/bios/lpxelinux.0" "${isofs_dir}/syslinux/"
+ install -m 0644 -- "${pacstrap_dir}/usr/lib/syslinux/bios/memdisk" "${isofs_dir}/syslinux/"
_run_dual '_run_once _make_boot_on_iso9660'
if [[ -e "${isofs_dir}/syslinux/hdt.c32" ]]; then
install -d -m 0755 -- "${isofs_dir}/syslinux/hdt"
- if [[ -e "${airootfs_dir}/usr/share/hwdata/pci.ids" ]]; then
- gzip -cn9 "${airootfs_dir}/usr/share/hwdata/pci.ids" > \
+ if [[ -e "${pacstrap_dir}/usr/share/hwdata/pci.ids" ]]; then
+ gzip -cn9 "${pacstrap_dir}/usr/share/hwdata/pci.ids" > \
"${isofs_dir}/syslinux/hdt/pciids.gz"
fi
- find "${airootfs_dir}/usr/lib/modules" -name 'modules.alias' -print -exec gzip -cn9 '{}' ';' -quit > \
+ find "${pacstrap_dir}/usr/lib/modules" -name 'modules.alias' -print -exec gzip -cn9 '{}' ';' -quit > \
"${isofs_dir}/syslinux/hdt/modalias.gz"
fi
# Add other aditional/extra files to ${install_dir}/boot/
- if [[ -e "${airootfs_dir}/boot/memtest86+/memtest.bin" ]]; then
+ if [[ -e "${pacstrap_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"
+ install -m 0644 -- "${pacstrap_dir}/boot/memtest86+/memtest.bin" "${isofs_dir}/${install_dir}/boot/memtest"
install -d -m 0755 -- "${isofs_dir}/${install_dir}/boot/licenses/memtest86+/"
- install -m 0644 -- "${airootfs_dir}/usr/share/licenses/common/GPL2/license.txt" \
+ install -m 0644 -- "${pacstrap_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."
@@ -451,8 +471,8 @@ _make_bootmode_bios.syslinux.mbr() {
_make_bootmode_bios.syslinux.eltorito() {
_msg_info "Setting up SYSLINUX for BIOS booting from an optical disc..."
install -d -m 0755 -- "${isofs_dir}/syslinux"
- install -m 0644 -- "${airootfs_dir}/usr/lib/syslinux/bios/isolinux.bin" "${isofs_dir}/syslinux/"
- install -m 0644 -- "${airootfs_dir}/usr/lib/syslinux/bios/isohdpfx.bin" "${isofs_dir}/syslinux/"
+ install -m 0644 -- "${pacstrap_dir}/usr/lib/syslinux/bios/isolinux.bin" "${isofs_dir}/syslinux/"
+ install -m 0644 -- "${pacstrap_dir}/usr/lib/syslinux/bios/isohdpfx.bin" "${isofs_dir}/syslinux/"
# ISOLINUX and SYSLINUX installation is shared
_run_once _make_bootmode_bios.syslinux.mbr
@@ -464,7 +484,7 @@ _make_bootmode_bios.syslinux.eltorito() {
_make_efi_dir_on_iso9660() {
_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" \
+ install -m 0644 -- "${pacstrap_dir}/usr/lib/systemd/boot/efi/systemd-bootx64.efi" \
"${isofs_dir}/EFI/BOOT/BOOTx64.EFI"
install -d -m 0755 -- "${isofs_dir}/loader/entries"
@@ -479,15 +499,15 @@ _make_efi_dir_on_iso9660() {
# edk2-shell based UEFI shell
# 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" "${isofs_dir}/shellx64.efi"
+ if [[ -e "${pacstrap_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" ]]; then
+ install -m 0644 -- "${pacstrap_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" "${isofs_dir}/shellx64.efi"
fi
}
_make_refind_efi_dir_on_iso9660() {
_msg_info "Preparing an /EFI directory for the ISO 9660 file system..."
install -d -m 0755 -- "${isofs_dir}/EFI/BOOT/entries"
- install -m 0644 -- "${airootfs_dir}/usr/share/refind/refind_x64.efi" \
+ install -m 0644 -- "${pacstrap_dir}/usr/share/refind/refind_x64.efi" \
"${isofs_dir}/EFI/BOOT/BOOTx64.EFI"
install -m 0644 -- "${profile}/efiboot/EFI/BOOT/refind.conf" "${isofs_dir}/EFI/BOOT/"
@@ -501,8 +521,8 @@ _make_refind_efi_dir_on_iso9660() {
# edk2-shell based UEFI shell
# 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" "${isofs_dir}/shellx64.efi"
+ if [[ -e "${pacstrap_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" ]]; then
+ install -m 0644 -- "${pacstrap_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" "${isofs_dir}/shellx64.efi"
fi
}
@@ -511,8 +531,8 @@ _make_boot_on_fat() {
_msg_info "Preparing kernel and initramfs for the FAT file system..."
mmd -i "${work_dir}/efiboot.img" \
"::/${install_dir}" "::/${install_dir}/boot" "::/${install_dir}/boot/x86_64"
- mcopy -i "${work_dir}/efiboot.img" "${airootfs_dir}/boot/vmlinuz-"* \
- "${airootfs_dir}/boot/initramfs-"*".img" "::/${install_dir}/boot/x86_64/"
+ mcopy -i "${work_dir}/efiboot.img" "${pacstrap_dir}/boot/vmlinuz-"* \
+ "${pacstrap_dir}/boot/initramfs-"*".img" "::/${install_dir}/boot/x86_64/"
_msg_info "Done!"
}
@@ -523,11 +543,11 @@ _make_bootmode_uefi-x64.systemd-boot.esp() {
# the required image size in KiB (rounded up to the next full MiB with an additional MiB for reserved sectors)
efiboot_imgsize="$(du -bc \
- "${airootfs_dir}/usr/lib/systemd/boot/efi/systemd-bootx64.efi" \
- "${airootfs_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" \
+ "${pacstrap_dir}/usr/lib/systemd/boot/efi/systemd-bootx64.efi" \
+ "${pacstrap_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" \
"${profile}/efiboot/" \
- "${airootfs_dir}/boot/vmlinuz-"* \
- "${airootfs_dir}/boot/initramfs-"*".img" \
+ "${pacstrap_dir}/boot/vmlinuz-"* \
+ "${pacstrap_dir}/boot/initramfs-"*".img" \
2>/dev/null | awk 'function ceil(x){return int(x)+(x>int(x))}
function byte_to_kib(x){return x/1024}
function mib_to_kib(x){return x*1024}
@@ -541,7 +561,7 @@ _make_bootmode_uefi-x64.systemd-boot.esp() {
mmd -i "${work_dir}/efiboot.img" ::/EFI ::/EFI/BOOT
mcopy -i "${work_dir}/efiboot.img" \
- "${airootfs_dir}/usr/lib/systemd/boot/efi/systemd-bootx64.efi" ::/EFI/BOOT/BOOTx64.EFI
+ "${pacstrap_dir}/usr/lib/systemd/boot/efi/systemd-bootx64.efi" ::/EFI/BOOT/BOOTx64.EFI
mmd -i "${work_dir}/efiboot.img" ::/loader ::/loader/entries
mcopy -i "${work_dir}/efiboot.img" "${profile}/efiboot/loader/loader.conf" ::/loader/
@@ -553,9 +573,9 @@ _make_bootmode_uefi-x64.systemd-boot.esp() {
done
# shellx64.efi is picked up automatically when on /
- if [[ -e "${airootfs_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" ]]; then
+ if [[ -e "${pacstrap_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" ]]; then
mcopy -i "${work_dir}/efiboot.img" \
- "${airootfs_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" ::/shellx64.efi
+ "${pacstrap_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" ::/shellx64.efi
fi
# Copy kernel and initramfs
@@ -570,11 +590,11 @@ _make_bootmode_uefi-x64.refind.esp() {
# the required image size in KiB (rounded up to the next full MiB with an additional MiB for reserved sectors)
efiboot_imgsize="$(du -bc \
- "${airootfs_dir}/usr/share/refind/refind_x64.efi" \
- "${airootfs_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" \
+ "${pacstrap_dir}/usr/share/refind/refind_x64.efi" \
+ "${pacstrap_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" \
"${profile}/efiboot/" \
- "${airootfs_dir}/boot/vmlinuz-"* \
- "${airootfs_dir}/boot/initramfs-"*".img" \
+ "${pacstrap_dir}/boot/vmlinuz-"* \
+ "${pacstrap_dir}/boot/initramfs-"*".img" \
2>/dev/null | awk 'function ceil(x){return int(x)+(x>int(x))}
function byte_to_kib(x){return x/1024}
function mib_to_kib(x){return x*1024}
@@ -588,7 +608,7 @@ _make_bootmode_uefi-x64.refind.esp() {
mmd -i "${work_dir}/efiboot.img" ::/EFI ::/EFI/BOOT
mcopy -i "${work_dir}/efiboot.img" \
- "${airootfs_dir}/usr/share/refind/refind_x64.efi" ::/EFI/BOOT/BOOTx64.EFI
+ "${pacstrap_dir}/usr/share/refind/refind_x64.efi" ::/EFI/BOOT/BOOTx64.EFI
mmd -i "${work_dir}/efiboot.img" ::/EFI/BOOT/entries
mcopy -i "${work_dir}/efiboot.img" "${profile}/efiboot/EFI/BOOT/refind.conf" ::/EFI/BOOT/
@@ -600,9 +620,9 @@ _make_bootmode_uefi-x64.refind.esp() {
done
# shellx64.efi is picked up automatically when on /
- if [[ -e "${airootfs_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" ]]; then
+ if [[ -e "${pacstrap_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" ]]; then
mcopy -i "${work_dir}/efiboot.img" \
- "${airootfs_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" ::/shellx64.efi
+ "${pacstrap_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" ::/shellx64.efi
fi
# Copy kernel and initramfs
@@ -699,8 +719,8 @@ _validate_requirements_bootmode_uefi-x64.systemd-boot.esp() {
fi
# Check for optional packages
- # shellcheck disable=SC2076
if [[ "${arch}" == "dual" ]]; then
+ # shellcheck disable=SC2154
if [[ ! " ${pkg_list_x86_64[*]} " =~ ' edk2-shell ' ]]; then
_msg_info "'edk2-shell' is not in the x86_64 package list. The ISO will not contain a bootable UEFI shell."
fi
@@ -744,7 +764,6 @@ _validate_requirements_bootmode_uefi-x64.refind.esp() {
fi
# Check for optional packages
- # shellcheck disable=SC2076
if [[ "${arch}" == "dual" ]]; then
if [[ ! " ${pkg_list_x86_64[*]} " =~ ' edk2-shell ' ]]; then
_msg_info "'edk2-shell' is not in the x86_64 package list. The ISO will not contain a bootable UEFI shell."
@@ -775,6 +794,34 @@ _prepare_airootfs_image() {
fi
}
+# export build artifacts for netboot
+_export_netboot_artifacts() {
+ _msg_info "Exporting netboot artifacts..."
+ install -d -m 0755 "${out_dir}"
+ cp -a -- "${isofs_dir}/${install_dir}/" "${out_dir}/"
+ _msg_info "Done!"
+ du -h -- "${out_dir}/${install_dir}"
+}
+
+# sign build artifacts for netboot
+_sign_netboot_artifacts() {
+ local _file _dir
+ _msg_info "Signing netboot artifacts..."
+ _dir="${isofs_dir}/${install_dir}/"
+ for _file in "${_dir}/boot/${arch}/vmlinuz-"* "${_dir}/boot/${arch}/initramfs-"*.img; do
+ openssl cms \
+ -sign \
+ -binary \
+ -noattr \
+ -in "${_file}" \
+ -signer "${cert_list[0]}" \
+ -inkey "${cert_list[1]}" \
+ -outform DER \
+ -out "${_file}".ipxe.sig
+ done
+ _msg_info "Done!"
+}
+
_validate_requirements_airootfs_image_type_squashfs() {
if ! command -v mksquashfs &> /dev/null; then
(( validation_error=validation_error+1 ))
@@ -797,6 +844,44 @@ _validate_requirements_airootfs_image_type_erofs() {
fi
}
+_validate_requirements_buildmode_all() {
+ if ! command -v pacman &> /dev/null; then
+ (( validation_error=validation_error+1 ))
+ _msg_error "Validating build mode '${_buildmode}': pacman is not available on this host. Install 'pacman'!" 0
+ fi
+ if ! command -v find &> /dev/null; then
+ (( validation_error=validation_error+1 ))
+ _msg_error "Validating build mode '${_buildmode}': find is not available on this host. Install 'findutils'!" 0
+ fi
+ if ! command -v gzip &> /dev/null; then
+ (( validation_error=validation_error+1 ))
+ _msg_error "Validating build mode '${_buildmode}': gzip is not available on this host. Install 'gzip'!" 0
+ fi
+}
+
+_validate_requirements_buildmode_bootstrap() {
+ _validate_requirements_buildmode_all
+ if ! command -v bsdtar &> /dev/null; then
+ (( validation_error=validation_error+1 ))
+ _msg_error "Validating build mode '${_buildmode}': bsdtar is not available on this host. Install 'libarchive'!" 0
+ fi
+}
+
+_validate_requirements_buildmode_iso() {
+ _validate_requirements_buildmode_all
+ if ! command -v awk &> /dev/null; then
+ (( validation_error=validation_error+1 ))
+ _msg_error "Validating build mode '${_buildmode}': awk is not available on this host. Install 'awk'!" 0
+ fi
+}
+_validate_requirements_buildmode_netboot() {
+ _validate_requirements_buildmode_all
+ if ! command -v openssl &> /dev/null; then
+ (( validation_error=validation_error+1 ))
+ _msg_error "Validating build mode '${_buildmode}': openssl is not available on this host. Install 'openssl'!" 0
+ fi
+}
+
# SYSLINUX El Torito
_add_xorrisofs_options_bios.syslinux.eltorito() {
xorrisofs_options+=(
@@ -944,8 +1029,28 @@ _add_xorrisofs_options_uefi-x64.refind.eltorito() {
[[ " ${bootmodes[*]} " =~ ' bios.' ]] || xorrisofs_options+=('-eltorito-catalog' 'EFI/boot.cat')
}
+# Build bootstrap image
+_build_bootstrap_image() {
+ local _bootstrap_parent
+ _bootstrap_parent="$(dirname -- "${pacstrap_dir}")"
+
+ local image_name_arch
+ eval "image_name_arch=\${image_name_${arch}}"
+ [[ -z "${image_name_arch}" ]] || image_name="${image_name_arch}"
+
+ [[ -d "${out_dir}" ]] || install -d -- "${out_dir}"
+
+ cd -- "${_bootstrap_parent}"
+
+ _msg_info "Creating ${arch} bootstrap image..."
+ bsdtar -cf - "root.${arch}" | gzip -cn9 > "${out_dir}/${image_name}"
+ _msg_info "Done!"
+ du -h -- "${out_dir}/${image_name}"
+ cd -- "${OLDPWD}"
+}
+
# Build ISO
-_build_iso() {
+_build_iso_image() {
local xorrisofs_options=()
local bootmode
@@ -970,10 +1075,10 @@ _build_iso() {
-publisher "${iso_publisher}" \
-preparer "prepared by ${app_name}" \
"${xorrisofs_options[@]}" \
- -output "${out_dir}/${img_name}" \
+ -output "${out_dir}/${image_name}" \
"${isofs_dir}/"
_msg_info "Done!"
- du -h -- "${out_dir}/${img_name}"
+ du -h -- "${out_dir}/${image_name}"
}
# Read profile's values from profiledef.sh
@@ -992,16 +1097,31 @@ _read_profile() {
# shellcheck source=configs/releng/profiledef.sh
. "${profile}/profiledef.sh"
- # Resolve paths of files that are expected to reside in the profile's directory
if [[ "${arch}" == "dual" ]]; then
- [[ -n "$packages_dual" ]] || packages_dual=("${profile}/packages."{both,i686,x86_64})
- # shellcheck disable=SC2178
- packages_dual="$(realpath -- "${packages_dual[@]}")"
+ # Resolve paths of files that are expected to reside in the profile's directory for each architecture
+ [[ -n "$packages_dual" ]] || packages_files_dual=("${profile}/packages."{both,i686,x86_64})
+ packages_dual="$(realpath -- "${packages_files_dual[@]}")"
+ pacman_conf="$(realpath -- "${pacman_conf}")"
+
+ # Resolve paths of files that may reside in the profile's directory for each architecture
+ if [[ -z "$bootstrap_packages_dual" ]] && [[ -e "${profile}/bootstrap_packages.both" ]]; then
+ bootstrap_packages_files_dual=("${profile}/bootstrap_packages."{both,i686,x86_64})
+ bootstrap_packages_dual="$(realpath -- "${bootstrap_packages_files_dual[@]}")"
+ pacman_conf="$(realpath -- "${pacman_conf}")"
+ fi
else
+ # Resolve paths of files that are expected to reside in the profile's directory
[[ -n "$packages" ]] || packages="${profile}/packages.${arch}"
packages="$(realpath -- "${packages}")"
+ pacman_conf="$(realpath -- "${pacman_conf}")"
+
+ # Resolve paths of files that may reside in the profile's directory
+ if [[ -z "$bootstrap_packages" ]] && [[ -e "${profile}/bootstrap_packages.${arch}" ]]; then
+ bootstrap_packages="${profile}/bootstrap_packages.${arch}"
+ bootstrap_packages="$(realpath -- "${bootstrap_packages}")"
+ pacman_conf="$(realpath -- "${pacman_conf}")"
+ fi
fi
- pacman_conf="$(realpath -- "${pacman_conf}")"
cd -- "${OLDPWD}"
fi
@@ -1009,50 +1129,132 @@ _read_profile() {
# Validate set options
_validate_options() {
- local validation_error=0 bootmode
+ local validation_error=0 bootmode _cert _buildmode
local pkg_list_from_file=()
+ # shellcheck disable=SC2034
+ local pkg_list_from_file_i686=()
+ # shellcheck disable=SC2034
+ local pkg_list_from_file_x86_64=()
+ local bootstrap_pkg_list_from_file=()
+ # shellcheck disable=SC2034
+ local bootstrap_pkg_list_from_file_i686=()
+ # shellcheck disable=SC2034
+ local bootstrap_pkg_list_from_file_x86_64=()
+ local _override_cert_list=()
+
_msg_info "Validating options..."
- # Check if the package list file exists and read packages from it
if [[ "${arch}" == "dual" ]]; then
+ # Check if the package list files exist and read packages from them for each architecture
# shellcheck disable=SC2128
for packages in ${packages_dual}; do
- if [[ "${packages##*/}" = "packages.both" ]]; then
+ if [[ "${packages##*/}" == "packages.both" ]]; then
if [[ -e "${packages}" ]]; then
mapfile -t pkg_list_from_file < <(sed '/^[[:blank:]]*#.*/d;s/#.*//;/^[[:blank:]]*$/d' "${packages}")
pkg_list+=("${pkg_list_from_file[@]}")
if (( ${#pkg_list_from_file} < 1 )); then
(( validation_error=validation_error+1 ))
- _msg_error "No package specified in '${packages}'." 0
+ _msg_error "Packages file '${packages}' does not exist." 0
fi
else
(( validation_error=validation_error+1 ))
- _msg_error "File '${packages}' does not exist." 0
+ _msg_error "Packages file '${packages}' does not exist." 0
fi
elif [[ -e "${packages}" ]]; then
mapfile -t "pkg_list_from_file_${packages##*.}" < <(sed '/^[[:blank:]]*#.*/d;s/#.*//;/^[[:blank:]]*$/d' "${packages}")
eval "pkg_list_${packages##*.}+=(\${pkg_list_from_file_${packages##*.}[@]})"
fi
done
+
+ # Check if packages for the bootstrap image are specified for each architecture
+ if [[ "${buildmodes[*]}" == *bootstrap* ]]; then
+ for bootstrap_packages in ${bootstrap_packages_dual}; do
+ if [[ "${bootstrap_packages##*/}" == "bootstrap_packages.both" ]]; then
+ if [[ -e "${bootstrap_packages}" ]]; then
+ mapfile -t bootstrap_pkg_list_from_file < \
+ <(sed '/^[[:blank:]]*#.*/d;s/#.*//;/^[[:blank:]]*$/d' "${bootstrap_packages}")
+ bootstrap_pkg_list+=("${bootstrap_pkg_list_from_file[@]}")
+ if (( ${#bootstrap_pkg_list_from_file} < 1 )); then
+ (( validation_error=validation_error+1 ))
+ _msg_error "No package specified in '${bootstrap_packages}'." 0
+ fi
+ else
+ (( validation_error=validation_error+1 ))
+ _msg_error "Bootstrap packages file '${bootstrap_packages}' does not exist." 0
+ fi
+ elif [[ -e "${bootstrap_packages}" ]]; then
+ mapfile -t "bootstrap_pkg_list_from_file_${bootstrap_packages##*.}" < \
+ <(sed '/^[[:blank:]]*#.*/d;s/#.*//;/^[[:blank:]]*$/d' "${bootstrap_packages}")
+ eval "bootstrap_pkg_list_${bootstrap_packages##*.}+=(\${bootstrap_pkg_list_from_file_${bootstrap_packages##*.}[@]})"
+ fi
+ done
+ fi
else
+ # Check if the package list file exists and read packages from it
if [[ -e "${packages}" ]]; then
mapfile -t pkg_list_from_file < <(sed '/^[[:blank:]]*#.*/d;s/#.*//;/^[[:blank:]]*$/d' "${packages}")
pkg_list+=("${pkg_list_from_file[@]}")
if (( ${#pkg_list_from_file} < 1 )); then
(( validation_error=validation_error+1 ))
- _msg_error "No package specified in '${packages}'." 0
+ _msg_error "Packages file '${packages}' does not exist." 0
fi
else
(( validation_error=validation_error+1 ))
- _msg_error "File '${packages}' does not exist." 0
+ _msg_error "Packages file '${packages}' does not exist." 0
+ fi
+ # Check if packages for the bootstrap image are specified
+ if [[ "${buildmodes[*]}" == *bootstrap* ]]; then
+ if [[ -e "${bootstrap_packages}" ]]; then
+ mapfile -t bootstrap_pkg_list_from_file < \
+ <(sed '/^[[:blank:]]*#.*/d;s/#.*//;/^[[:blank:]]*$/d' "${bootstrap_packages}")
+ bootstrap_pkg_list+=("${bootstrap_pkg_list_from_file[@]}")
+ if (( ${#bootstrap_pkg_list_from_file} < 1 )); then
+ (( validation_error=validation_error+1 ))
+ _msg_error "No package specified in '${bootstrap_packages}'." 0
+ fi
+ else
+ (( validation_error=validation_error+1 ))
+ _msg_error "Bootstrap packages file '${bootstrap_packages}' does not exist." 0
+ fi
+ fi
+ fi
+ if [[ "${sign_netboot_artifacts}" == "y" ]]; then
+ # Check if the certificate files exist
+ for _cert in "${cert_list[@]}"; do
+ if [[ -e "${_cert}" ]]; then
+ _override_cert_list+=("$(realpath -- "${_cert}")")
+ else
+ (( validation_error=validation_error+1 ))
+ _msg_error "File '${_cert}' does not exist." 0
+ fi
+ done
+ cert_list=("${_override_cert_list[@]}")
+ # Check if there are at least two certificate files
+ if (( "${#cert_list[@]}" < 2 )); then
+ (( validation_error=validation_error+1 ))
+ _msg_error "Two certificates are required for codesigning, but '${cert_list[*]}' is provided." 0
fi
fi
-
# Check if pacman configuration file exists
if [[ ! -e "${pacman_conf}" ]]; then
(( validation_error=validation_error+1 ))
_msg_error "File '${pacman_conf}' does not exist." 0
fi
+
+ # Check if the specified buildmodes are supported
+ for _buildmode in "${buildmodes[@]}"; do
+ if typeset -f "_build_buildmode_${_buildmode}" &> /dev/null; then
+ if typeset -f "_validate_requirements_buildmode_${_buildmode}" &> /dev/null; then
+ "_validate_requirements_buildmode_${_buildmode}"
+ else
+ _msg_warning "Function '_validate_requirements_buildmode_${_buildmode}' does not exist. Validating the requirements of '${_buildmode}' build mode will not be possible."
+ fi
+ else
+ (( validation_error=validation_error+1 ))
+ _msg_error "${_buildmode} is not a valid build mode!" 0
+ fi
+ done
+
# Check if the specified bootmodes are supported
for bootmode in "${bootmodes[@]}"; do
if typeset -f "_make_bootmode_${bootmode}" &> /dev/null; then
@@ -1066,6 +1268,7 @@ _validate_options() {
_msg_error "${bootmode} is not a valid boot mode!" 0
fi
done
+
# Check if the specified airootfs_image_type is supported
if typeset -f "_mkairootfs_${airootfs_image_type}" &> /dev/null; then
if typeset -f "_validate_requirements_airootfs_image_type_${airootfs_image_type}" &> /dev/null; then
@@ -1077,6 +1280,7 @@ _validate_options() {
(( validation_error=validation_error+1 ))
_msg_error "Unsupported image type: '${airootfs_image_type}'" 0
fi
+
if (( validation_error )); then
_msg_error "${validation_error} errors were encountered while validating the profile. Aborting." 1
fi
@@ -1086,6 +1290,10 @@ _validate_options() {
# Set defaults and, if present, overrides from mkparabolaiso command line option parameters
_set_overrides() {
# Set variables that have command line overrides
+ [[ ! -v override_buildmodes ]] || buildmodes=("${override_buildmodes[@]}")
+ if (( "${#buildmodes[@]}" < 1 )); then
+ buildmodes+=('iso')
+ fi
if [[ -v override_work_dir ]]; then
work_dir="$override_work_dir"
elif [[ -z "$work_dir" ]]; then
@@ -1105,6 +1313,7 @@ _set_overrides() {
fi
pacman_conf="$(realpath -- "$pacman_conf")"
[[ ! -v override_pkg_list ]] || pkg_list+=("${override_pkg_list[@]}")
+ # TODO: allow overriding bootstrap_pkg_list
if [[ -v override_iso_label ]]; then
iso_label="$override_iso_label"
elif [[ -z "$iso_label" ]]; then
@@ -1126,6 +1335,10 @@ _set_overrides() {
install_dir="${app_name}"
fi
[[ ! -v override_gpg_key ]] || gpg_key="$override_gpg_key"
+ if [[ -v override_cert_list ]]; then
+ sign_netboot_artifacts="y"
+ fi
+ [[ ! -v override_cert_list ]] || cert_list+=("${override_cert_list[@]}")
if [[ -v override_quiet ]]; then
quiet="$override_quiet"
elif [[ -z "$quiet" ]]; then
@@ -1136,7 +1349,6 @@ _set_overrides() {
[[ -n "$arch" ]] || arch="$(uname -m)"
[[ -n "$airootfs_image_type" ]] || airootfs_image_type="squashfs"
[[ -n "$iso_name" ]] || iso_name="${app_name}"
- [[ -n "$img_name" ]] || img_name="${iso_name}-${iso_version}-${arch}.iso"
}
_export_gpg_publickey() {
@@ -1144,42 +1356,65 @@ _export_gpg_publickey() {
}
_make_version() {
- local osrelease
- install -d -m 0755 -- "${isofs_dir}/${install_dir}"
- _msg_info "Creating files with iso version..."
- # Write version file to airootfs
- rm -f -- "${airootfs_dir}/version"
- printf '%s\n' "${iso_version}" > "${airootfs_dir}/version"
- # Write version file to ISO 9660
- printf '%s\n' "${iso_version}" > "${isofs_dir}/${install_dir}/version"
- # Write grubenv with version information to ISO 9660
- printf '%.1024s' "$(printf '# GRUB Environment Block\nNAME=%s\nVERSION=%s\n%s' \
- "${iso_name}" "${iso_version}" "$(printf '%0.1s' "#"{1..1024})")" \
- > "${isofs_dir}/${install_dir}/grubenv"
+ local _os_release
+
+ _msg_info "Creating ${arch} version files..."
+ # Write version file to system installation dir
+ rm -f -- "${pacstrap_dir}/version"
+ printf '%s\n' "${iso_version}" > "${pacstrap_dir}/version"
+
+ if [[ "${buildmode}" == "iso" ]]; then
+ install -d -m 0755 -- "${isofs_dir}/${install_dir}"
+ # Write version file to ISO 9660
+ printf '%s\n' "${iso_version}" > "${isofs_dir}/${install_dir}/version"
+ # Write grubenv with version information to ISO 9660
+ printf '%.1024s' "$(printf '# GRUB Environment Block\nNAME=%s\nVERSION=%s\n%s' \
+ "${iso_name}" "${iso_version}" "$(printf '%0.1s' "#"{1..1024})")" \
+ > "${isofs_dir}/${install_dir}/grubenv"
+ fi
+
# Append IMAGE_ID & IMAGE_VERSION to os-release
- osrelease="$(realpath -- "${airootfs_dir}/etc/os-release")"
- if [[ ! -e "${airootfs_dir}/etc/os-release" && -e "${airootfs_dir}/usr/lib/os-release" ]]; then
- osrelease="$(realpath -- "${airootfs_dir}/usr/lib/os-release")"
+ _os_release="$(realpath -- "${pacstrap_dir}/etc/os-release")"
+ if [[ ! -e "${pacstrap_dir}/etc/os-release" && -e "${pacstrap_dir}/usr/lib/os-release" ]]; then
+ _os_release="$(realpath -- "${pacstrap_dir}/usr/lib/os-release")"
fi
- if [[ "${osrelease}" != "${airootfs_dir}"* ]]; then
- _msg_warning "os-release file '${osrelease}' is outside of valid path."
+ if [[ "${_os_release}" != "${pacstrap_dir}"* ]]; then
+ _msg_warning "os-release file '${_os_release}' is outside of valid path."
else
- [[ ! -e "${osrelease}" ]] || sed -i '/^IMAGE_ID=/d;/^IMAGE_VERSION=/d' "${osrelease}"
- printf 'IMAGE_ID=%s\nIMAGE_VERSION=%s\n' "${iso_name}" "${iso_version}" >> "${osrelease}"
+ [[ ! -e "${_os_release}" ]] || sed -i '/^IMAGE_ID=/d;/^IMAGE_VERSION=/d' "${_os_release}"
+ printf 'IMAGE_ID=%s\nIMAGE_VERSION=%s\n' "${iso_name}" "${iso_version}" >> "${_os_release}"
fi
_msg_info "Done!"
}
_make_pkglist() {
- install -d -m 0755 -- "${isofs_dir}/${install_dir}"
_msg_info "Creating a list of installed packages on ${arch} live-enviroment..."
- pacman -Q --sysroot "${airootfs_dir}" > "${isofs_dir}/${install_dir}/pkglist.${arch}.txt"
+ case "${buildmode}" in
+ "bootstrap")
+ pacman -Q --sysroot "${pacstrap_dir}" > "${pacstrap_dir}/pkglist.${arch}.txt"
+ ;;
+ "iso"|"netboot")
+ install -d -m 0755 -- "${isofs_dir}/${install_dir}"
+ pacman -Q --sysroot "${pacstrap_dir}" > "${isofs_dir}/${install_dir}/pkglist.${arch}.txt"
+ ;;
+ esac
_msg_info "Done!"
}
-_build_profile() {
+# build the base for an ISO and/or a netboot target
+_build_iso_base() {
+ local run_once_mode="base"
+ local buildmode_packages="${packages}"
+ if [[ "${arch}" == "dual" ]]; then
+ local buildmode_packages="${packages_dual}"
+ # Set the package list to use for each architecture
+ local buildmode_pkg_list_i686=("${pkg_list_i686[@]}")
+ local buildmode_pkg_list_x86_64=("${pkg_list_x86_64[@]}")
+ fi
+ # Set the package list to use
+ local buildmode_pkg_list=("${pkg_list[@]}")
# Set up essential directory paths
- airootfs_dir="${work_dir}/${arch}/airootfs"
+ pacstrap_dir="${work_dir}/${arch}/airootfs"
isofs_dir="${work_dir}/iso"
# Create working directory
[[ -d "${work_dir}" ]] || install -d -- "${work_dir}"
@@ -1199,12 +1434,79 @@ _build_profile() {
_run_dual '_run_once _make_customize_airootfs'
_run_dual '_run_once _make_pkglist'
_make_bootmodes
- _run_dual '_run_once _cleanup_airootfs' \
+ _run_dual '_run_once _cleanup_pacstrap_dir' \
'_run_once _prepare_airootfs_image'
- _run_once _build_iso
}
-while getopts 'p:C:L:P:A:D:w:o:g:vh?' arg; do
+# Build the bootstrap buildmode
+_build_buildmode_bootstrap() {
+ local run_once_mode="${buildmode}"
+ if [[ "${arch}" == "dual" ]]; then
+ local image_name_i686="${iso_name}-bootstrap-${iso_version}-i686.tar.gz"
+ local image_name_x86_64="${iso_name}-bootstrap-${iso_version}-x86_64.tar.gz"
+ local image_name="${image_name_i686} ${image_name_x86_64}"
+ local buildmode_packages="${bootstrap_packages_dual}"
+ # Set the package lists to use
+ local buildmode_pkg_list_i686=("${bootstrap_pkg_list_i686[@]}")
+ local buildmode_pkg_list_x86_64=("${bootstrap_pkg_list_x86_64[@]}")
+ local buildmode_pkg_list=("${bootstrap_pkg_list[@]}")
+
+ # Set up essential directory paths
+ pacstrap_dir_i686="${work_dir}/i686/bootstrap/root.i686"
+ pacstrap_dir_x86_64="${work_dir}/x86_64/bootstrap/root.x86_64"
+ [[ -d "${work_dir}" ]] || install -d -- "${work_dir}"
+ install -d -m 0755 -o 0 -g 0 -- "${pacstrap_dir_i686}" "${pacstrap_dir_x86_64}"
+ else
+ local image_name="${iso_name}-bootstrap-${iso_version}-${arch}.tar.gz"
+ local buildmode_packages="${bootstrap_packages}"
+ # Set the package list to use
+ local buildmode_pkg_list=("${bootstrap_pkg_list[@]}")
+
+ # Set up essential directory paths
+ pacstrap_dir="${work_dir}/${arch}/bootstrap/root.${arch}"
+ [[ -d "${work_dir}" ]] || install -d -- "${work_dir}"
+ install -d -m 0755 -o 0 -g 0 -- "${pacstrap_dir}"
+ fi
+
+ [[ "${quiet}" == "y" ]] || _show_config
+ _run_dual '_run_once _make_pacman_conf'
+ _run_dual '_run_once _make_packages'
+ _run_dual '_run_once _make_version'
+ _run_dual '_run_once _make_pkglist'
+ _run_dual '_run_once _cleanup_pacstrap_dir'
+ _run_dual '_run_once _build_bootstrap_image'
+}
+
+# Build the netboot buildmode
+_build_buildmode_netboot() {
+ local run_once_mode="${buildmode}"
+
+ _run_once _build_iso_base
+ if [[ -v cert_list ]]; then
+ _run_once _sign_netboot_artifacts
+ fi
+ _run_once _export_netboot_artifacts
+}
+
+# Build the ISO buildmode
+_build_buildmode_iso() {
+ local image_name="${iso_name}-${iso_version}-${arch}.iso"
+ local run_once_mode="${buildmode}"
+ _run_once _build_iso_base
+ _run_once _build_iso_image
+}
+
+# build all buildmodes
+_build() {
+ local buildmode
+ local run_once_mode="build"
+
+ for buildmode in "${buildmodes[@]}"; do
+ _run_once "_build_buildmode_${buildmode}"
+ done
+}
+
+while getopts 'c:p:C:L:P:A:D:w:m:o:g:vh?' arg; do
case "${arg}" in
p) read -r -a override_pkg_list <<< "${OPTARG}" ;;
C) override_pacman_conf="${OPTARG}" ;;
@@ -1212,7 +1514,9 @@ while getopts 'p:C:L:P:A:D:w:o:g:vh?' arg; do
P) override_iso_publisher="${OPTARG}" ;;
A) override_iso_application="${OPTARG}" ;;
D) override_install_dir="${OPTARG}" ;;
+ c) read -r -a override_cert_list <<< "${OPTARG}" ;;
w) override_work_dir="${OPTARG}" ;;
+ m) read -r -a override_buildmodes <<< "${OPTARG}" ;;
o) override_out_dir="${OPTARG}" ;;
g) override_gpg_key="${OPTARG}" ;;
v) override_quiet="n" ;;
@@ -1241,6 +1545,6 @@ profile="$(realpath -- "${1}")"
_read_profile
_set_overrides
_validate_options
-_build_profile
+_build
# vim:ts=4:sw=4:et: