Skip to content

Commit

Permalink
Implement dynamic kernel cmdline generation
Browse files Browse the repository at this point in the history
Allows an image to define additional kernel cmdline arguments via shell scripts executed when frzr bootloader is called for the specific deployment.
  • Loading branch information
NeroReflex committed Sep 30, 2024
1 parent efabb22 commit 0eed95b
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 3 deletions.
62 changes: 59 additions & 3 deletions __frzr
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ frzr_umount_chroot() {
umount -l "${CHROOT_PATH}/dev"
}

# Get the UUID of the desk containing the given directory
# Get the UUID of the disk containing the given directory
# $1 the directory
# stdout UUID (compatible with /dev/disk/by-uuid/), an error otherwise
get_uuid() {
Expand Down Expand Up @@ -156,6 +156,10 @@ get_uuid() {
# return 0 if the directory is a subvolume, 1 otherwise
is_btrfs_subvolume() {
local dir=$1
if [ ! -d "${dir}" ]; then
return 1
fi

[ "$(stat -f --format="%T" "$dir")" == "btrfs" ] || return 1
inode="$(stat --format="%i" "$dir")"
case "$inode" in
Expand Down Expand Up @@ -494,10 +498,10 @@ check_uefi() {
}

# Check if there are migrations available in the image to be deployed and run them one by one
# Note: migrations are functions named either post_install or chroot_post_install inside (executable) files with .migration extension
# Note: migrations are functions named either post_install inside (executable) files with .migration extension,
# stored inside $2/usr/lib/frzr.d/
#
# Every post_install function will be run in a subshell, while every chroot_post_install will be run inside a chroot.
# Every post_install function will be run in a subshell.
#
# PRE=$2/usr/lib/frzr.d is a directory
# POST=
Expand Down Expand Up @@ -664,6 +668,58 @@ execute_removal() {
fi
}

# Check if there are bootloader hooks available in the image to be deployed and run them one by one
# Note: bootloader hooks are functions named boot_cmdline inside (executable) files with .bootloader extension
# stored inside $2/usr/lib/frzr.d/
#
# Every boot_cmdline function will be run in a subshell.
#
# PRE=$2/usr/lib/frzr.d is a directory
# POST=
#
# $1 the deployment version; this is also the deployment name (the name of the subvolume to be used as rootfs)
# $2 the deployment subvolume
# $3 frzr_root the mounted path to the main btrfs subvolume (the one that contains home as a subvolume)
# $4 frzr version string
# stdout additional kernel cmdline arguments
generate_additional_cmdline() {
local deployment_version=$1
local deployment=$2
local frzr_root=$3
local frzr_version=$4

local additional_cmdline=" "

if compgen -G "${deployment}"/usr/lib/frzr.d/*.bootloader >/dev/null; then
for m in "${deployment}"/usr/lib/frzr.d/*.bootloader; do
unset frzr_migration_version

unset -f boot_cmdline

# source the migration
. $m

# only execute migrations marked for newer frzr versions
if [ ! -z "$frzr_migration_version" ] && [ $frzr_migration_version -gt 0 ]; then
if [ "$(type -t boot_cmdline)" == function ] ; then

# Run migration and check for errors
local this_cmdline=$(boot_cmdline "${frzr_root}" "${deployment}" "${deployment_version}" "${frzr_version}")
additional_cmdline="$additional_cmdline ${this_cmdline}"
fi
fi

unset -f boot_cmdline

unset frzr_migration_version
done

echo "$additional_cmdline"
else
echo ""
fi
}

# Write the systemd-boot entry needed to boot the specified deployment
# Note: this function can ignore amd-ucode and intel-ucode if those are not found since
# either dracut or mkinitcpio will place those in the initramfs and including
Expand Down
12 changes: 12 additions & 0 deletions __frzr-bootloader
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ frzr_bootloader() {
continue
fi

local version=$("${BASH_SOURCE%/*}/frzr-version")
if echo "${version}" | grep -Fq "ERROR"; then
TASK_ERROR=1
TASK_ERROR_MSG="Could not fetch frzr version: ${version}"
STATE="FAIL"
send_data
continue
fi

# Make sure the frzr_root is mounted during the deployment procedure
# this code is based on the fact that when a btrfs filesystem is created
# the default subvolid that is created contextually has the ID set to 256
Expand Down Expand Up @@ -195,6 +204,9 @@ frzr_bootloader() {
send_data
fi

local dyn_cmdline=$(generate_additional_cmdline "${NAME}" "${SUBVOL}" "${MOUNT_PATH}" "${version}")
deployment_arguments="$deployment_arguments ${dyn_cmdline}"

# Make sure the deployment has a /boot directory
if [ ! -d "${SUBVOL}/boot" ]; then
TASK_ERROR=1
Expand Down

0 comments on commit 0eed95b

Please sign in to comment.