add --hook-directory option and a directory with hooks

This commit is contained in:
Johannes 'josch' Schauer 2020-08-16 00:50:46 +02:00
parent e2a759967f
commit 075645289f
Signed by: josch
GPG key ID: F2CBA5C78FBD83E1
6 changed files with 120 additions and 1 deletions

7
hooks/busybox/extract00.sh Executable file
View file

@ -0,0 +1,7 @@
#!/bin/sh
set -exu
rootdir="$1"
chroot "$rootdir" busybox --install -s

13
hooks/busybox/setup00.sh Executable file
View file

@ -0,0 +1,13 @@
#!/bin/sh
set -exu
rootdir="$1"
mkdir -p "$rootdir/bin"
echo root:x:0:0:root:/root:/bin/sh > "$rootdir/etc/passwd"
cat << END > "$rootdir/etc/group"
root:x:0:
mail:x:8:
utmp:x:43:
END

10
hooks/eatmydata/customize.sh Executable file
View file

@ -0,0 +1,10 @@
#!/bin/sh
set -exu
rootdir="$1"
rm "$rootdir/usr/bin/eatmydata"
mv "$rootdir/usr/bin/dpkg.orig" "$rootdir/usr/bin/dpkg"
sync

16
hooks/eatmydata/extract.sh Executable file
View file

@ -0,0 +1,16 @@
#!/bin/sh
set -exu
rootdir="$1"
libdir="/usr/lib/$(dpkg-architecture -q DEB_HOST_MULTIARCH)"
mkdir -p "$rootdir$libdir"
cp -a $libdir/libeatmydata* "$rootdir$libdir"
cp -a /usr/bin/eatmydata "$rootdir/usr/bin"
mv "$rootdir/usr/bin/dpkg" "$rootdir/usr/bin/dpkg.orig"
cat << END > "$rootdir/usr/bin/dpkg"
#!/bin/sh
exec /usr/bin/eatmydata /usr/bin/dpkg.orig "\$@"
END
chmod +x "$rootdir/usr/bin/dpkg"

10
hooks/setup00-merged-usr.sh Executable file
View file

@ -0,0 +1,10 @@
#!/bin/sh
set -exu
rootdir="$1"
for d in bin sbin lib; do
ln -s usr/$d "$rootdir/$d"
mkdir -p "$rootdir/usr/$d"
done

View file

@ -3474,11 +3474,45 @@ sub main() {
sub { push @{ $options->{noop} }, 'no-merged-usr'; },
'force-check-gpg' =>
sub { push @{ $options->{noop} }, 'force-check-gpg'; },
# hook options are hidden until I'm happy with them
'setup-hook=s@' => \$options->{setup_hook},
'extract-hook=s@' => \$options->{extract_hook},
'essential-hook=s@' => \$options->{essential_hook},
'customize-hook=s@' => \$options->{customize_hook},
'hook-directory=s' => sub {
my ($opt_name, $opt_value) = @_;
if (!-e $opt_value) {
error "hook directory \"$opt_value\" does not exist";
}
my $abs_path = abs_path($opt_value);
if (!defined $abs_path) {
error( "unable to get absolute path of "
. "--hook-directory: $opt_value");
}
# since abs_path resolved all symlinks for us, we can now test
# what the actual target actually is
if (!-d $opt_value) {
error "hook directory \"$opt_value\" is not a directory";
}
# gather all files starting with special prefixes into the
# respective keys of a hash
my %scripts;
opendir(my $dh, $opt_value)
or error "Can't opendir($opt_value): $!";
while (my $entry = readdir $dh) {
foreach
my $hook ('setup', 'extract', 'essential', 'customize') {
if ($entry =~ m/^\Q$hook\E/ and -x "$opt_value/$entry") {
push @{$scripts{$hook}}, "$opt_value/$entry";
}
}
}
closedir($dh);
# add the sorted list associated with each key to the respective
# list of hooks
foreach my $hook (keys %scripts) {
push @{ $options->{"${hook}_hook"} }, (sort @{$scripts{$hook}});
}
},
# Sometimes --simulate fails even though non-simulate succeeds because
# in simulate mode, apt cannot rely on dpkg to figure out tricky
# dependency situations and will give up instead when it cannot find
@ -5291,6 +5325,35 @@ Example: Preparing a chroot for use with autopkgtest
--customize-hook='echo "127.0.0.1 localhost host" > "$1/etc/hosts"'
--customize-hook=/usr/share/autopkgtest/setup-commands/setup-testbed
=item B<--hook-directory>=I<directory>
Execute scripts in I<directory> with filenames starting with C<setup>,
C<extract>, C<essential> or C<customize>, at the respective stages during an
mmdebstrap run. The files must be marked executable. Their extension is
ignored. Subdirectories are not traversed. This option is a short-hand for
specifying the remaining four hook options individually for each file in the
directory. If there are more than one script for a stage, then they are added
alphabetically. This is useful in cases, where a user wants to run the same
hooks frequently. For example, given a directory C<./hooks> with two scripts
C<setup01-foo.sh> and C<setup01-bar.sh>, this call:
mmdebstrap --customize=./scriptA --hook-dir=./hooks --setup=./scriptB
is equivalent to this call:
mmdebstrap --customize=./scriptA --setup=./hooks/setup01-foo.sh \
--setup=./hooks/setup02-bar.sh --setup=./scriptB
The option can be specified multiple times and scripts are added to the
respective hooks in the order the options are given on the command line. Thus,
if the scripts in two directories depend upon each other, the scripts must be
placed into a common directory and be named such that they get added in the
correct order.
Example: Run mmdebstrap with eatmydata
--hook-dir=/usr/share/mmdebstrap/hooks/eatmydata
=item B<--skip>=I<stage>[,I<stage>,...]
B<mmdebstrap> tries hard to implement sensible defaults and will try to stop