add docs and initial implementation for hooks
git-svn-id: http://emdebian.org/svn/current@7755 563faec7-e20c-0410-992a-a66f704d0ccd
This commit is contained in:
parent
9fda93fe05
commit
2a7aa089b6
2 changed files with 101 additions and 15 deletions
82
multistrap
82
multistrap
|
@ -354,6 +354,8 @@ die (sprintf (_g("apt download failed. Exit value: %d\n"),($retval/256)))
|
||||||
&force_unpack if ($unpack eq "true");
|
&force_unpack if ($unpack eq "true");
|
||||||
system ("touch ${dir}${libdir}lists/lock");
|
system ("touch ${dir}${libdir}lists/lock");
|
||||||
system ("$setupsh $dir $arch") if ((defined $setupsh) and (-x $setupsh));
|
system ("$setupsh $dir $arch") if ((defined $setupsh) and (-x $setupsh));
|
||||||
|
# run first set of hooks
|
||||||
|
&run_download_hooks(sort @{$hooks{'D'}});
|
||||||
&native if (not defined ($foreign) and $unpack eq "true");
|
&native if (not defined ($foreign) and $unpack eq "true");
|
||||||
&add_extra_packages;
|
&add_extra_packages;
|
||||||
system ("cp $configsh $dir/") if ((defined $configsh) and (-f $configsh));
|
system ("cp $configsh $dir/") if ((defined $configsh) and (-f $configsh));
|
||||||
|
@ -393,6 +395,8 @@ foreach my $aptsrc (@aptsources) {
|
||||||
}
|
}
|
||||||
# altered the sources, so get apt to update.
|
# altered the sources, so get apt to update.
|
||||||
(not defined $tidy) ? system ("apt-get $config_str update") : &tidy_apt;
|
(not defined $tidy) ? system ("apt-get $config_str update") : &tidy_apt;
|
||||||
|
# run second set of hooks
|
||||||
|
&run_completion_hooks(sort @{$hooks{'A'}});
|
||||||
printf (_g("\nMultistrap system installed successfully in %s.\n"), $dir);
|
printf (_g("\nMultistrap system installed successfully in %s.\n"), $dir);
|
||||||
if (defined $tgzname) {
|
if (defined $tgzname) {
|
||||||
printf (_g("\nCompressing multistrap system in '%s' to a tarball called: '%s'.\n"), $dir, $tgzname);
|
printf (_g("\nCompressing multistrap system in '%s' to a tarball called: '%s'.\n"), $dir, $tgzname);
|
||||||
|
@ -563,6 +567,50 @@ sub force_unpack {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub run_download_hooks {
|
||||||
|
my (@hooks) = @_;
|
||||||
|
return if (scalar @hooks == 0);
|
||||||
|
printf(ngettext("I: Running %d post-download hook\n",
|
||||||
|
"I: Running %d post-download hooks\n", scalar @hooks), scalar @hooks);
|
||||||
|
foreach my $hookscript (@hooks) {
|
||||||
|
printf (_g("I: Running post-download hook: '%s'\n"), basename($hookscript));
|
||||||
|
system ("$hookscript $dir");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub run_native_hooks_start {
|
||||||
|
my (@hooks) = @_;
|
||||||
|
return if (scalar @hooks == 0);
|
||||||
|
printf(ngettext("I: Starting %d native hook\n",
|
||||||
|
"I: Starting %d native hooks\n", scalar @hooks), scalar @hooks);
|
||||||
|
foreach my $hookscript (@hooks) {
|
||||||
|
printf (_g("I: Starting native hook: '%s'\n"), basename($hookscript));
|
||||||
|
system ("$hookscript $dir start");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub run_native_hooks_end {
|
||||||
|
my (@hooks) = @_;
|
||||||
|
return if (scalar @hooks == 0);
|
||||||
|
printf(ngettext("I: Stopping %d native hook\n",
|
||||||
|
"I: Stopping %d native hooks\n", scalar @hooks), scalar @hooks);
|
||||||
|
foreach my $hookscript (@hooks) {
|
||||||
|
printf (_g("I: Stopping native hook: '%s'\n"), basename($hookscript));
|
||||||
|
system ("$hookscript $dir end");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub run_completion_hooks {
|
||||||
|
my (@hooks) = @_;
|
||||||
|
return if (scalar @hooks == 0);
|
||||||
|
printf(ngettext("I: Running %d post-configuration hook\n",
|
||||||
|
"I: Running %d post-configuration hooks\n", scalar @hooks), scalar @hooks);
|
||||||
|
foreach my $hookscript (@hooks) {
|
||||||
|
printf (_g("I: Running post-configuration hook: '%s'\n"), basename($hookscript));
|
||||||
|
system ("$hookscript $dir");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# prevent the absolute symlink in libc6 from allowing
|
# prevent the absolute symlink in libc6 from allowing
|
||||||
# writes outside the multistrap root dir. See: #553599
|
# writes outside the multistrap root dir. See: #553599
|
||||||
sub guard_lib64 {
|
sub guard_lib64 {
|
||||||
|
@ -577,10 +625,10 @@ sub guard_lib64 {
|
||||||
} elsif (not -d "${dir}lib64") {
|
} elsif (not -d "${dir}lib64") {
|
||||||
chdir ("$dir");
|
chdir ("$dir");
|
||||||
if ($host eq 'i386' and $arch eq 'amd64') {
|
if ($host eq 'i386' and $arch eq 'amd64') {
|
||||||
print _g("INF: Replaced ./lib64 -> /lib symbolic link with new ./lib64 directory.\n");
|
print _g("I: Replaced ./lib64 -> /lib symbolic link with new ./lib64 directory.\n");
|
||||||
mkdir ("./lib64");
|
mkdir ("./lib64");
|
||||||
} else {
|
} else {
|
||||||
print _g("INF: Setting ./lib64 -> ./lib symbolic link.\n");
|
print _g("I: Setting ./lib64 -> ./lib symbolic link.\n");
|
||||||
symlink "./lib", "lib64";
|
symlink "./lib", "lib64";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -597,14 +645,14 @@ sub check_bin_sh {
|
||||||
unlink ("$dir/var/lib/dpkg/info/dash.postinst");
|
unlink ("$dir/var/lib/dpkg/info/dash.postinst");
|
||||||
# now ensure that a usable shell is available as /bin/sh
|
# now ensure that a usable shell is available as /bin/sh
|
||||||
if (not -l "$dir/bin/sh") {
|
if (not -l "$dir/bin/sh") {
|
||||||
print (_g("INF: ./bin/sh symbolic link does not exist.\n"));
|
print (_g("I: ./bin/sh symbolic link does not exist.\n"));
|
||||||
if (-f "$dir/bin/dash") {
|
if (-f "$dir/bin/dash") {
|
||||||
print (_g("INF: Setting ./bin/sh -> ./bin/dash\n"));
|
print (_g("I: Setting ./bin/sh -> ./bin/dash\n"));
|
||||||
chdir ("$dir/bin");
|
chdir ("$dir/bin");
|
||||||
symlink ("dash", "sh");
|
symlink ("dash", "sh");
|
||||||
chdir ("$old");
|
chdir ("$old");
|
||||||
} elsif (-f "$dir/bin/bash") {
|
} elsif (-f "$dir/bin/bash") {
|
||||||
print (_g("INF: ./bin/dash not found. Setting ./bin/sh -> ./bin/bash\n"));
|
print (_g("I: ./bin/dash not found. Setting ./bin/sh -> ./bin/bash\n"));
|
||||||
chdir ("$dir/bin");
|
chdir ("$dir/bin");
|
||||||
symlink ("bash", "sh");
|
symlink ("bash", "sh");
|
||||||
chdir ("$old");
|
chdir ("$old");
|
||||||
|
@ -694,6 +742,7 @@ sub native {
|
||||||
system ("$str $env chroot $dir debconf-set-selections /tmp/preseeds/$s");
|
system ("$str $env chroot $dir debconf-set-selections /tmp/preseeds/$s");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&run_native_hooks_start(sort @{$hooks{'N'}});
|
||||||
opendir (PRI, "${dir}/var/lib/dpkg/info") or return;
|
opendir (PRI, "${dir}/var/lib/dpkg/info") or return;
|
||||||
my @preinsts=grep(/\.preinst$/, readdir PRI);
|
my @preinsts=grep(/\.preinst$/, readdir PRI);
|
||||||
closedir (PRI);
|
closedir (PRI);
|
||||||
|
@ -711,6 +760,7 @@ sub native {
|
||||||
foreach my $reinst (sort @reinstall) {
|
foreach my $reinst (sort @reinstall) {
|
||||||
system ("$str $env chroot $dir apt-get --reinstall -y install $reinst");
|
system ("$str $env chroot $dir apt-get --reinstall -y install $reinst");
|
||||||
}
|
}
|
||||||
|
&run_native_hooks_end(sort @{$hooks{'N'}});
|
||||||
}
|
}
|
||||||
|
|
||||||
sub get_required_debs {
|
sub get_required_debs {
|
||||||
|
@ -907,8 +957,9 @@ sub cascade {
|
||||||
my $fl = `realpath $f/$hf 2>/dev/null`;
|
my $fl = `realpath $f/$hf 2>/dev/null`;
|
||||||
chomp ($fl);
|
chomp ($fl);
|
||||||
next if (($fl eq "") or (not -f $fl) or (not -x $fl));
|
next if (($fl eq "") or (not -f $fl) or (not -x $fl));
|
||||||
push (@{$hooks{'A'}}, $fl) if ($hf =~ /^A/);
|
push (@{$hooks{'A'}}, $fl) if ($hf =~ /^completion/);
|
||||||
push (@{$hooks{'D'}}, $fl) if ($hf =~ /^D/);
|
push (@{$hooks{'D'}}, $fl) if ($hf =~ /^download/);
|
||||||
|
push (@{$hooks{'N'}}, $fl) if ($hf =~ /^native/);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
my @d = split(' ', lc($keys{$section}{'debootstrap'}));
|
my @d = split(' ', lc($keys{$section}{'debootstrap'}));
|
||||||
|
@ -1053,11 +1104,18 @@ sub dump_config {
|
||||||
}
|
}
|
||||||
$plural = ngettext("Debconf preseed file", "Debconf preseed files", scalar @debconf);
|
$plural = ngettext("Debconf preseed file", "Debconf preseed files", scalar @debconf);
|
||||||
printf("%s:\t%s\n", $plural, join(" ", sort @debconf)) if (scalar @debconf > 0);
|
printf("%s:\t%s\n", $plural, join(" ", sort @debconf)) if (scalar @debconf > 0);
|
||||||
$plural = ngettext ("Hook: ", "", scalar @extrapkgs);
|
if (defined ($hooks{'D'} and scalar @{$hooks{'D'}} > 0)) {
|
||||||
print "hooks (A):\t\t$plural".join (", ", sort @{$hooks{'A'}})."\n"
|
$plural = ngettext ("Download hook: ", "", scalar @{$hooks{'D'}});
|
||||||
if (defined ($hooks{'A'} and scalar @{$hooks{'A'}} > 0));
|
print "download hooks:\t\t$plural".join (", ", sort @{$hooks{'D'}})."\n";
|
||||||
print "hooks (D):\t\t$plural".join (", ", sort @{$hooks{'D'}})."\n"
|
}
|
||||||
if (defined ($hooks{'D'} and scalar @{$hooks{'D'}} > 0));
|
if (defined ($hooks{'N'} and scalar @{$hooks{'N'}} > 0)) {
|
||||||
|
$plural = ngettext ("Native hook: ", "", scalar @{$hooks{'N'}});
|
||||||
|
print "native hooks:\t\t$plural".join (", ", sort @{$hooks{'N'}})."\n";
|
||||||
|
}
|
||||||
|
if (defined ($hooks{'A'} and scalar @{$hooks{'A'}} > 0)) {
|
||||||
|
$plural = ngettext ("Completion hook: ", "", scalar @{$hooks{'A'}});
|
||||||
|
print "completion hooks:\t$plural".join (", ", sort @{$hooks{'A'}})."\n";
|
||||||
|
}
|
||||||
$plural = ngettext ("Extra Package: ", "Extra Packages: ", scalar @extrapkgs);
|
$plural = ngettext ("Extra Package: ", "Extra Packages: ", scalar @extrapkgs);
|
||||||
print "additional:\t\t$plural".join (", ", sort @extrapkgs)."\n" if (scalar @extrapkgs > 0);
|
print "additional:\t\t$plural".join (", ", sort @extrapkgs)."\n" if (scalar @extrapkgs > 0);
|
||||||
print "reinstall:\t\t".join (", ", sort (@reinstall))."\n" if (scalar @reinstall > 0);
|
print "reinstall:\t\t".join (", ", sort (@reinstall))."\n" if (scalar @reinstall > 0);
|
||||||
|
|
|
@ -400,6 +400,9 @@ into C<multistrap> configuration variables. The machine:variant
|
||||||
support in C<multistrap> concentrates on the scripts,
|
support in C<multistrap> concentrates on the scripts,
|
||||||
F<config.sh> and F<setup.sh>
|
F<config.sh> and F<setup.sh>
|
||||||
|
|
||||||
|
Note: B<machine:variant support is likely to be replaced by the
|
||||||
|
hook functionality described below.>
|
||||||
|
|
||||||
Once C<multistrap> has unpacked the downloaded packages, the
|
Once C<multistrap> has unpacked the downloaded packages, the
|
||||||
C<setup.sh> can be called, passing the location and architecture of
|
C<setup.sh> can be called, passing the location and architecture of
|
||||||
the root filesystem, so that other fine tuning can take place. At
|
the root filesystem, so that other fine tuning can take place. At
|
||||||
|
@ -598,20 +601,45 @@ If a hook directory is specified in the General section of the
|
||||||
C<multistrap> configuration file, the hook scripts which are executable
|
C<multistrap> configuration file, the hook scripts which are executable
|
||||||
will be run from outside the multistrap directory at the following stages:
|
will be run from outside the multistrap directory at the following stages:
|
||||||
|
|
||||||
A hooks
|
=over 1
|
||||||
|
|
||||||
Executed before unpacking is started
|
=item download hooks
|
||||||
|
|
||||||
D hooks
|
Executed before unpacking is started, immediately after the packages
|
||||||
|
have been downloaded. Download hooks are executable scripts in the
|
||||||
|
specified hook directory with a filename beginning with B<download>.
|
||||||
|
|
||||||
|
=item native hooks
|
||||||
|
|
||||||
|
Native hook scripts are executed only in native mode, immediately before
|
||||||
|
starting the configuration of the downloaded packages and again upon
|
||||||
|
completion of the package configuration. Native hooks will be called
|
||||||
|
the absolute path and the current progress state, start or end.
|
||||||
|
|
||||||
|
Native scripts are executable scripts in the specified hook directory
|
||||||
|
with a filename beginning with B<native>.
|
||||||
|
|
||||||
|
=item completion hooks
|
||||||
|
|
||||||
Executed immediately before the tarball is created or C<multistrap> exits
|
Executed immediately before the tarball is created or C<multistrap> exits
|
||||||
if not configured to create a tarball.
|
if not configured to create a tarball.
|
||||||
|
|
||||||
|
Completion scripts are executable scripts in the specified hook directory
|
||||||
|
with a filename beginning with C<completion>.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
Hooks are passed the absolute path to the directory which will be the
|
Hooks are passed the absolute path to the directory which will be the
|
||||||
top level directory of the chroot or multistrap system. Hooks which
|
top level directory of the chroot or multistrap system. Hooks which
|
||||||
cannot be resolved using realpath or which are not executable will be
|
cannot be resolved using realpath or which are not executable will be
|
||||||
ignored.
|
ignored.
|
||||||
|
|
||||||
|
All hooks of one type are sorted into alphabetical order before being
|
||||||
|
run.
|
||||||
|
|
||||||
|
Note that C<multistrap> does not rollback the effects of hooks in the
|
||||||
|
case of errors.
|
||||||
|
|
||||||
=head1 Output
|
=head1 Output
|
||||||
|
|
||||||
C<multistrap> can produce a lot of output - informational messages
|
C<multistrap> can produce a lot of output - informational messages
|
||||||
|
|
Loading…
Reference in a new issue