Skip to content

Commit 2c8eacc

Browse files
committed
Add support early/late hooks in generate-zbm
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.
1 parent 86e3ca3 commit 2c8eacc

File tree

5 files changed

+87
-0
lines changed

5 files changed

+87
-0
lines changed

bin/generate-zbm

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,15 @@ if ( nonempty $config{Global}{BootMountPoint} ) {
194194
}
195195
}
196196

197+
if ( nonempty $config{Global}{PreHooksDir} and -d $config{Global}{PreHooksDir} ) {
198+
while (my $hook = <$config{Global}{PreHooksDir}/*> ){
199+
next unless -x $hook;
200+
Log("Processing hook: $hook");
201+
my @output = execute(qq($hook));
202+
Log( \@output );
203+
}
204+
}
205+
197206
# Create a temp directory
198207
# It is automatically purged on program exit
199208
my $dir = File::Temp->newdir();
@@ -536,6 +545,15 @@ EOF
536545
safeCopy( $runConf{syslinux_temp}, $config{Components}{syslinux}{Config} ) or exit 1;
537546
}
538547

548+
if ( nonempty $config{Global}{PostHooksDir} and -d $config{Global}{PostHooksDir} ) {
549+
while (my $hook = <$config{Global}{PostHooksDir}/*> ){
550+
next unless -x $hook;
551+
Log("Processing hook: $hook");
552+
my @output = execute(qq($hook));
553+
Log( \@output );
554+
}
555+
}
556+
539557
END {
540558
cleanupMount;
541559
}
@@ -928,6 +946,11 @@ sub Log {
928946
chomp($entry);
929947
unless ( ref($entry) ) {
930948
print STDERR "## $entry\n";
949+
} elsif ( ref $entry eq REFARRAY ) {
950+
foreach my $line ( @{ $entry } ) {
951+
chomp $line;
952+
print STDERR "## $line\n";
953+
}
931954
} else {
932955
print STDERR Dumper($entry);
933956
}

contrib/esp-sync.sh

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/bin/bash
2+
3+
cleanup() {
4+
if [ -n "${ESP_MNT}" ]; then
5+
mountpoint -q "${ESP_MNT}" && umount -R "${ESP_MNT}"
6+
[ -d "${ESP_MNT}" ] && rmdir "${ESP_MNT}"
7+
fi
8+
}
9+
10+
ESPS=(
11+
"/dev/sdb1"
12+
"/dev/sdc1"
13+
"/dev/sdd1"
14+
)
15+
16+
BMP="$( yq-go eval ".Global.BootMountPoint" /etc/zfsbootmenu/config.yaml )"
17+
if [ -z "${BMP}" ]; then
18+
echo "Unable to determine BootMountPoint"
19+
exit 1
20+
fi
21+
22+
IMG_DIR="$( yq-go eval ".EFI.ImageDir" /etc/zfsbootmenu/config.yaml )"
23+
if [ -z "${IMG_DIR}" ]; then
24+
echo "Unable to determine ImageDir"
25+
exit 1
26+
fi
27+
28+
IMG_REL="${IMG_DIR#"${BMP}"}"
29+
30+
mount "${BMP}"
31+
32+
if ! ESP_MNT="$( mktemp -d )"; then
33+
echo "Unable to create temporary mountpoint"
34+
exit
35+
fi
36+
37+
trap cleanup EXIT INT TERM
38+
39+
for ESP in "${ESPS[@]}"; do
40+
if ! mount "${ESP}" "${ESP_MNT}" ; then
41+
echo "Unable to mount ${ESP} at ${ESP_MNT}"
42+
continue
43+
fi
44+
45+
mkdir -p "${ESP_MNT}${IMG_REL}"
46+
rsync --delete-after -avpP --include=zfsbootmenu\* --exclude=\* "${IMG_DIR}/" "${ESP_MNT}${IMG_REL}/"
47+
48+
if ! umount "${ESP_MNT}" ; then
49+
echo "Unable to unmount ${ESP_MNT}"
50+
exit 1
51+
fi
52+
done

etc/zfsbootmenu/config.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ Global:
22
ManageImages: false
33
BootMountPoint: /boot/efi
44
DracutConfDir: /etc/zfsbootmenu/dracut.conf.d
5+
PreHooksDir: /etc/zfsbootmenu/generate-zbm.pre.d
6+
PostHooksDir: /etc/zfsbootmenu/generate-zbm.post.d
57
Components:
68
ImageDir: /boot/efi/EFI/void
79
Versions: 3

pod/generate-zbm.5.pod

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ A specific ZFSBootMenu version string to use in producing images. In the string,
3838

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

41+
=item B<PreHooksDir>
42+
43+
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.
44+
45+
=item B<PostHooksDir>
46+
47+
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.
48+
4149
=back
4250

4351
=head2 Kernel

testing/setup.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ if ((YAML)) ; then
171171
yq-go eval ".EFI.Stub = \"${STUBS}/linuxx64.efi.stub\"" -i "${yamlconf}"
172172
yq-go eval ".Global.ManageImages = true" -i "${yamlconf}"
173173
yq-go eval ".Global.DracutConfDir = \"${TESTDIR}/dracut.conf.d\"" -i "${yamlconf}"
174+
yq-go eval ".Global.PreHooksDir = \"${TESTDIR}/generate-zbm.pre.d\"" -i "${yamlconf}"
175+
yq-go eval ".Global.PostHooksDir = \"${TESTDIR}/generate-zbm.post.d\"" -i "${yamlconf}"
174176
yq-go eval ".Global.DracutFlags = [ \"--local\" ]" -i "${yamlconf}"
175177
yq-go eval "del(.Global.BootMountPoint)" -i "${yamlconf}"
176178
yq-go eval -P -C "${yamlconf}"

0 commit comments

Comments
 (0)