allow multiple --architecture options and separation by whitespace

This commit is contained in:
Johannes 'josch' Schauer 2019-10-27 22:04:21 +01:00
parent 7eb0851c59
commit d36ba6b371
Signed by: josch
GPG key ID: F2CBA5C78FBD83E1
2 changed files with 99 additions and 28 deletions

View file

@ -52,7 +52,7 @@ if [ ! -e shared/mmdebstrap ] || [ mmdebstrap -nt shared/mmdebstrap ]; then
fi fi
starttime= starttime=
total=104 total=105
i=1 i=1
print_header() { print_header() {
@ -856,6 +856,42 @@ else
echo "RUN_MA_SAME_TESTS != yes -- Skipping test..." echo "RUN_MA_SAME_TESTS != yes -- Skipping test..."
fi fi
print_header "mode=root,variant=apt: test --include=libmagic-mgc:armhf with multiple --arch options"
cat << END > shared/test.sh
#!/bin/sh
set -eu
export LC_ALL=C.UTF-8
$CMD --mode=root --variant=apt --architectures=amd64 --architectures=armhf --include=libmagic-mgc:armhf $DEFAULT_DIST /tmp/debian-chroot $mirror
{ echo "amd64"; echo "armhf"; } | cmp /tmp/debian-chroot/var/lib/dpkg/arch -
rm /tmp/debian-chroot/var/lib/dpkg/arch
rm /tmp/debian-chroot/var/log/apt/eipp.log.xz
rm /tmp/debian-chroot/var/lib/apt/extended_states
rm /tmp/debian-chroot/var/lib/dpkg/info/libmagic-mgc.list
rm /tmp/debian-chroot/var/lib/dpkg/info/libmagic-mgc.md5sums
rm /tmp/debian-chroot/usr/lib/file/magic.mgc
rm /tmp/debian-chroot/usr/share/doc/libmagic-mgc/README.Debian
rm /tmp/debian-chroot/usr/share/doc/libmagic-mgc/changelog.Debian.gz
rm /tmp/debian-chroot/usr/share/doc/libmagic-mgc/changelog.gz
rm /tmp/debian-chroot/usr/share/doc/libmagic-mgc/copyright
rm /tmp/debian-chroot/usr/share/file/magic.mgc
rm /tmp/debian-chroot/usr/share/misc/magic.mgc
rmdir /tmp/debian-chroot/usr/share/doc/libmagic-mgc/
rmdir /tmp/debian-chroot/usr/share/file/magic/
rmdir /tmp/debian-chroot/usr/share/file/
rmdir /tmp/debian-chroot/usr/lib/file/
tar -C /tmp/debian-chroot --one-file-system -c . | tar -t | sort | diff -u tar1.txt -
rm -r /tmp/debian-chroot
END
if [ "$RUN_MA_SAME_TESTS" = "yes" ]; then
if [ "$HAVE_QEMU" = "yes" ]; then
./run_qemu.sh
else
./run_null.sh SUDO
fi
else
echo "RUN_MA_SAME_TESTS != yes -- Skipping test..."
fi
print_header "mode=root,variant=apt: test --aptopt" print_header "mode=root,variant=apt: test --aptopt"
cat << END > shared/test.sh cat << END > shared/test.sh
#!/bin/sh #!/bin/sh

View file

@ -1778,10 +1778,12 @@ sub main() {
# copy ARGV because getopt modifies it # copy ARGV because getopt modifies it
my @ARGVORIG = @ARGV; my @ARGVORIG = @ARGV;
chomp (my $hostarch = `dpkg --print-architecture`);
my $options = { my $options = {
components => ["main"], components => ["main"],
variant => "important", variant => "important",
include => undef, include => undef,
architectures => [$hostarch],
mode => 'auto', mode => 'auto',
dpkgopts => [], dpkgopts => [],
aptopts => [], aptopts => [],
@ -1790,7 +1792,6 @@ sub main() {
essential_hook => [], essential_hook => [],
customize_hook => [], customize_hook => [],
}; };
chomp ($options->{architectures} = `dpkg --print-architecture`);
my $logfile = undef; my $logfile = undef;
Getopt::Long::Configure ('default', 'bundling', 'auto_abbrev', 'ignore_case_always'); Getopt::Long::Configure ('default', 'bundling', 'auto_abbrev', 'ignore_case_always');
GetOptions( GetOptions(
@ -1799,7 +1800,7 @@ sub main() {
'components=s@' => \$options->{components}, 'components=s@' => \$options->{components},
'variant=s' => \$options->{variant}, 'variant=s' => \$options->{variant},
'include=s' => \$options->{include}, 'include=s' => \$options->{include},
'architectures=s' => \$options->{architectures}, 'architectures=s@' => \$options->{architectures},
'mode=s' => \$options->{mode}, 'mode=s' => \$options->{mode},
'dpkgopt=s@' => \$options->{dpkgopts}, 'dpkgopt=s@' => \$options->{dpkgopts},
'aptopt=s@' => \$options->{aptopts}, 'aptopt=s@' => \$options->{aptopts},
@ -1938,9 +1939,37 @@ sub main() {
error "unknown mode: $options->{mode}"; error "unknown mode: $options->{mode}";
} }
my ($nativearch, @foreignarchs) = split /,/, $options->{architectures}; my @architectures = ();
$options->{nativearch} = $nativearch; foreach my $archs (@{$options->{architectures}}) {
$options->{foreignarchs} = \@foreignarchs; foreach my $arch (split /[,\s]+/, $archs) {
# strip leading and trailing whitespace
$arch =~ s/^\s+|\s+$//g;
# skip if the remainder is an empty string
if ($arch eq '') {
next;
}
# do not append component if it's already in the list
if (any {$_ eq $arch} @architectures) {
next;
}
push @architectures, $arch;
}
}
$options->{nativearch} = $hostarch;
$options->{foreignarchs} = [];
if (scalar @architectures == 0) {
warning "empty architecture list: falling back to native architecture $hostarch";
} elsif (scalar @architectures == 1) {
$options->{nativearch} = $architectures[0];
} else {
$options->{nativearch} = $architectures[0];
push @{$options->{foreignarchs}}, @architectures[1..$#architectures];
}
debug "Native architecture (outside): $hostarch";
debug "Native architecture (inside): $options->{nativearch}";
debug ("Foreign architectures (inside): " . (join ', ', @{$options->{foreignarchs}}));
{ {
# FIXME: autogenerate this list # FIXME: autogenerate this list
@ -1967,8 +1996,7 @@ sub main() {
sparc => 'sparc', sparc => 'sparc',
sparc64 => 'sparc64', sparc64 => 'sparc64',
}; };
chomp (my $hostarch = `dpkg --print-architecture`); if ($hostarch ne $options->{nativearch}) {
if ($hostarch ne $nativearch) {
my $withemu = 0; my $withemu = 0;
my $noemu = 0; my $noemu = 0;
{ {
@ -1976,17 +2004,17 @@ sub main() {
if ($pid == 0) { if ($pid == 0) {
{ {
no warnings; # don't print a warning if the following fails no warnings; # don't print a warning if the following fails
exec 'arch-test', $nativearch; exec 'arch-test', $options->{nativearch};
} }
# if exec didn't work (for example because the arch-test program is # if exec didn't work (for example because the arch-test program is
# missing) prepare for the worst and assume that the architecture # missing) prepare for the worst and assume that the architecture
# cannot be executed # cannot be executed
print "$nativearch: not supported on this machine/kernel\n"; print "$options->{nativearch}: not supported on this machine/kernel\n";
exit 1; exit 1;
} }
chomp (my $content = do { local $/; <$fh> }); chomp (my $content = do { local $/; <$fh> });
close $fh; close $fh;
if ($? == 0 and $content eq "$nativearch: ok") { if ($? == 0 and $content eq "$options->{nativearch}: ok") {
$withemu = 1; $withemu = 1;
} }
} }
@ -1995,17 +2023,17 @@ sub main() {
if ($pid == 0) { if ($pid == 0) {
{ {
no warnings; # don't print a warning if the following fails no warnings; # don't print a warning if the following fails
exec 'arch-test', '-n', $nativearch; exec 'arch-test', '-n', $options->{nativearch};
} }
# if exec didn't work (for example because the arch-test program is # if exec didn't work (for example because the arch-test program is
# missing) prepare for the worst and assume that the architecture # missing) prepare for the worst and assume that the architecture
# cannot be executed # cannot be executed
print "$nativearch: not supported on this machine/kernel\n"; print "$options->{nativearch}: not supported on this machine/kernel\n";
exit 1; exit 1;
} }
chomp (my $content = do { local $/; <$fh> }); chomp (my $content = do { local $/; <$fh> });
close $fh; close $fh;
if ($? == 0 and $content eq "$nativearch: ok") { if ($? == 0 and $content eq "$options->{nativearch}: ok") {
$noemu = 1; $noemu = 1;
} }
} }
@ -2034,10 +2062,10 @@ sub main() {
close $fh; close $fh;
} }
{ {
if (!exists $deb2qemu->{$nativearch}) { if (!exists $deb2qemu->{$options->{nativearch}}) {
warning "no mapping from $nativearch to qemu-user binary"; warning "no mapping from $options->{nativearch} to qemu-user binary";
} else { } else {
my $binfmt_identifier = 'qemu-' . $deb2qemu->{$nativearch}; my $binfmt_identifier = 'qemu-' . $deb2qemu->{$options->{nativearch}};
open my $fh, '-|', '/usr/sbin/update-binfmts', '--display', $binfmt_identifier // error "failed to fork(): $!"; open my $fh, '-|', '/usr/sbin/update-binfmts', '--display', $binfmt_identifier // error "failed to fork(): $!";
chomp (my $binfmts = do { local $/; <$fh> }); chomp (my $binfmts = do { local $/; <$fh> });
close $fh; close $fh;
@ -2046,22 +2074,22 @@ sub main() {
} }
} }
} }
error "$nativearch can neither be executed natively nor via qemu user emulation with binfmt_misc"; error "$options->{nativearch} can neither be executed natively nor via qemu user emulation with binfmt_misc";
} elsif ($withemu == 0 and $noemu == 1) { } elsif ($withemu == 0 and $noemu == 1) {
error "arch-test succeeded without emu but not with emu"; error "arch-test succeeded without emu but not with emu";
} elsif ($withemu == 1 and $noemu == 0) { } elsif ($withemu == 1 and $noemu == 0) {
info "$nativearch cannot be executed, falling back to qemu-user"; info "$options->{nativearch} cannot be executed, falling back to qemu-user";
if (!exists $deb2qemu->{$nativearch}) { if (!exists $deb2qemu->{$options->{nativearch}}) {
error "no mapping from $nativearch to qemu-user binary"; error "no mapping from $options->{nativearch} to qemu-user binary";
} }
$options->{qemu} = $deb2qemu->{$nativearch}; $options->{qemu} = $deb2qemu->{$options->{nativearch}};
} elsif ($withemu == 1 and $noemu == 1) { } elsif ($withemu == 1 and $noemu == 1) {
info "$nativearch is different from $hostarch but can be executed natively"; info "$options->{nativearch} is different from $hostarch but can be executed natively";
} else { } else {
error "logic error"; error "logic error";
} }
} else { } else {
info "chroot architecture $nativearch is equal to the host's architecture"; info "chroot architecture $options->{nativearch} is equal to the host's architecture";
} }
} }
@ -2750,11 +2778,18 @@ of duplicates. So the following are equivalent:
=item B<--architectures>=I<native>[,I<foreign1>,...] =item B<--architectures>=I<native>[,I<foreign1>,...]
Comma separated list of architectures. The first architecture is the I<native> Comma or whitespace separated list of architectures. The first architecture is
architecture inside the chroot. The remaining architectures will be added to the I<native> architecture inside the chroot. The remaining architectures will
the foreign dpkg architectures. Without this option, the I<native> be added to the foreign dpkg architectures. Without this option, the I<native>
architecture of the chroot defaults to the native architecture of the system architecture of the chroot defaults to the native architecture of the system
running B<mmdebstrap>. running B<mmdebstrap>. The option can be specified multiple times and values
are concatenated. If later list items are repeated, then they get dropped so
that the resulting list is free of duplicates. So the following are
equivalent:
--architectures="amd64 armhf mipsel"
--architectures=amd64,armhf,mipsel
--arch=amd64 --arch="armhf mipsel" --arch=armhf,mipsel
=begin comment =begin comment