|
|
@ -23,7 +23,7 @@
|
|
|
|
use strict;
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
use warnings;
|
|
|
|
|
|
|
|
|
|
|
|
our $VERSION = '1.3.0';
|
|
|
|
our $VERSION = '1.3.1';
|
|
|
|
|
|
|
|
|
|
|
|
use English;
|
|
|
|
use English;
|
|
|
|
use Getopt::Long;
|
|
|
|
use Getopt::Long;
|
|
|
@ -961,8 +961,18 @@ sub run_dpkg_progress {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sub run_apt_progress {
|
|
|
|
sub run_apt_progress {
|
|
|
|
my $options = shift;
|
|
|
|
my $options = shift;
|
|
|
|
my @debs = @{ $options->{PKGS} // [] };
|
|
|
|
my @debs = @{ $options->{PKGS} // [] };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ($verbosity_level >= 3) {
|
|
|
|
|
|
|
|
my @apt_debug_opts = qw(
|
|
|
|
|
|
|
|
-oDebug::pkgProblemResolver=true
|
|
|
|
|
|
|
|
-oDebug::pkgDepCache::Marker=1
|
|
|
|
|
|
|
|
-oDebug::pkgDepCache::AutoInstall=1
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
push @{ $options->{ARGV} }, @apt_debug_opts;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
my $get_exec = sub {
|
|
|
|
my $get_exec = sub {
|
|
|
|
my @prefix = ();
|
|
|
|
my @prefix = ();
|
|
|
|
my @opts = ();
|
|
|
|
my @opts = ();
|
|
|
@ -1031,15 +1041,6 @@ sub run_apt_download_progress {
|
|
|
|
info "downloading packages with apt...";
|
|
|
|
info "downloading packages with apt...";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ($verbosity_level >= 3) {
|
|
|
|
|
|
|
|
my @apt_debug_opts = qw(
|
|
|
|
|
|
|
|
-oDebug::pkgProblemResolver=true
|
|
|
|
|
|
|
|
-oDebug::pkgDepCache::Marker=1
|
|
|
|
|
|
|
|
-oDebug::pkgDepCache::AutoInstall=1
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
push @{ $options->{APT_ARGV} }, @apt_debug_opts;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pipe my $rfh, my $wfh;
|
|
|
|
pipe my $rfh, my $wfh;
|
|
|
|
my $pid = open my $fh, '-|' // error "fork() failed: $!";
|
|
|
|
my $pid = open my $fh, '-|' // error "fork() failed: $!";
|
|
|
|
if ($pid == 0) {
|
|
|
|
if ($pid == 0) {
|
|
|
@ -2251,10 +2252,21 @@ sub run_setup() {
|
|
|
|
# root mode when the path of the chroot is not in a world-readable
|
|
|
|
# root mode when the path of the chroot is not in a world-readable
|
|
|
|
# location.
|
|
|
|
# location.
|
|
|
|
my $partial = '/var/lib/apt/lists/partial';
|
|
|
|
my $partial = '/var/lib/apt/lists/partial';
|
|
|
|
if (
|
|
|
|
my @testcmd = (
|
|
|
|
system('/usr/lib/apt/apt-helper', 'drop-privs', '--', 'test',
|
|
|
|
'/usr/lib/apt/apt-helper', 'drop-privs', '--', 'test',
|
|
|
|
'-r', "$options->{root}$partial") != 0
|
|
|
|
'-r', "$options->{root}$partial"
|
|
|
|
) {
|
|
|
|
);
|
|
|
|
|
|
|
|
my $pid = fork() // error "fork() failed: $!";
|
|
|
|
|
|
|
|
if ($pid == 0) {
|
|
|
|
|
|
|
|
open(STDOUT, '>', '/dev/null')
|
|
|
|
|
|
|
|
or error "cannot open /dev/null for writing: $!";
|
|
|
|
|
|
|
|
open(STDERR, '>', '/dev/null')
|
|
|
|
|
|
|
|
or error "cannot open /dev/null for writing: $!";
|
|
|
|
|
|
|
|
exec { $testcmd[0] } @testcmd
|
|
|
|
|
|
|
|
or error("cannot exec " . (join " ", @testcmd) . ": $!");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
waitpid $pid, 0;
|
|
|
|
|
|
|
|
if ($? != 0) {
|
|
|
|
warning "Download is performed unsandboxed as root as file"
|
|
|
|
warning "Download is performed unsandboxed as root as file"
|
|
|
|
. " $options->{root}$partial couldn't be accessed by user _apt";
|
|
|
|
. " $options->{root}$partial couldn't be accessed by user _apt";
|
|
|
|
open my $fh, '>>', $tmpfile
|
|
|
|
open my $fh, '>>', $tmpfile
|
|
|
@ -2602,20 +2614,30 @@ sub run_prepare {
|
|
|
|
$subst{ldconfig}
|
|
|
|
$subst{ldconfig}
|
|
|
|
= '/usr/libexec/mmdebstrap/ldconfig.fakechroot';
|
|
|
|
= '/usr/libexec/mmdebstrap/ldconfig.fakechroot';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
my @fakechrootsubst = ();
|
|
|
|
my %mergedusrmap = (
|
|
|
|
|
|
|
|
"/bin" => "/usr/bin",
|
|
|
|
|
|
|
|
"/sbin" => "/usr/sbin",
|
|
|
|
|
|
|
|
"/usr/bin/" => "/bin",
|
|
|
|
|
|
|
|
"/usr/sbin" => "/sbin"
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
my %fakechrootsubst;
|
|
|
|
foreach my $d (split ':', $ENV{PATH}) {
|
|
|
|
foreach my $d (split ':', $ENV{PATH}) {
|
|
|
|
foreach my $k (sort keys %subst) {
|
|
|
|
foreach my $k (sort %subst) {
|
|
|
|
if (-e "$d/$k") {
|
|
|
|
my $mapped_path = $mergedusrmap{$d} // $d;
|
|
|
|
push @fakechrootsubst, "$d/$k=$subst{$k}";
|
|
|
|
next if !-e "$d/$k" && !-e "$mapped_path/$k";
|
|
|
|
}
|
|
|
|
$fakechrootsubst{"$d/$k=$subst{$k}"} = 1;
|
|
|
|
|
|
|
|
$fakechrootsubst{"$mapped_path/$k=$subst{$k}"} = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (defined $ENV{FAKECHROOT_CMD_SUBST}
|
|
|
|
if (defined $ENV{FAKECHROOT_CMD_SUBST}
|
|
|
|
&& $ENV{FAKECHROOT_CMD_SUBST} ne "") {
|
|
|
|
&& $ENV{FAKECHROOT_CMD_SUBST} ne "") {
|
|
|
|
push @fakechrootsubst, split /:/, $ENV{FAKECHROOT_CMD_SUBST};
|
|
|
|
foreach my $e (split /:/, $ENV{FAKECHROOT_CMD_SUBST}) {
|
|
|
|
|
|
|
|
$fakechrootsubst{$e} = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
## no critic (Variables::RequireLocalizedPunctuationVars)
|
|
|
|
## no critic (Variables::RequireLocalizedPunctuationVars)
|
|
|
|
$ENV{FAKECHROOT_CMD_SUBST} = join ':', @fakechrootsubst;
|
|
|
|
$ENV{FAKECHROOT_CMD_SUBST} = join ':',
|
|
|
|
|
|
|
|
(sort keys %fakechrootsubst);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (defined $ENV{FAKECHROOT_EXCLUDE_PATH}
|
|
|
|
if (defined $ENV{FAKECHROOT_EXCLUDE_PATH}
|
|
|
|
&& $ENV{FAKECHROOT_EXCLUDE_PATH} ne "") {
|
|
|
|
&& $ENV{FAKECHROOT_EXCLUDE_PATH} ne "") {
|
|
|
@ -6704,7 +6726,14 @@ C<Essential:yes> packages.
|
|
|
|
|
|
|
|
|
|
|
|
=item B<apt>
|
|
|
|
=item B<apt>
|
|
|
|
|
|
|
|
|
|
|
|
The B<essential> set plus apt.
|
|
|
|
The B<essential> set plus apt. This variant uses the fact that B<apt> treats
|
|
|
|
|
|
|
|
itself as essential and thus running C<apt-get dist-upgrade> without any
|
|
|
|
|
|
|
|
packages installed will install the B<essential> set plus B<apt>. If you just
|
|
|
|
|
|
|
|
want B<essential> and B<apt>, then this variant is faster than using the
|
|
|
|
|
|
|
|
B<essential> variant and adding B<apt> via C<--include> because all packages
|
|
|
|
|
|
|
|
get installed at once. The downside of this variant is, that if it should
|
|
|
|
|
|
|
|
happen that an B<essential> package is not installable, then it will just get
|
|
|
|
|
|
|
|
ignored without throwing an error.
|
|
|
|
|
|
|
|
|
|
|
|
=item B<required>, B<minbase>
|
|
|
|
=item B<required>, B<minbase>
|
|
|
|
|
|
|
|
|
|
|
@ -7452,6 +7481,15 @@ F</etc/unsupported-skip-usrmerge-conversion> inside the chroot and install the
|
|
|
|
B<usr-is-merged> package to avoid the installation of the B<usrmerge> package
|
|
|
|
B<usr-is-merged> package to avoid the installation of the B<usrmerge> package
|
|
|
|
and its dependencies.
|
|
|
|
and its dependencies.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
If you are using B<mmdebstrap> in a setup where you do not know upfront whether
|
|
|
|
|
|
|
|
the chroot you are creating should be merged-/usr or not and you want to avoid
|
|
|
|
|
|
|
|
installation of the B<usrmerge> package and it's dependencies, you can use:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
--hook-dir=/usr/share/mmdebstrap/hooks/maybe-merged-usr
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
That hook will use the availability of the B<usr-is-merged> package to decide
|
|
|
|
|
|
|
|
whether to call the B<merged-usr> hook or not.
|
|
|
|
|
|
|
|
|
|
|
|
=head1 COMPRESSION
|
|
|
|
=head1 COMPRESSION
|
|
|
|
|
|
|
|
|
|
|
|
B<mmdebstrap> will choose a suitable compressor for the output tarball
|
|
|
|
B<mmdebstrap> will choose a suitable compressor for the output tarball
|
|
|
|