Skip to content

Commit

Permalink
Refactor user runtime hooks installation and processing
Browse files Browse the repository at this point in the history
- Add new hook points: load-key.d and boot-sel.d

- All hooks are installed in hook-point-specific subdirectories of
  /libexec/hooks instead of in the top-level /libexec

- User hooks are recognized in level-specific subdirectories of a
  zfsbootmenu_hook_root defined for dracut or mkinitcpio

- Deprecate zfsbootmenu_{early_setup,setup,teardown} variables

- Take advantage of zfsbootmenu_hook_root to simplify hooks in container
  builds via zbm-builder.sh

- Simplify zbm.hookdir overrides

Closes: #477.
  • Loading branch information
ahesford committed Sep 13, 2023
1 parent 1206736 commit 640af57
Show file tree
Hide file tree
Showing 15 changed files with 720 additions and 456 deletions.
20 changes: 3 additions & 17 deletions docs/guides/general/container-building.rst
Original file line number Diff line number Diff line change
Expand Up @@ -133,23 +133,9 @@ The default behavior of ``zbm-builder.sh`` will:
Custom ZFSBootMenu Hooks
~~~~~~~~~~~~~~~~~~~~~~~~

ZFSBootMenu supports :ref:`custom hooks <zbm-dracut-options>` in three stages:

1. ``early_setup`` hooks run after the ``zfs`` kernel driver has been loaded, but before ZFSBootMenu attempts to import
any pools.
2. ``setup`` hooks run after pools are imported, right before ZFSBootMenu will either boot a default environment or
present a menu.
3. ``teardown`` hooks run immediately before ZFSBootMenu will ``kexec`` the kernel for the selected environment.

When ``zbm-builder.sh`` runs, it will identify custom hooks as executable files in the respective subdirectories of its
build directory:

1. ``hooks.early_setup.d``
2. ``hooks.setup.d``
3. ``hooks.teardown.d``

For each hook directory that contains at least one executable file, ``zbm-builder.sh`` will write custom configuration
snippets for ``dracut`` and ``mkinitcpio`` that will include these files in the output images.
ZFSBootMenu supports :ref:`custom hooks <zbm-dracut-options>` in several stages. When ``zbm-builder.sh`` runs, it will
configure the subdirectory ``hooks`` of the build directory, if it exists, as the value of ``zfsbootmenu_hook_root`` to
allow custom hooks to be included in ZFSBootMenu images.

Fully Customizing Images
~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
126 changes: 87 additions & 39 deletions docs/man/dist/man7/zfsbootmenu.7

Large diffs are not rendered by default.

103 changes: 66 additions & 37 deletions docs/man/zfsbootmenu.7.rst

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions dracut/module-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ installkernel() {

install() {
: "${zfsbootmenu_module_root:=/usr/share/zfsbootmenu}"
: "${zfsbootmenu_hook_root:=/etc/zfsbootmenu/hooks}"

# shellcheck disable=SC1091
if ! source "${zfsbootmenu_module_root}/install-helpers.sh" ; then
Expand Down
11 changes: 3 additions & 8 deletions etc/zbm-builder/mkinitcpio.conf
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,9 @@ HOOKS=(base udev autodetect modconf block filesystems keyboard)
# dracut.conf.d
# mkinitcpio.conf.d
#
# of the build directory for any hook found in the subdirectories
#
# hooks.early_setup.d
# hooks.setup.d
# hooks.teardown.d
#
# of the same build directory. Support for mkinitcpio.conf.d mimics similar
# support for dracut.conf.d built directly into dracut.
# of the build directory for any hooks found in the hooks subdirectory of the
# build directory. Support for mkinitcpio.conf.d mimics similar support for
# dracut.conf.d built directly into dracut.
#
# Note that, inside the container, the build directory will be mounted at
# /build, so reference those paths here.
Expand Down
25 changes: 4 additions & 21 deletions etc/zfsbootmenu/mkinitcpio.conf
Original file line number Diff line number Diff line change
Expand Up @@ -75,25 +75,8 @@ HOOKS=(base udev autodetect modconf block filesystems keyboard zfsbootmenu)
# tested and may break some (non-essential) ZFSBootMenu features.
#zfsbootmenu_miser="no"

# zfsbootmenu_early_setup, zfsbootmenu_setup, zfsbootmenu_teardown
# zfsbootmenu_hook_root
# ZFSBootMenu supports user-provided hooks that may be run at various points in
# the boot process. Set each of these variables to an array of executable files
# that should be installed as user hooks in the provided image. Files that are
# not executable will be ignored. See the zfsbootmenu(7) manual page for more
# details about these hooks.
#
# 'zfsbootmenu_early_setup' hooks are run after ZFS modules are loaded, but
# before ZFSBootMenu attempts to import any pools. Hooks here, for example, can
# unlock LUKS volumes or otherwise manage devices that must be made available
# before a pool can be recognized.
#
# 'zfsbootmenu_setup' hooks are run after pools are imported and right before
# the menu is presented.
#
# 'zfsbootmenu_teardown' hooks are run immediately before a chosen boot
# environment is about to be launched. Any writable ZFS pools will have been
# exported, but read-only pools will generally still be available.
#
#zfsbootmenu_early_setup=()
#zfsbootmenu_setup=()
#zfsbootmenu_teardown=()
# the boot process. Set zfsbootmenu_hook_root to the path of the hooks tree
# that includes a subdirectory for each hook point.
#zfsbootmenu_hook_root="/etc/zfsbootmenu/hooks"
3 changes: 2 additions & 1 deletion initcpio/install/zfsbootmenu
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,10 @@ create_zbm_entrypoint() {


build() {
local hooks relative _file
local _file

: "${zfsbootmenu_module_root:=/usr/share/zfsbootmenu}"
: "${zfsbootmenu_hook_root:=/etc/zfsbootmenu/hooks}"

# shellcheck disable=SC1091
source "${zfsbootmenu_module_root}/install-helpers.sh" || exit 1
Expand Down
1 change: 0 additions & 1 deletion testing/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,6 @@ if [ -n "${DISPLAY_TYPE}" ]; then
# Add release hooks, supported only under Dracut
if ((DRACUT)); then
cat <<-EOF >> "${TESTDIR}/dracut.conf.d/testing.conf"
zfsbootmenu_early_setup+=" $( realpath -e ../contrib )/10-console-init.sh "
zfsbootmenu_early_setup+=" $( realpath -e ../contrib )/20-console-autosize.sh "
EOF
fi
Expand Down
27 changes: 6 additions & 21 deletions zbm-builder.sh
Original file line number Diff line number Diff line change
Expand Up @@ -239,32 +239,17 @@ if ! [ -r "${BUILD_DIRECTORY}"/config.yaml ]; then
fi

# Try to include ZBM hooks in the images by default
for stage in early_setup setup teardown; do
[ -d "${BUILD_DIRECTORY}/hooks.${stage}.d" ] || continue

# Only executable hooks are added to the image
hooks=()
for f in "${BUILD_DIRECTORY}/hooks.${stage}.d"/*; do
[ -x "${f}" ] || continue
hooks+=( "/build/hooks.${stage}.d/${f##*/}" )
done

[ "${#hooks[@]}" -gt 0 ] || continue

hconf="zbm-builder.${stage}.conf"

if [ -d "${BUILD_DIRECTORY}/hooks" ]; then
# Write a dracut configuration snippet
mkdir -p "${BUILD_DIRECTORY}/dracut.conf.d"
echo "zfsbootmenu_${stage}+=\" ${hooks[*]} \"" > "${BUILD_DIRECTORY}/dracut.conf.d/${hconf}"
echo "zfsbootmenu_hook_root=/build/hooks" \
> "${BUILD_DIRECTORY}/dracut.conf.d/user_hooks.conf"

# Write a mkinitcpio configuration snippet
mkdir -p "${BUILD_DIRECTORY}/mkinitcpio.conf.d"
echo "zfsbootmenu_${stage}=(" > "${BUILD_DIRECTORY}/mkinitcpio.conf.d/${hconf}"
for hook in "${hooks[@]}"; do
echo " \"${hook}\"" >> "${BUILD_DIRECTORY}/mkinitcpio.conf.d/${hconf}"
done
echo ")" >> "${BUILD_DIRECTORY}/mkinitcpio.conf.d/${hconf}"
done
echo "zfsbootmenu_hook_root=/build/hooks" \
> "${BUILD_DIRECTORY}/mkinitcpio.conf.d/user_hooks.conf"
fi

# Make `/build` the working directory so relative paths in configs make sense
exec "${PODMAN}" run \
Expand Down
Loading

0 comments on commit 640af57

Please sign in to comment.