forked from josch/mmdebstrap
Remove support for proot.
The proot mode was broken from the start because in contrast to fakechroot, no ownership information can be retained across multiple invocations of proot. Since mmdebstrap started using apt from the outside by setting DPkg::Chroot-Directory in mmdebstrap 0.8.0 proot mode was finally completely broken because proot cannot wrap the chroot call done by apt. Users of proot are recommended to run mmdebstrap in fakechroot mode and then use proot with the resulting directory.
This commit is contained in:
parent
892e568496
commit
f4a3865c00
4 changed files with 60 additions and 154 deletions
|
@ -34,7 +34,7 @@ Summary:
|
||||||
- chroot with apt in 11 seconds
|
- chroot with apt in 11 seconds
|
||||||
- gzipped tarball with apt is 27M small
|
- gzipped tarball with apt is 27M small
|
||||||
- bit-by-bit reproducible output
|
- bit-by-bit reproducible output
|
||||||
- unprivileged operation using Linux user namespaces, fakechroot or proot
|
- unprivileged operation using Linux user namespaces or fakechroot
|
||||||
- can operate on filesystems mounted with nodev
|
- can operate on filesystems mounted with nodev
|
||||||
- foreign architecture chroots with qemu-user
|
- foreign architecture chroots with qemu-user
|
||||||
- variant installing only Essential:yes packages and dependencies
|
- variant installing only Essential:yes packages and dependencies
|
||||||
|
@ -78,9 +78,9 @@ privileges to create a file (the chroot tarball) in one's home directory.
|
||||||
Thus, mmdebstrap provides multiple options to create a chroot tarball with the
|
Thus, mmdebstrap provides multiple options to create a chroot tarball with the
|
||||||
right permissions **without superuser privileges**. This avoids a whole class
|
right permissions **without superuser privileges**. This avoids a whole class
|
||||||
of bugs like #921815. Depending on what is available, it uses either Linux user
|
of bugs like #921815. Depending on what is available, it uses either Linux user
|
||||||
namespaces, fakechroot or proot. Debootstrap supports fakechroot but will not
|
namespaces or fakechroot. Debootstrap supports fakechroot but will not
|
||||||
create a tarball with the right permissions by itself. Support for Linux user
|
create a tarball with the right permissions by itself. Support for Linux user
|
||||||
namespaces and proot is missing (see bugs #829134 and #698347, respectively).
|
namespaces is missing (see #829134).
|
||||||
|
|
||||||
When creating a chroot tarball with debootstrap, the temporary chroot directory
|
When creating a chroot tarball with debootstrap, the temporary chroot directory
|
||||||
cannot be on a filesystem that has been mounted with nodev. In unprivileged
|
cannot be on a filesystem that has been mounted with nodev. In unprivileged
|
||||||
|
|
190
mmdebstrap
190
mmdebstrap
|
@ -1263,13 +1263,8 @@ sub run_chroot {
|
||||||
error "unsupported type: $type";
|
error "unsupported type: $type";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} elsif (
|
} elsif (any { $_ eq $options->{mode} } ('fakechroot', 'chrootless')) {
|
||||||
any { $_ eq $options->{mode} }
|
# we cannot mount in fakechroot mode
|
||||||
('proot', 'fakechroot', 'chrootless')
|
|
||||||
) {
|
|
||||||
# we cannot mount in fakechroot and proot mode
|
|
||||||
# in proot mode we have /dev bind-mounted already through
|
|
||||||
# --bind=/dev
|
|
||||||
} else {
|
} else {
|
||||||
error "unknown mode: $options->{mode}";
|
error "unknown mode: $options->{mode}";
|
||||||
}
|
}
|
||||||
|
@ -1344,13 +1339,8 @@ sub run_chroot {
|
||||||
# type, bad option, bad superblock" error
|
# type, bad option, bad superblock" error
|
||||||
0 == system('mount', '-o', 'rbind', '/sys', "$options->{root}/sys")
|
0 == system('mount', '-o', 'rbind', '/sys', "$options->{root}/sys")
|
||||||
or error "mount /sys failed: $?";
|
or error "mount /sys failed: $?";
|
||||||
} elsif (
|
} elsif (any { $_ eq $options->{mode} } ('fakechroot', 'chrootless')) {
|
||||||
any { $_ eq $options->{mode} }
|
# we cannot mount in fakechroot mode
|
||||||
('proot', 'fakechroot', 'chrootless')
|
|
||||||
) {
|
|
||||||
# we cannot mount in fakechroot and proot mode
|
|
||||||
# in proot mode we have /proc bind-mounted already through
|
|
||||||
# --bind=/proc
|
|
||||||
} else {
|
} else {
|
||||||
error "unknown mode: $options->{mode}";
|
error "unknown mode: $options->{mode}";
|
||||||
}
|
}
|
||||||
|
@ -1422,13 +1412,8 @@ sub run_chroot {
|
||||||
};
|
};
|
||||||
0 == system('mount', '-t', 'proc', 'proc', "$options->{root}/proc")
|
0 == system('mount', '-t', 'proc', 'proc', "$options->{root}/proc")
|
||||||
or error "mount /proc failed: $?";
|
or error "mount /proc failed: $?";
|
||||||
} elsif (
|
} elsif (any { $_ eq $options->{mode} } ('fakechroot', 'chrootless')) {
|
||||||
any { $_ eq $options->{mode} }
|
# we cannot mount in fakechroot mode
|
||||||
('proot', 'fakechroot', 'chrootless')
|
|
||||||
) {
|
|
||||||
# we cannot mount in fakechroot and proot mode
|
|
||||||
# in proot mode we have /sys bind-mounted already through
|
|
||||||
# --bind=/sys
|
|
||||||
} else {
|
} else {
|
||||||
error "unknown mode: $options->{mode}";
|
error "unknown mode: $options->{mode}";
|
||||||
}
|
}
|
||||||
|
@ -1588,13 +1573,11 @@ sub run_hooks {
|
||||||
)\ /x
|
)\ /x
|
||||||
) {
|
) {
|
||||||
info "running special hook: $script";
|
info "running special hook: $script";
|
||||||
if (
|
if ((any { $_ eq $options->{variant} } ('extract', 'custom'))
|
||||||
any { $_ eq $options->{variant} } ('extract', 'custom')
|
and $options->{mode} eq 'fakechroot'
|
||||||
and any { $_ eq $options->{mode} }
|
and $name ne 'setup') {
|
||||||
('fakechroot', 'proot') and $name ne 'setup'
|
|
||||||
) {
|
|
||||||
info "the copy-in, copy-out, tar-in and tar-out commands"
|
info "the copy-in, copy-out, tar-in and tar-out commands"
|
||||||
. " in fakechroot mode or proot mode might fail in"
|
. " in fakechroot mode might fail in"
|
||||||
. " extract and custom variants because there might be"
|
. " extract and custom variants because there might be"
|
||||||
. " no tar inside the chroot";
|
. " no tar inside the chroot";
|
||||||
}
|
}
|
||||||
|
@ -2120,14 +2103,14 @@ sub run_setup() {
|
||||||
copy($tmpfile, \*STDERR);
|
copy($tmpfile, \*STDERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (none { $_ eq $options->{mode} } ('fakechroot', 'proot')) {
|
if ($options->{mode} ne 'fakechroot') {
|
||||||
# Apt dropping privileges to another user than root is not useful in
|
# Apt dropping privileges to another user than root is not useful in
|
||||||
# fakechroot and proot mode because all users are faked and thus there
|
# fakechroot mode because all users are faked and thus there is no real
|
||||||
# is no real privilege difference anyways. We could set
|
# privilege difference anyways. We could set APT::Sandbox::User "root"
|
||||||
# APT::Sandbox::User "root" in fakechroot and proot mode but we don't
|
# in fakechroot mode but we don't because if we would, then
|
||||||
# because if we would, then /var/cache/apt/archives/partial/ and
|
# /var/cache/apt/archives/partial/ and /var/lib/apt/lists/partial/
|
||||||
# /var/lib/apt/lists/partial/ would not be owned by the _apt user
|
# would not be owned by the _apt user if mmdebstrap was run in
|
||||||
# if mmdebstrap was run in fakechroot or proot mode.
|
# fakechroot mode.
|
||||||
#
|
#
|
||||||
# when apt-get update is run by the root user, then apt will attempt to
|
# when apt-get update is run by the root user, then apt will attempt to
|
||||||
# drop privileges to the _apt user. This will fail if the _apt user
|
# drop privileges to the _apt user. This will fail if the _apt user
|
||||||
|
@ -2539,29 +2522,15 @@ sub run_prepare {
|
||||||
# make sure that APT_CONFIG and TMPDIR are not set when executing
|
# make sure that APT_CONFIG and TMPDIR are not set when executing
|
||||||
# anything inside the chroot
|
# anything inside the chroot
|
||||||
my @chrootcmd = ('env', '--unset=APT_CONFIG', '--unset=TMPDIR');
|
my @chrootcmd = ('env', '--unset=APT_CONFIG', '--unset=TMPDIR');
|
||||||
if ($options->{mode} eq 'proot') {
|
if (any { $_ eq $options->{mode} } ('root', 'unshare', 'fakechroot')) {
|
||||||
push @chrootcmd,
|
|
||||||
(
|
|
||||||
'proot', '--root-id',
|
|
||||||
'--bind=/dev', '--bind=/proc',
|
|
||||||
'--bind=/sys', "--rootfs=$options->{root}",
|
|
||||||
'--cwd=/'
|
|
||||||
);
|
|
||||||
} elsif (
|
|
||||||
any { $_ eq $options->{mode} }
|
|
||||||
('root', 'unshare', 'fakechroot')
|
|
||||||
) {
|
|
||||||
push @chrootcmd, ('chroot', $options->{root});
|
push @chrootcmd, ('chroot', $options->{root});
|
||||||
} else {
|
} else {
|
||||||
error "unknown mode: $options->{mode}";
|
error "unknown mode: $options->{mode}";
|
||||||
}
|
}
|
||||||
|
|
||||||
# copy qemu-user-static binary into chroot or setup proot with
|
# copy qemu-user-static binary into chroot
|
||||||
# --qemu
|
|
||||||
if (defined $options->{qemu}) {
|
if (defined $options->{qemu}) {
|
||||||
if ($options->{mode} eq 'proot') {
|
if ($options->{mode} eq 'fakechroot') {
|
||||||
push @chrootcmd, "--qemu=qemu-$options->{qemu}";
|
|
||||||
} elsif ($options->{mode} eq 'fakechroot') {
|
|
||||||
# Make sure that the fakeroot and fakechroot shared
|
# Make sure that the fakeroot and fakechroot shared
|
||||||
# libraries exist for the right architecture
|
# libraries exist for the right architecture
|
||||||
open my $fh, '-|', 'dpkg-architecture', '-a',
|
open my $fh, '-|', 'dpkg-architecture', '-a',
|
||||||
|
@ -2647,29 +2616,21 @@ sub run_prepare {
|
||||||
}
|
}
|
||||||
|
|
||||||
# some versions of coreutils use the renameat2 system call in mv.
|
# some versions of coreutils use the renameat2 system call in mv.
|
||||||
# This breaks certain versions of fakechroot and proot. Here we do
|
# This breaks certain versions of fakechroot. Here we do
|
||||||
# a sanity check and warn the user in case things might break.
|
# a sanity check and warn the user in case things might break.
|
||||||
if (any { $_ eq $options->{mode} } ('fakechroot', 'proot')
|
if ($options->{mode} eq 'fakechroot'
|
||||||
and -e "$options->{root}/bin/mv") {
|
and -e "$options->{root}/bin/mv") {
|
||||||
mkdir "$options->{root}/000-move-me"
|
mkdir "$options->{root}/000-move-me"
|
||||||
or error "cannot create directory: $!";
|
or error "cannot create directory: $!";
|
||||||
my $ret = system @chrootcmd, '/bin/mv', '/000-move-me',
|
my $ret = system @chrootcmd, '/bin/mv', '/000-move-me',
|
||||||
'/001-delete-me';
|
'/001-delete-me';
|
||||||
if ($ret != 0) {
|
if ($ret != 0) {
|
||||||
if ($options->{mode} eq 'proot') {
|
|
||||||
info "the /bin/mv binary inside the chroot doesn't"
|
|
||||||
. " work under proot";
|
|
||||||
info "this is likely due to missing support for"
|
|
||||||
. " renameat2 in proot";
|
|
||||||
info "see https://github.com/proot-me/PRoot/issues/147";
|
|
||||||
} else {
|
|
||||||
info "the /bin/mv binary inside the chroot doesn't"
|
info "the /bin/mv binary inside the chroot doesn't"
|
||||||
. " work under fakechroot";
|
. " work under fakechroot";
|
||||||
info "with certain versions of coreutils and glibc,"
|
info "with certain versions of coreutils and glibc,"
|
||||||
. " this is due to missing support for renameat2 in"
|
. " this is due to missing support for renameat2 in"
|
||||||
. " fakechroot";
|
. " fakechroot";
|
||||||
info "see https://github.com/dex4er/fakechroot/issues/60";
|
info "see https://github.com/dex4er/fakechroot/issues/60";
|
||||||
}
|
|
||||||
info "expect package post installation scripts not to work";
|
info "expect package post installation scripts not to work";
|
||||||
rmdir "$options->{root}/000-move-me"
|
rmdir "$options->{root}/000-move-me"
|
||||||
or error "cannot rmdir: $!";
|
or error "cannot rmdir: $!";
|
||||||
|
@ -2739,10 +2700,8 @@ sub run_essential() {
|
||||||
'--force-depends'
|
'--force-depends'
|
||||||
],
|
],
|
||||||
PKGS => [map { "$options->{root}/$_" } @{$essential_pkgs}] });
|
PKGS => [map { "$options->{root}/$_" } @{$essential_pkgs}] });
|
||||||
} elsif (
|
} elsif (any { $_ eq $options->{mode} } ('root', 'unshare', 'fakechroot'))
|
||||||
any { $_ eq $options->{mode} }
|
{
|
||||||
('root', 'unshare', 'fakechroot', 'proot')
|
|
||||||
) {
|
|
||||||
# install the extracted packages properly
|
# install the extracted packages properly
|
||||||
# we need --force-depends because dpkg does not take Pre-Depends
|
# we need --force-depends because dpkg does not take Pre-Depends
|
||||||
# into account and thus doesn't install them in the right order
|
# into account and thus doesn't install them in the right order
|
||||||
|
@ -2862,10 +2821,8 @@ sub run_install() {
|
||||||
PKGS => [@pkgs_to_install],
|
PKGS => [@pkgs_to_install],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} elsif (
|
} elsif (any { $_ eq $options->{mode} } ('root', 'unshare', 'fakechroot'))
|
||||||
any { $_ eq $options->{mode} }
|
{
|
||||||
('root', 'unshare', 'fakechroot', 'proot')
|
|
||||||
) {
|
|
||||||
if ($options->{variant} ne 'custom'
|
if ($options->{variant} ne 'custom'
|
||||||
and scalar @pkgs_to_install > 0) {
|
and scalar @pkgs_to_install > 0) {
|
||||||
# Advantage of running apt on the outside instead of inside the
|
# Advantage of running apt on the outside instead of inside the
|
||||||
|
@ -3172,26 +3129,12 @@ sub hookhelper {
|
||||||
. 'delete=atime,delete=ctime'
|
. 'delete=atime,delete=ctime'
|
||||||
);
|
);
|
||||||
if ($hook eq 'setup') {
|
if ($hook eq 'setup') {
|
||||||
if ($mode eq 'proot') {
|
|
||||||
# since we cannot run tar inside the chroot under proot during
|
|
||||||
# the setup hook because the chroot is empty, we have to run
|
|
||||||
# tar from the outside, which leads to all files being owned
|
|
||||||
# by the user running mmdebstrap. To let the ownership
|
|
||||||
# information not be completely off, we force all files be
|
|
||||||
# owned by the root user.
|
|
||||||
push @tarcmd, '--owner=0', '--group=0';
|
|
||||||
}
|
|
||||||
} elsif (any { $_ eq $hook } ('extract', 'essential', 'customize')) {
|
} elsif (any { $_ eq $hook } ('extract', 'essential', 'customize')) {
|
||||||
if ($mode eq 'fakechroot') {
|
if ($mode eq 'fakechroot') {
|
||||||
# Fakechroot requires tar to run inside the chroot or
|
# Fakechroot requires tar to run inside the chroot or
|
||||||
# otherwise absolute symlinks will include the path to the
|
# otherwise absolute symlinks will include the path to the
|
||||||
# root directory
|
# root directory
|
||||||
push @cmdprefix, 'chroot', $root;
|
push @cmdprefix, 'chroot', $root;
|
||||||
} elsif ($mode eq 'proot') {
|
|
||||||
# proot requires tar to run inside proot or otherwise
|
|
||||||
# permissions will be completely off
|
|
||||||
push @cmdprefix, 'proot', '--root-id', "--rootfs=$root",
|
|
||||||
'--cwd=/', "--qemu=$qemu";
|
|
||||||
} elsif (any { $_ eq $mode } ('root', 'chrootless', 'unshare')) {
|
} elsif (any { $_ eq $mode } ('root', 'chrootless', 'unshare')) {
|
||||||
# not chrooting in this case
|
# not chrooting in this case
|
||||||
} else {
|
} else {
|
||||||
|
@ -3222,7 +3165,7 @@ sub hookhelper {
|
||||||
any { $_ eq $hook }
|
any { $_ eq $hook }
|
||||||
('extract', 'essential', 'customize')
|
('extract', 'essential', 'customize')
|
||||||
) {
|
) {
|
||||||
if (any { $_ eq $mode } ('fakechroot', 'proot')) {
|
if ($mode eq 'fakechroot') {
|
||||||
# tar will run inside the chroot
|
# tar will run inside the chroot
|
||||||
$directory = $outpath;
|
$directory = $outpath;
|
||||||
} elsif (
|
} elsif (
|
||||||
|
@ -3237,10 +3180,10 @@ sub hookhelper {
|
||||||
error "unknown hook: $hook";
|
error "unknown hook: $hook";
|
||||||
}
|
}
|
||||||
|
|
||||||
# if chrooted_realpath was used and if neither fakechroot or
|
# if chrooted_realpath was used and if fakechroot
|
||||||
# proot were used (absolute symlinks will be broken) we can
|
# was used (absolute symlinks will be broken) we can
|
||||||
# check and potentially fail early if the target does not exist
|
# check and potentially fail early if the target does not exist
|
||||||
if (none { $_ eq $mode } ('fakechroot', 'proot')) {
|
if ($mode ne 'fakechroot') {
|
||||||
my $dirtocheck = $directory;
|
my $dirtocheck = $directory;
|
||||||
if ($command eq 'upload') {
|
if ($command eq 'upload') {
|
||||||
# check the parent directory instead
|
# check the parent directory instead
|
||||||
|
@ -3369,7 +3312,7 @@ sub hookhelper {
|
||||||
any { $_ eq $hook }
|
any { $_ eq $hook }
|
||||||
('extract', 'essential', 'customize')
|
('extract', 'essential', 'customize')
|
||||||
) {
|
) {
|
||||||
if (any { $_ eq $mode } ('fakechroot', 'proot')) {
|
if ($mode eq 'fakechroot') {
|
||||||
# tar will run inside the chroot
|
# tar will run inside the chroot
|
||||||
$directory = $ARGV[$i];
|
$directory = $ARGV[$i];
|
||||||
} elsif (
|
} elsif (
|
||||||
|
@ -3384,10 +3327,10 @@ sub hookhelper {
|
||||||
error "unknown hook: $hook";
|
error "unknown hook: $hook";
|
||||||
}
|
}
|
||||||
|
|
||||||
# if chrooted_realpath was used and if neither fakechroot or
|
# if chrooted_realpath was used and if fakechroot
|
||||||
# proot were used (absolute symlinks will be broken) we can
|
# was used (absolute symlinks will be broken) we can
|
||||||
# check and potentially fail early if the source does not exist
|
# check and potentially fail early if the source does not exist
|
||||||
if (none { $_ eq $mode } ('fakechroot', 'proot')) {
|
if ($mode ne 'fakechroot') {
|
||||||
if (!-e $directory) {
|
if (!-e $directory) {
|
||||||
error "path does not exist: $directory";
|
error "path does not exist: $directory";
|
||||||
}
|
}
|
||||||
|
@ -4506,8 +4449,7 @@ sub main() {
|
||||||
if ($options->{mode} eq 'sudo') {
|
if ($options->{mode} eq 'sudo') {
|
||||||
$options->{mode} = 'root';
|
$options->{mode} = 'root';
|
||||||
}
|
}
|
||||||
my @valid_modes
|
my @valid_modes = ('auto', 'root', 'unshare', 'fakechroot', 'chrootless');
|
||||||
= ('auto', 'root', 'unshare', 'fakechroot', 'proot', 'chrootless');
|
|
||||||
if (none { $_ eq $options->{mode} } @valid_modes) {
|
if (none { $_ eq $options->{mode} } @valid_modes) {
|
||||||
error "invalid mode. Choose from " . (join ', ', @valid_modes);
|
error "invalid mode. Choose from " . (join ', ', @valid_modes);
|
||||||
}
|
}
|
||||||
|
@ -4631,9 +4573,6 @@ sub main() {
|
||||||
@prefix = ($EXECUTABLE_NAME, '-MDevel::Cover=-silent,-nogcov');
|
@prefix = ($EXECUTABLE_NAME, '-MDevel::Cover=-silent,-nogcov');
|
||||||
}
|
}
|
||||||
exec 'fakechroot', 'fakeroot', @prefix, $PROGRAM_NAME, @ARGVORIG;
|
exec 'fakechroot', 'fakeroot', @prefix, $PROGRAM_NAME, @ARGVORIG;
|
||||||
} elsif (can_execute 'proot') {
|
|
||||||
# and lastly, proot
|
|
||||||
$options->{mode} = 'proot';
|
|
||||||
} else {
|
} else {
|
||||||
error "unable to pick chroot mode automatically";
|
error "unable to pick chroot mode automatically";
|
||||||
}
|
}
|
||||||
|
@ -4642,10 +4581,6 @@ sub main() {
|
||||||
if ($EFFECTIVE_USER_ID != 0) {
|
if ($EFFECTIVE_USER_ID != 0) {
|
||||||
error "need to be root";
|
error "need to be root";
|
||||||
}
|
}
|
||||||
} elsif ($options->{mode} eq 'proot') {
|
|
||||||
if (!can_execute 'proot') {
|
|
||||||
error "need working proot binary";
|
|
||||||
}
|
|
||||||
} elsif ($options->{mode} eq 'fakechroot') {
|
} elsif ($options->{mode} eq 'fakechroot') {
|
||||||
if (&{$check_fakechroot_running}()) {
|
if (&{$check_fakechroot_running}()) {
|
||||||
# fakechroot is already running
|
# fakechroot is already running
|
||||||
|
@ -5376,10 +5311,10 @@ sub main() {
|
||||||
|
|
||||||
if (any { $_ eq $format } ('tar', 'squashfs', 'ext2', 'null')) {
|
if (any { $_ eq $format } ('tar', 'squashfs', 'ext2', 'null')) {
|
||||||
if ($format ne 'null') {
|
if ($format ne 'null') {
|
||||||
if ( any { $_ eq $options->{variant} } ('extract', 'custom')
|
if (any { $_ eq $options->{variant} } ('extract', 'custom')
|
||||||
and any { $_ eq $options->{mode} } ('fakechroot', 'proot')) {
|
and $options->{mode} eq 'fakechroot') {
|
||||||
info "creating a tarball or squashfs image or ext2 image in"
|
info "creating a tarball or squashfs image or ext2 image in"
|
||||||
. " fakechroot mode or proot mode might fail in extract and"
|
. " fakechroot mode might fail in extract and"
|
||||||
. " custom variants because there might be no tar inside the"
|
. " custom variants because there might be no tar inside the"
|
||||||
. " chroot";
|
. " chroot";
|
||||||
}
|
}
|
||||||
|
@ -5517,7 +5452,7 @@ sub main() {
|
||||||
$? == 0 or error "havemknod failed";
|
$? == 0 or error "havemknod failed";
|
||||||
} elsif (
|
} elsif (
|
||||||
any { $_ eq $options->{mode} }
|
any { $_ eq $options->{mode} }
|
||||||
('root', 'fakechroot', 'proot', 'chrootless')
|
('root', 'fakechroot', 'chrootless')
|
||||||
) {
|
) {
|
||||||
$options->{havemknod} = havemknod($options->{root});
|
$options->{havemknod} = havemknod($options->{root});
|
||||||
} else {
|
} else {
|
||||||
|
@ -5678,7 +5613,7 @@ sub main() {
|
||||||
);
|
);
|
||||||
} elsif (
|
} elsif (
|
||||||
any { $_ eq $options->{mode} }
|
any { $_ eq $options->{mode} }
|
||||||
('root', 'fakechroot', 'proot', 'chrootless')
|
('root', 'fakechroot', 'chrootless')
|
||||||
) {
|
) {
|
||||||
$pid = fork() // error "fork() failed: $!";
|
$pid = fork() // error "fork() failed: $!";
|
||||||
if ($pid == 0) {
|
if ($pid == 0) {
|
||||||
|
@ -5741,18 +5676,6 @@ sub main() {
|
||||||
0 == system('chroot', $options->{root}, 'tar',
|
0 == system('chroot', $options->{root}, 'tar',
|
||||||
@taropts, '-C', '/', '.')
|
@taropts, '-C', '/', '.')
|
||||||
or error "tar failed: $?";
|
or error "tar failed: $?";
|
||||||
} elsif ($options->{mode} eq 'proot') {
|
|
||||||
# proot requires tar to run inside proot or otherwise
|
|
||||||
# permissions will be completely off
|
|
||||||
my @qemuopt = ();
|
|
||||||
if (defined $options->{qemu}) {
|
|
||||||
push @qemuopt, "--qemu=qemu-$options->{qemu}";
|
|
||||||
push @taropts, "--exclude=./host-rootfs";
|
|
||||||
}
|
|
||||||
0 == system('proot', '--root-id',
|
|
||||||
"--rootfs=$options->{root}", '--cwd=/', @qemuopt,
|
|
||||||
'tar', @taropts, '-C', '/', '.')
|
|
||||||
or error "tar failed: $?";
|
|
||||||
} elsif (
|
} elsif (
|
||||||
any { $_ eq $options->{mode} }
|
any { $_ eq $options->{mode} }
|
||||||
('root', 'chrootless')
|
('root', 'chrootless')
|
||||||
|
@ -5990,15 +5913,11 @@ sub main() {
|
||||||
}
|
}
|
||||||
} elsif (
|
} elsif (
|
||||||
any { $_ eq $options->{mode} }
|
any { $_ eq $options->{mode} }
|
||||||
('root', 'fakechroot', 'proot', 'chrootless')
|
('root', 'fakechroot', 'chrootless')
|
||||||
) {
|
) {
|
||||||
# without unshare, we use the system's rm to recursively remove the
|
# without unshare, we use the system's rm to recursively remove the
|
||||||
# temporary directory just to make sure that we do not accidentally
|
# temporary directory just to make sure that we do not accidentally
|
||||||
# remove more than we should by using --one-file-system.
|
# remove more than we should by using --one-file-system.
|
||||||
#
|
|
||||||
# --interactive=never is needed when in proot mode, the
|
|
||||||
# write-protected file /apt/apt.conf.d/01autoremove-kernels is to
|
|
||||||
# be removed.
|
|
||||||
0 == system('rm', '--interactive=never', '--recursive',
|
0 == system('rm', '--interactive=never', '--recursive',
|
||||||
'--preserve-root', '--one-file-system', $options->{root})
|
'--preserve-root', '--one-file-system', $options->{root})
|
||||||
or error "rm failed: $?";
|
or error "rm failed: $?";
|
||||||
|
@ -6119,7 +6038,7 @@ B<debootstrap>. See the section B<VARIANTS> for more information.
|
||||||
|
|
||||||
Choose how to perform the chroot operation and create a filesystem with
|
Choose how to perform the chroot operation and create a filesystem with
|
||||||
ownership information different from the current user. Valid mode I<name>s are
|
ownership information different from the current user. Valid mode I<name>s are
|
||||||
B<auto>, B<sudo>, B<root>, B<unshare>, B<fakeroot>, B<fakechroot>, B<proot> and
|
B<auto>, B<sudo>, B<root>, B<unshare>, B<fakeroot>, B<fakechroot> and
|
||||||
B<chrootless>. The default mode is B<auto>. See the section B<MODES> for more
|
B<chrootless>. The default mode is B<auto>. See the section B<MODES> for more
|
||||||
information.
|
information.
|
||||||
|
|
||||||
|
@ -6444,8 +6363,7 @@ This mode automatically selects a fitting mode. If the effective user id is the
|
||||||
one of the superuser, then the B<sudo> mode is chosen. Otherwise, the
|
one of the superuser, then the B<sudo> mode is chosen. Otherwise, the
|
||||||
B<unshare> mode is picked if the system has the sysctl
|
B<unshare> mode is picked if the system has the sysctl
|
||||||
C<kernel.unprivileged_userns_clone> set to C<1>. Should that not be the case
|
C<kernel.unprivileged_userns_clone> set to C<1>. Should that not be the case
|
||||||
and if the fakechroot binary exists, the B<fakechroot> mode is chosen. Lastly,
|
and if the fakechroot binary exists, the B<fakechroot> mode is chosen.
|
||||||
the B<proot> mode is used if the proot binary exists.
|
|
||||||
|
|
||||||
=item B<sudo>, B<root>
|
=item B<sudo>, B<root>
|
||||||
|
|
||||||
|
@ -6497,15 +6415,6 @@ package B<initramfs-tools> until version 0.132. This mode will also not work
|
||||||
with a different libc inside the chroot than on the outside. See the section
|
with a different libc inside the chroot than on the outside. See the section
|
||||||
B<LIMITATIONS> in B<fakechroot(1)>.
|
B<LIMITATIONS> in B<fakechroot(1)>.
|
||||||
|
|
||||||
=item B<proot>
|
|
||||||
|
|
||||||
This mode will carry out all calls to chroot with proot instead. Since
|
|
||||||
ownership information is only retained while proot is still running, this will
|
|
||||||
lead to wrong ownership information in the final directory (everything will be
|
|
||||||
owned by the user that executed B<mmdebstrap>) and tarball (everything will be
|
|
||||||
owned by the root user). Extended attributes are not retained. This mode is
|
|
||||||
useful if you plan to use the chroot with proot.
|
|
||||||
|
|
||||||
=item B<chrootless>
|
=item B<chrootless>
|
||||||
|
|
||||||
Uses the dpkg option C<--force-script-chrootless> to install packages into
|
Uses the dpkg option C<--force-script-chrootless> to install packages into
|
||||||
|
@ -6707,12 +6616,11 @@ directory of the chroot. The path on the outside is relative to current
|
||||||
directory of the original B<mmdebstrap> invocation. The path inside the chroot
|
directory of the original B<mmdebstrap> invocation. The path inside the chroot
|
||||||
must already exist. Paths outside the chroot are created as necessary.
|
must already exist. Paths outside the chroot are created as necessary.
|
||||||
|
|
||||||
In B<fakechroot> and B<proot> mode, C<tar>, or C<sh> and C<cat> have to be run
|
In B<fakechroot> mode, C<tar>, or C<sh> and C<cat> have to be run inside the
|
||||||
inside the chroot or otherwise, symlinks will be wrongly resolved and/or
|
chroot or otherwise, symlinks will be wrongly resolved and/or permissions will
|
||||||
permissions will be off. This means that the special hooks might fail in
|
be off. This means that the special hooks might fail in B<fakechroot> mode for
|
||||||
B<fakechroot> and B<proot> mode for the B<setup> hook or for the B<extract> and
|
the B<setup> hook or for the B<extract> and B<custom> variants if no C<tar> or
|
||||||
B<custom> variants if no C<tar> or C<sh> and C<cat> is available inside the
|
C<sh> and C<cat> is available inside the chroot.
|
||||||
chroot.
|
|
||||||
|
|
||||||
=over 8
|
=over 8
|
||||||
|
|
||||||
|
@ -7216,7 +7124,7 @@ This section lists some differences to debootstrap.
|
||||||
|
|
||||||
=item * Default mirrors for stable releases include updates and security mirror
|
=item * Default mirrors for stable releases include updates and security mirror
|
||||||
|
|
||||||
=item * Multiple ways to operate as non-root: fakechroot, proot, unshare
|
=item * Multiple ways to operate as non-root: fakechroot and unshare
|
||||||
|
|
||||||
=item * twice as fast
|
=item * twice as fast
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ prefix=
|
||||||
$prefix {{ CMD }} --mode={{ MODE }} --variant=apt --architectures=arm64 {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }}
|
$prefix {{ CMD }} --mode={{ MODE }} --variant=apt --architectures=arm64 {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }}
|
||||||
# we ignore differences between architectures by ignoring some files
|
# we ignore differences between architectures by ignoring some files
|
||||||
# and renaming others
|
# and renaming others
|
||||||
# in proot mode, some extra files are put there by proot
|
|
||||||
{ tar -tf /tmp/debian-chroot.tar \
|
{ tar -tf /tmp/debian-chroot.tar \
|
||||||
| grep -v '^\./lib/ld-linux-aarch64\.so\.1$' \
|
| grep -v '^\./lib/ld-linux-aarch64\.so\.1$' \
|
||||||
| grep -v '^\./lib/aarch64-linux-gnu/ld-linux-aarch64\.so\.1$' \
|
| grep -v '^\./lib/aarch64-linux-gnu/ld-linux-aarch64\.so\.1$' \
|
||||||
|
@ -40,6 +39,5 @@ $prefix {{ CMD }} --mode={{ MODE }} --variant=apt --architectures=arm64 {{ DIST
|
||||||
| grep -v '^\./usr/share/doc/[^/]\+/changelog\(\.Debian\)\?\.amd64\.gz$' \
|
| grep -v '^\./usr/share/doc/[^/]\+/changelog\(\.Debian\)\?\.amd64\.gz$' \
|
||||||
| grep -v '^\./usr/share/man/man8/i386\.8\.gz$' \
|
| grep -v '^\./usr/share/man/man8/i386\.8\.gz$' \
|
||||||
| grep -v '^\./usr/share/man/man8/x86_64\.8\.gz$';
|
| grep -v '^\./usr/share/man/man8/x86_64\.8\.gz$';
|
||||||
[ "{{ MODE }}" = "proot" ] && printf "./etc/ld.so.preload\n";
|
|
||||||
} | sort | diff -u - tar2.txt
|
} | sort | diff -u - tar2.txt
|
||||||
rm /tmp/debian-chroot.tar
|
rm /tmp/debian-chroot.tar
|
||||||
|
|
|
@ -19,7 +19,7 @@ prefix=
|
||||||
[ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && prefix="runuser -u user --"
|
[ "$(id -u)" -eq 0 ] && [ "{{ MODE }}" != "root" ] && prefix="runuser -u user --"
|
||||||
[ "{{ MODE }}" = "fakechroot" ] && prefix="$prefix fakechroot fakeroot"
|
[ "{{ MODE }}" = "fakechroot" ] && prefix="$prefix fakechroot fakeroot"
|
||||||
symlinktarget=/real
|
symlinktarget=/real
|
||||||
case {{ MODE }} in fakechroot|proot) symlinktarget='$1/real';; esac
|
[ "{{ MODE }}" = "fakechroot" ] && symlinktarget='$1/real'
|
||||||
echo copy-in-setup > /tmp/copy-in-setup
|
echo copy-in-setup > /tmp/copy-in-setup
|
||||||
echo copy-in-essential > /tmp/copy-in-essential
|
echo copy-in-essential > /tmp/copy-in-essential
|
||||||
echo copy-in-customize > /tmp/copy-in-customize
|
echo copy-in-customize > /tmp/copy-in-customize
|
||||||
|
|
Loading…
Reference in a new issue