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:
Johannes Schauer Marin Rodrigues 2022-09-05 05:50:50 +02:00
parent 892e568496
commit f4a3865c00
Signed by: josch
GPG key ID: F2CBA5C78FBD83E1
4 changed files with 60 additions and 154 deletions

View file

@ -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

View file

@ -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
@ -5377,9 +5312,9 @@ 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

View file

@ -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

View file

@ -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