Skip to content

Commit

Permalink
Add support early/late hooks in generate-zbm
Browse files Browse the repository at this point in the history
Since generate-zbm only knows how to manage one ESP, it can be a
challenge to keep multiple redundant ESPs up-to-date on a system. To
help with this, Global.PreHooksDir and Global.PostHooksDir can now be
defined to point to a directory of executable hooks. These are executed
without any additional environment context or arguments.
  • Loading branch information
zdykstra committed Dec 10, 2021
1 parent 86e3ca3 commit 2c8eacc
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 0 deletions.
23 changes: 23 additions & 0 deletions bin/generate-zbm
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,15 @@ if ( nonempty $config{Global}{BootMountPoint} ) {
}
}

if ( nonempty $config{Global}{PreHooksDir} and -d $config{Global}{PreHooksDir} ) {
while (my $hook = <$config{Global}{PreHooksDir}/*> ){
next unless -x $hook;
Log("Processing hook: $hook");
my @output = execute(qq($hook));
Log( \@output );
}
}

# Create a temp directory
# It is automatically purged on program exit
my $dir = File::Temp->newdir();
Expand Down Expand Up @@ -536,6 +545,15 @@ EOF
safeCopy( $runConf{syslinux_temp}, $config{Components}{syslinux}{Config} ) or exit 1;
}

if ( nonempty $config{Global}{PostHooksDir} and -d $config{Global}{PostHooksDir} ) {
while (my $hook = <$config{Global}{PostHooksDir}/*> ){
next unless -x $hook;
Log("Processing hook: $hook");
my @output = execute(qq($hook));
Log( \@output );
}
}

END {
cleanupMount;
}
Expand Down Expand Up @@ -928,6 +946,11 @@ sub Log {
chomp($entry);
unless ( ref($entry) ) {
print STDERR "## $entry\n";
} elsif ( ref $entry eq REFARRAY ) {
foreach my $line ( @{ $entry } ) {
chomp $line;
print STDERR "## $line\n";
}
} else {
print STDERR Dumper($entry);
}
Expand Down
52 changes: 52 additions & 0 deletions contrib/esp-sync.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/bin/bash

cleanup() {
if [ -n "${ESP_MNT}" ]; then
mountpoint -q "${ESP_MNT}" && umount -R "${ESP_MNT}"
[ -d "${ESP_MNT}" ] && rmdir "${ESP_MNT}"
fi
}

ESPS=(
"/dev/sdb1"
"/dev/sdc1"
"/dev/sdd1"
)

BMP="$( yq-go eval ".Global.BootMountPoint" /etc/zfsbootmenu/config.yaml )"
if [ -z "${BMP}" ]; then
echo "Unable to determine BootMountPoint"
exit 1
fi

IMG_DIR="$( yq-go eval ".EFI.ImageDir" /etc/zfsbootmenu/config.yaml )"
if [ -z "${IMG_DIR}" ]; then
echo "Unable to determine ImageDir"
exit 1
fi

IMG_REL="${IMG_DIR#"${BMP}"}"

mount "${BMP}"

if ! ESP_MNT="$( mktemp -d )"; then
echo "Unable to create temporary mountpoint"
exit
fi

trap cleanup EXIT INT TERM

for ESP in "${ESPS[@]}"; do
if ! mount "${ESP}" "${ESP_MNT}" ; then
echo "Unable to mount ${ESP} at ${ESP_MNT}"
continue
fi

mkdir -p "${ESP_MNT}${IMG_REL}"
rsync --delete-after -avpP --include=zfsbootmenu\* --exclude=\* "${IMG_DIR}/" "${ESP_MNT}${IMG_REL}/"

if ! umount "${ESP_MNT}" ; then
echo "Unable to unmount ${ESP_MNT}"
exit 1
fi
done
2 changes: 2 additions & 0 deletions etc/zfsbootmenu/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ Global:
ManageImages: false
BootMountPoint: /boot/efi
DracutConfDir: /etc/zfsbootmenu/dracut.conf.d
PreHooksDir: /etc/zfsbootmenu/generate-zbm.pre.d
PostHooksDir: /etc/zfsbootmenu/generate-zbm.post.d
Components:
ImageDir: /boot/efi/EFI/void
Versions: 3
Expand Down
8 changes: 8 additions & 0 deletions pod/generate-zbm.5.pod
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ A specific ZFSBootMenu version string to use in producing images. In the string,

An array of additional arguments that will be passed to B<dracut> when generating an initramfs.

=item B<PreHooksDir>

The path of the directory containing executables that should be executed after I<BootMountPoint> has been mounted. Files in this directory should be B<+x>, and are executed in the order returned by a shell glob. The exit code of each hook is ignored.

=item B<PostHooksDir>

The path of the directory containing executables that should be executed after all images have been created and any file pruning has taken place. Files in this directory should be B<+x>, and are executed in the order returned by a shell glob. The exit code of each hook is ignored.

=back

=head2 Kernel
Expand Down
2 changes: 2 additions & 0 deletions testing/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ if ((YAML)) ; then
yq-go eval ".EFI.Stub = \"${STUBS}/linuxx64.efi.stub\"" -i "${yamlconf}"
yq-go eval ".Global.ManageImages = true" -i "${yamlconf}"
yq-go eval ".Global.DracutConfDir = \"${TESTDIR}/dracut.conf.d\"" -i "${yamlconf}"
yq-go eval ".Global.PreHooksDir = \"${TESTDIR}/generate-zbm.pre.d\"" -i "${yamlconf}"
yq-go eval ".Global.PostHooksDir = \"${TESTDIR}/generate-zbm.post.d\"" -i "${yamlconf}"
yq-go eval ".Global.DracutFlags = [ \"--local\" ]" -i "${yamlconf}"
yq-go eval "del(.Global.BootMountPoint)" -i "${yamlconf}"
yq-go eval -P -C "${yamlconf}"
Expand Down

0 comments on commit 2c8eacc

Please sign in to comment.