forked from josch/mmdebstrap
now that fakechroot and proot are fixed, add support for for variants beyond essential and apt
This commit is contained in:
parent
e5564a0dad
commit
1e0b4cb3b0
2 changed files with 164 additions and 99 deletions
39
coverage.sh
39
coverage.sh
|
@ -496,14 +496,18 @@ END
|
||||||
if [ "$variant" = standard ]; then
|
if [ "$variant" = standard ]; then
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
# FIXME: cannot test fakechroot or proot in any other variant
|
|
||||||
# than essential because of
|
|
||||||
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=909637
|
|
||||||
case "$mode" in
|
case "$mode" in
|
||||||
fakechroot|proot)
|
proot)
|
||||||
if [ "$variant" != "essential" ]; then
|
case "$variant" in
|
||||||
|
important|debootstrap|-|standard)
|
||||||
|
# the systemd postint yields:
|
||||||
|
# chfn: PAM: System error
|
||||||
|
# adduser: `/usr/bin/chfn -f systemd Time Synchronization systemd-timesync' returned error code 1. Exiting.
|
||||||
|
# similar error with fakechroot https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=745082#75
|
||||||
|
# https://github.com/proot-me/PRoot/issues/156
|
||||||
continue
|
continue
|
||||||
fi
|
;;
|
||||||
|
esac
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
print_header "mode=$mode,variant=$variant: create tarball"
|
print_header "mode=$mode,variant=$variant: create tarball"
|
||||||
|
@ -714,28 +718,9 @@ fi
|
||||||
|
|
||||||
# test foreign architecture with all modes
|
# test foreign architecture with all modes
|
||||||
# create directory in sudo mode
|
# create directory in sudo mode
|
||||||
# FIXME: once fakechroot and proot are fixed, we have to test more variants
|
|
||||||
# than just essential
|
|
||||||
print_header "mode=root,variant=essential: create directory"
|
|
||||||
cat << END > shared/test.sh
|
|
||||||
#!/bin/sh
|
|
||||||
set -eu
|
|
||||||
export LC_ALL=C.UTF-8
|
|
||||||
$CMD --mode=root --variant=essential unstable /tmp/unstable-chroot.tar $mirror
|
|
||||||
tar -tf /tmp/unstable-chroot.tar | sort > tar1.txt
|
|
||||||
rm /tmp/unstable-chroot.tar
|
|
||||||
END
|
|
||||||
if [ "$HAVE_QEMU" = "yes" ]; then
|
|
||||||
./run_qemu.sh
|
|
||||||
else
|
|
||||||
./run_null.sh SUDO
|
|
||||||
fi
|
|
||||||
|
|
||||||
# FIXME: once fakechroot and proot are fixed, we can switch to variant=apt
|
|
||||||
# FIXME: cannot test fakechroot or proot because of
|
|
||||||
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=909637
|
|
||||||
for mode in root unshare fakechroot proot; do
|
for mode in root unshare fakechroot proot; do
|
||||||
print_header "mode=$mode,variant=essential: create armhf tarball"
|
print_header "mode=$mode,variant=apt: create armhf tarball"
|
||||||
if [ "$HAVE_BINFMT" != "yes" ]; then
|
if [ "$HAVE_BINFMT" != "yes" ]; then
|
||||||
echo "HAVE_BINFMT != yes -- Skipping test..."
|
echo "HAVE_BINFMT != yes -- Skipping test..."
|
||||||
continue
|
continue
|
||||||
|
@ -757,7 +742,7 @@ export LC_ALL=C.UTF-8
|
||||||
prefix=
|
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"
|
||||||
\$prefix $CMD --mode=$mode --variant=essential --architectures=armhf unstable /tmp/unstable-chroot.tar $mirror
|
\$prefix $CMD --mode=$mode --variant=apt --architectures=armhf unstable /tmp/unstable-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 fakechroot mode, we use a fake ldconfig, so we have to
|
# in fakechroot mode, we use a fake ldconfig, so we have to
|
||||||
|
|
116
mmdebstrap
116
mmdebstrap
|
@ -1025,22 +1025,75 @@ sub setup {
|
||||||
# nothing to do
|
# nothing to do
|
||||||
} elsif (any { $_ eq $options->{variant} } ('custom', 'essential', 'apt', 'standard', 'important', 'required', 'buildd', 'minbase')) {
|
} elsif (any { $_ eq $options->{variant} } ('custom', 'essential', 'apt', 'standard', 'important', 'required', 'buildd', 'minbase')) {
|
||||||
if ($options->{mode} eq 'fakechroot') {
|
if ($options->{mode} eq 'fakechroot') {
|
||||||
# FIXME: if trouble arises, look into /etc/fakechroot/*.env for
|
# this borrows from and extends
|
||||||
# more interesting variables to set
|
# /etc/fakechroot/debootstrap.env and /etc/fakechroot/chroot.env
|
||||||
$ENV{FAKECHROOT_CMD_SUBST} = join ':', (
|
{
|
||||||
'/bin/mount=/bin/true',
|
my @fakechrootsubst = ();
|
||||||
'/usr/bin/ldd=/usr/bin/ldd.fakechroot',
|
foreach my $dir ('/usr/sbin', '/usr/bin', '/sbin', '/bin') {
|
||||||
'/usr/bin/mkfifo=/bin/true',
|
push @fakechrootsubst, "$dir/chroot=/usr/sbin/chroot.fakechroot";
|
||||||
'/sbin/ldconfig=/bin/true',
|
push @fakechrootsubst, "$dir/mkfifo=/bin/true";
|
||||||
);
|
push @fakechrootsubst, "$dir/ldconfig=/bin/true";
|
||||||
|
push @fakechrootsubst, "$dir/ldd=/usr/bin/ldd.fakechroot";
|
||||||
|
push @fakechrootsubst, "$dir/ischroot=/bin/true";
|
||||||
|
}
|
||||||
|
if (defined $ENV{FAKECHROOT_CMD_SUBST}
|
||||||
|
&& $ENV{FAKECHROOT_CMD_SUBST} ne "") {
|
||||||
|
push @fakechrootsubst, split /:/, $ENV{FAKECHROOT_CMD_SUBST};
|
||||||
|
}
|
||||||
|
$ENV{FAKECHROOT_CMD_SUBST} = join ':', @fakechrootsubst;
|
||||||
|
}
|
||||||
|
if (defined $ENV{FAKECHROOT_EXCLUDE_PATH}
|
||||||
|
&& $ENV{FAKECHROOT_EXCLUDE_PATH} ne "") {
|
||||||
|
$ENV{FAKECHROOT_EXCLUDE_PATH} = "$ENV{FAKECHROOT_EXCLUDE_PATH}:/dev:/proc:/sys";
|
||||||
|
} else {
|
||||||
|
$ENV{FAKECHROOT_EXCLUDE_PATH} = '/dev:/proc:/sys';
|
||||||
|
}
|
||||||
|
# workaround for long unix socket path if FAKECHROOT_BASE
|
||||||
|
# exceeds the limit of 108 bytes
|
||||||
|
$ENV{FAKECHROOT_AF_UNIX_PATH} = "/tmp";
|
||||||
|
{
|
||||||
|
my @ldsoconf = ('/etc/ld.so.conf');
|
||||||
|
opendir(my $dh, '/etc/ld.so.conf.d') or die "Can't opendir(/etc/ld.so.conf.d): $!";
|
||||||
|
while (my $entry = readdir $dh) {
|
||||||
|
# skip the "." and ".." entries
|
||||||
|
next if $entry eq ".";
|
||||||
|
next if $entry eq "..";
|
||||||
|
next if $entry !~ /\.conf$/;
|
||||||
|
push @ldsoconf, "/etc/ld.so.conf.d/$entry";
|
||||||
|
}
|
||||||
|
closedir($dh);
|
||||||
|
my @ldlibpath = ();
|
||||||
|
if (defined $ENV{LD_LIBRARY_PATH}
|
||||||
|
&& $ENV{LD_LIBRARY_PATH} ne "") {
|
||||||
|
push @ldlibpath, (split /:/, $ENV{LD_LIBRARY_PATH});
|
||||||
|
}
|
||||||
|
# FIXME: workaround allowing installation of systemd should
|
||||||
|
# live in fakechroot, see #917920
|
||||||
|
push @ldlibpath, "/lib/systemd";
|
||||||
|
foreach my $fname (@ldsoconf) {
|
||||||
|
open my $fh, "<", $fname or die "cannot open $fname for reading: $!";
|
||||||
|
while (my $line = <$fh>) {
|
||||||
|
next if $line !~ /^\//;
|
||||||
|
push @ldlibpath, $line;
|
||||||
|
}
|
||||||
|
close $fh;
|
||||||
|
}
|
||||||
|
$ENV{LD_LIBRARY_PATH} = join ':', @ldlibpath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# make sure that APT_CONFIG is not set when executing anything inside the
|
# make sure that APT_CONFIG is not set when executing anything inside the
|
||||||
# chroot
|
# chroot
|
||||||
my @chrootcmd = ('env', '--unset=APT_CONFIG');
|
my @chrootcmd = ('env', '--unset=APT_CONFIG');
|
||||||
if ($options->{mode} eq 'proot') {
|
if ($options->{mode} eq 'proot') {
|
||||||
# FIXME: proot currently cannot install apt because of https://github.com/proot-me/PRoot/issues/147
|
push @chrootcmd, (
|
||||||
push @chrootcmd, ('proot', '--root-id', '--bind=/dev', "--rootfs=$options->{root}", '--cwd=/');
|
'proot',
|
||||||
|
'--root-id',
|
||||||
|
'--bind=/dev',
|
||||||
|
'--bind=/proc',
|
||||||
|
'--bind=/sys',
|
||||||
|
"--rootfs=$options->{root}",
|
||||||
|
'--cwd=/');
|
||||||
} elsif (any { $_ eq $options->{mode} } ('root', 'unshare', 'fakechroot')) {
|
} elsif (any { $_ eq $options->{mode} } ('root', 'unshare', 'fakechroot')) {
|
||||||
push @chrootcmd, ('/usr/sbin/chroot', $options->{root});
|
push @chrootcmd, ('/usr/sbin/chroot', $options->{root});
|
||||||
} else {
|
} else {
|
||||||
|
@ -1223,6 +1276,7 @@ sub setup {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (any { $_ eq $options->{mode} } ('root', 'unshare')) {
|
||||||
# if more than essential should be installed, make the system look
|
# if more than essential should be installed, make the system look
|
||||||
# more like a real one by creating or bind-mounting the device nodes
|
# more like a real one by creating or bind-mounting the device nodes
|
||||||
foreach my $file (@devfiles) {
|
foreach my $file (@devfiles) {
|
||||||
|
@ -1256,6 +1310,12 @@ sub setup {
|
||||||
die "unsupported type: $type";
|
die "unsupported type: $type";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} elsif (any { $_ eq $options->{mode} } ('proot', 'fakechroot')) {
|
||||||
|
# we cannot mount in fakechroot and proot mode
|
||||||
|
# in proot mode we have /dev bind-mounted already through --bind=/dev
|
||||||
|
} else {
|
||||||
|
die "unknown mode: $options->{mode}";
|
||||||
|
}
|
||||||
# We can only mount /proc and /sys after extracting the essential
|
# We can only mount /proc and /sys after extracting the essential
|
||||||
# set because if we mount it before, then base-files will not be able
|
# set because if we mount it before, then base-files will not be able
|
||||||
# to extract those
|
# to extract those
|
||||||
|
@ -1266,12 +1326,22 @@ sub setup {
|
||||||
# we have to rbind because just using bind results in "wrong fs
|
# we have to rbind because just using bind results in "wrong fs
|
||||||
# type, bad option, bad superblock" error
|
# type, bad option, bad superblock" error
|
||||||
0 == system('mount', '-o', 'rbind', '/sys', "$options->{root}/sys") or die "mount failed: $?";
|
0 == system('mount', '-o', 'rbind', '/sys', "$options->{root}/sys") or die "mount failed: $?";
|
||||||
} elsif (any { $_ eq $options->{mode} } ('root', 'fakechroot', 'proot')) {
|
} elsif ($options->{mode} eq 'root') {
|
||||||
0 == system('mount', '-t', 'sysfs', '-o', 'nosuid,nodev,noexec', 'sys', "$options->{root}/sys") or die "mount failed: $?";
|
0 == system('mount', '-t', 'sysfs', '-o', 'nosuid,nodev,noexec', 'sys', "$options->{root}/sys") or die "mount failed: $?";
|
||||||
|
} elsif (any { $_ eq $options->{mode} } ('proot', 'fakechroot')) {
|
||||||
|
# we cannot mount in fakechroot and proot mode
|
||||||
|
# in proot mode we have /proc bind-mounted already through --bind=/proc
|
||||||
} else {
|
} else {
|
||||||
die "unknown mode: $options->{mode}";
|
die "unknown mode: $options->{mode}";
|
||||||
}
|
}
|
||||||
|
if (any { $_ eq $options->{mode} } ('root', 'unshare')) {
|
||||||
0 == system('mount', '-t', 'proc', 'proc', "$options->{root}/proc") or die "mount failed: $?";
|
0 == system('mount', '-t', 'proc', 'proc', "$options->{root}/proc") or die "mount failed: $?";
|
||||||
|
} elsif (any { $_ eq $options->{mode} } ('proot', 'fakechroot')) {
|
||||||
|
# we cannot mount in fakechroot and proot mode
|
||||||
|
# in proot mode we have /sys bind-mounted already through --bind=/sys
|
||||||
|
} else {
|
||||||
|
die "unknown mode: $options->{mode}";
|
||||||
|
}
|
||||||
|
|
||||||
# prevent daemons from starting
|
# prevent daemons from starting
|
||||||
{
|
{
|
||||||
|
@ -1302,6 +1372,7 @@ sub setup {
|
||||||
move("$options->{root}/sbin/start-stop-daemon.REAL", "$options->{root}/sbin/start-stop-daemon") or die "cannot move start-stop-daemon";
|
move("$options->{root}/sbin/start-stop-daemon.REAL", "$options->{root}/sbin/start-stop-daemon") or die "cannot move start-stop-daemon";
|
||||||
unlink "$options->{root}/usr/sbin/policy-rc.d" or die "cannot unlink policy-rc.d";
|
unlink "$options->{root}/usr/sbin/policy-rc.d" or die "cannot unlink policy-rc.d";
|
||||||
|
|
||||||
|
if (any { $_ eq $options->{mode} } ('root', 'unshare')) {
|
||||||
foreach my $file (@devfiles) {
|
foreach my $file (@devfiles) {
|
||||||
my ($fname, undef, $type, $linkname, undef, undef) = @{$file};
|
my ($fname, undef, $type, $linkname, undef, undef) = @{$file};
|
||||||
next if $fname eq './dev/';
|
next if $fname eq './dev/';
|
||||||
|
@ -1311,18 +1382,18 @@ sub setup {
|
||||||
die "type 1 not implemented";
|
die "type 1 not implemented";
|
||||||
} elsif ($type == 2) { # symlink
|
} elsif ($type == 2) { # symlink
|
||||||
if (!$options->{havemknod}) {
|
if (!$options->{havemknod}) {
|
||||||
if ($options->{mode} eq 'fakechroot' and $linkname =~ /^\/proc/) {
|
|
||||||
# there is no /proc in fakechroot mode
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
unlink "$options->{root}/$fname" or die "cannot unlink $fname: $!";
|
unlink "$options->{root}/$fname" or die "cannot unlink $fname: $!";
|
||||||
}
|
}
|
||||||
} elsif ($type == 3 or $type == 4) { # character/block special
|
} elsif ($type == 3 or $type == 4) { # character/block special
|
||||||
if (!$options->{havemknod}) {
|
if (!$options->{havemknod}) {
|
||||||
if ($options->{mode} eq 'unshare') {
|
if ($options->{mode} eq 'unshare') {
|
||||||
|
# FIXME: handle umount by a signal handler in
|
||||||
|
# case of CTRL+C
|
||||||
0 == system('umount', '--no-mtab', "$options->{root}/$fname") or die "umount failed: $?";
|
0 == system('umount', '--no-mtab', "$options->{root}/$fname") or die "umount failed: $?";
|
||||||
} elsif (any { $_ eq $options->{mode} } ('root', 'fakechroot', 'proot')) {
|
} elsif ($options->{mode} eq 'root') {
|
||||||
0 == system('umount', "$options->{root}/$fname") or die "umount failed: $?";
|
0 == system('umount', "$options->{root}/$fname") or die "umount failed: $?";
|
||||||
|
} elsif (any { $_ eq $options->{mode} } ('fakechroot', 'proot')) {
|
||||||
|
die "impossible";
|
||||||
} else {
|
} else {
|
||||||
die "unknown mode: $options->{mode}";
|
die "unknown mode: $options->{mode}";
|
||||||
}
|
}
|
||||||
|
@ -1331,8 +1402,10 @@ sub setup {
|
||||||
} elsif ($type == 5) { # directory
|
} elsif ($type == 5) { # directory
|
||||||
if ($options->{mode} eq 'unshare') {
|
if ($options->{mode} eq 'unshare') {
|
||||||
0 == system('umount', '--no-mtab', "$options->{root}/$fname") or die "umount failed: $?";
|
0 == system('umount', '--no-mtab', "$options->{root}/$fname") or die "umount failed: $?";
|
||||||
} elsif (any { $_ eq $options->{mode} } ('root', 'fakechroot', 'proot')) {
|
} elsif ($options->{mode} eq 'root') {
|
||||||
0 == system('umount', "$options->{root}/$fname") or die "umount failed: $?";
|
0 == system('umount', "$options->{root}/$fname") or die "umount failed: $?";
|
||||||
|
} elsif (any { $_ eq $options->{mode} } ('fakechroot', 'proot')) {
|
||||||
|
die "impossible";
|
||||||
} else {
|
} else {
|
||||||
die "unknown mode: $options->{mode}";
|
die "unknown mode: $options->{mode}";
|
||||||
}
|
}
|
||||||
|
@ -1343,6 +1416,11 @@ sub setup {
|
||||||
die "unsupported type: $type";
|
die "unsupported type: $type";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} elsif (any { $_ eq $options->{mode} } ('proot', 'fakechroot')) {
|
||||||
|
# nothing was mounted
|
||||||
|
} else {
|
||||||
|
die "unknown mode: $options->{mode}";
|
||||||
|
}
|
||||||
# naturally we have to clean up after ourselves in sudo mode where we
|
# naturally we have to clean up after ourselves in sudo mode where we
|
||||||
# do a real mount. But we also need to unmount in unshare mode because
|
# do a real mount. But we also need to unmount in unshare mode because
|
||||||
# otherwise, even with the --one-file-system tar option, the
|
# otherwise, even with the --one-file-system tar option, the
|
||||||
|
@ -1353,9 +1431,11 @@ sub setup {
|
||||||
# unmounting /sys only seems to be successful with --lazy
|
# unmounting /sys only seems to be successful with --lazy
|
||||||
0 == system('umount', '--no-mtab', '--lazy', "$options->{root}/sys") or die "umount failed: $?";
|
0 == system('umount', '--no-mtab', '--lazy', "$options->{root}/sys") or die "umount failed: $?";
|
||||||
0 == system('umount', '--no-mtab', "$options->{root}/proc") or die "umount failed: $?";
|
0 == system('umount', '--no-mtab', "$options->{root}/proc") or die "umount failed: $?";
|
||||||
} elsif (any { $_ eq $options->{mode} } ('root', 'fakechroot', 'proot')) {
|
} elsif ($options->{mode} eq 'root') {
|
||||||
0 == system('umount', "$options->{root}/sys") or die "umount failed: $?";
|
0 == system('umount', "$options->{root}/sys") or die "umount failed: $?";
|
||||||
0 == system('umount', "$options->{root}/proc") or die "umount failed: $?";
|
0 == system('umount', "$options->{root}/proc") or die "umount failed: $?";
|
||||||
|
} elsif (any { $_ eq $options->{mode} } ('proot', 'fakechroot')) {
|
||||||
|
# nothing was mounted
|
||||||
} else {
|
} else {
|
||||||
die "unknown mode: $options->{mode}";
|
die "unknown mode: $options->{mode}";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue