* Add support for MultiArch configuration files and checks for a suitable version of dpkg. * Allow multiple keyring packages to be imported. (Closes: #635584)

git-svn-id: http://emdebian.org/svn/current@8055 563faec7-e20c-0410-992a-a66f704d0ccd
This commit is contained in:
codehelp 2011-07-29 13:12:05 +00:00
parent 04f394acd5
commit 99bbcbe436
10 changed files with 1304 additions and 650 deletions

5
debian/changelog vendored
View file

@ -1,8 +1,11 @@
multistrap (2.1.16) unstable; urgency=low multistrap (2.1.16) unstable; urgency=low
* Allow empty aptsources lines. (Closes: #633525) * Allow empty aptsources lines. (Closes: #633525)
* Add support for MultiArch configuration files and checks for a
suitable version of dpkg.
* Allow multiple keyring packages to be imported. (Closes: #635584)
-- Neil Williams <codehelp@debian.org> Mon, 11 Jul 2011 12:21:09 +0100 -- Neil Williams <codehelp@debian.org> Fri, 29 Jul 2011 13:36:42 +0200
multistrap (2.1.15) unstable; urgency=low multistrap (2.1.15) unstable; urgency=low

6
debian/control vendored
View file

@ -13,7 +13,7 @@ Vcs-Svn: http://www.emdebian.org/svn/current/
Package: multistrap Package: multistrap
Section: admin Section: admin
Architecture: all Architecture: all
Depends: ${perl:Depends}, ${misc:Depends}, apt, Depends: ${perl:Depends}, ${misc:Depends}, apt (>= 0.8.15.2),
libconfig-auto-perl, libparse-debian-packages-perl libconfig-auto-perl, libparse-debian-packages-perl
Recommends: emdebian-archive-keyring Recommends: emdebian-archive-keyring
Suggests: fakeroot Suggests: fakeroot
@ -32,7 +32,9 @@ Description: multiple repository bootstrap based on apt
packages have been unpacked but before being configured. packages have been unpacked but before being configured.
. .
Unlike debootstrap, multistrap relies on working versions of Unlike debootstrap, multistrap relies on working versions of
dpkg and apt outside the final filesystem. dpkg and apt outside the final filesystem. If dpkg supports
MultiArch, foreign architecture libraries can be installed,
where available.
. .
Multistrap supercedes emdebian-rootfs and replaces the previous Multistrap supercedes emdebian-rootfs and replaces the previous
support for preparing root filesystems for specific machines and support for preparing root filesystems for specific machines and

1
debian/dirs vendored Normal file
View file

@ -0,0 +1 @@
/etc/multistrap.d/

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

44
examples/multiarch.conf Normal file
View file

@ -0,0 +1,44 @@
# Example multistrap configuration file for the sid shortcut.
[General]
arch=
directory=
# same as --tidy-up option if set to true
cleanup=true
# same as --no-auth option if set to true
# keyring packages listed in each debootstrap will
# still be installed.
noauth=false
# whether to add the /suite to be explicit about where apt
# needs to look for packages. Default is false.
explicitsuite=false
# extract all downloaded archives (default is true)
unpack=true
# enable MultiArch for the specified architectures
multiarch=armel armhf
# the order of sections is not important.
# the debootstrap option determines which repository
# is used to calculate the list of Priority: required packages.
debootstrap=Debian Foreign ForeignFloat
aptsources=Debian
[Debian]
packages=apt
source=http://ftp.uk.debian.org/debian
keyring=debian-archive-keyring
suite=sid
[Foreign]
packages=libgcc1
packages=libc6
architecture=armel
source=http://ftp.uk.debian.org/debian
keyring=debian-archive-keyring
suite=sid
[ForeignFloat]
packages=libgcc1 libc6
architecture=armhf
source=http://ftp.uk.debian.org/debian
keyring=debian-archive-keyring
suite=sid

View file

@ -35,7 +35,8 @@ use vars qw/ $progname $ourversion $dstrap $extra @aptsources $mirror
$omitpreinst @reinstall $tgzname %uniq %required $check @check %uniq $omitpreinst @reinstall $tgzname %uniq %required $check @check %uniq
$explicit_suite $allow_recommends %omitdebsrc @dsclist @sectoutput $explicit_suite $allow_recommends %omitdebsrc @dsclist @sectoutput
%flatfile %important $addimportant @debconf $hookdir %hooks %flatfile %important $addimportant @debconf $hookdir %hooks
$warn_count /; $warn_count $use_shortcut @foreignarches $olddpkg
%foreignpkgs /;
setlocale(LC_MESSAGES, ""); setlocale(LC_MESSAGES, "");
textdomain("multistrap"); textdomain("multistrap");
@ -43,7 +44,7 @@ $progname = basename($0);
$ourversion = &our_version(); $ourversion = &our_version();
$unpack = "true"; $unpack = "true";
%omitdebsrc=(); %omitdebsrc=();
%foreignpkgs=();
while( @ARGV ) { while( @ARGV ) {
$_= shift( @ARGV ); $_= shift( @ARGV );
last if m/^--$/; last if m/^--$/;
@ -53,6 +54,8 @@ while( @ARGV ) {
} elsif (/^(-\?|-h|--help|--version)$/) { } elsif (/^(-\?|-h|--help|--version)$/) {
&usageversion(); &usageversion();
exit( 0 ); exit( 0 );
} elsif (/^(-s|--shortcut)$/) {
$use_shortcut = shift(@ARGV);
} elsif (/^(-f|--file)$/) { } elsif (/^(-f|--file)$/) {
$file = shift(@ARGV); $file = shift(@ARGV);
} elsif (/^(-a|--arch)$/) { } elsif (/^(-a|--arch)$/) {
@ -74,6 +77,16 @@ while( @ARGV ) {
die "$progname: "._g("Unknown option")." $_.\n"; die "$progname: "._g("Unknown option")." $_.\n";
} }
} }
if (defined $use_shortcut) {
my $short = "/usr/share/multistrap/".$use_shortcut.".conf";
if (-f $short) {
$file = $short;
}
$short = "/etc/multistrap.d/".$use_shortcut.".conf";
if (-f $short) {
$file = $short;
}
}
$msg = sprintf (_g("Need a configuration file - use %s -f\n"), $progname); $msg = sprintf (_g("Need a configuration file - use %s -f\n"), $progname);
die ($msg) die ($msg)
if (not defined $file); if (not defined $file);
@ -160,6 +173,7 @@ if (not -d "$dir") {
} }
$dir = realpath ($dir); $dir = realpath ($dir);
$dir .= ($dir =~ m:/$:) ? '' : "/"; $dir .= ($dir =~ m:/$:) ? '' : "/";
# add a do_it wrapper to check the retval of system
system ("mkdir -p ${dir}${cachedir}") if (not -d "${dir}${cachedir}"); system ("mkdir -p ${dir}${cachedir}") if (not -d "${dir}${cachedir}");
system ("mkdir -p ${dir}${libdir}") if (not -d "${dir}${libdir}"); system ("mkdir -p ${dir}${libdir}") if (not -d "${dir}${libdir}");
system ("mkdir -p ${dir}${dpkgdir}") if (not -d "${dir}${dpkgdir}"); system ("mkdir -p ${dir}${dpkgdir}") if (not -d "${dir}${dpkgdir}");
@ -194,7 +208,19 @@ if (not -d "${dir}etc/network") {
if (not -d "${dir}dev") { if (not -d "${dir}dev") {
mkdir "${dir}dev"; mkdir "${dir}dev";
} }
if ($olddpkg != 0) {
if (not -d "${dir}etc/dpkg/dpkg.cfg.d/") {
system ("mkdir -p ${dir}etc/dpkg/dpkg.cfg.d/");
}
if (not -f "${dir}etc/dpkg/dpkg.cfg.d/multiarch") {
open (MA, ">${dir}etc/dpkg/dpkg.cfg.d/multiarch");
foreach my $farch (@foreignarches) {
print MA "foreign-architecture $farch\n";
}
close (MA);
}
}
die;
&guard_lib64($dir); &guard_lib64($dir);
system ("rm -rf ${dir}etc/apt/sources.list.d/*"); system ("rm -rf ${dir}etc/apt/sources.list.d/*");
@ -280,15 +306,13 @@ if ((defined $k) and (not defined $noauth)) {
} }
foreach my $gpg (@files) { foreach my $gpg (@files) {
next if ($gpg =~ /removed/); next if ($gpg =~ /removed/);
system ("gpg --no-default-keyring ". $retval = system ("gpg --no-default-keyring ".
"--homedir=${dir}/etc/apt/trusted.gpg.d/ ". "--homedir=${dir}/etc/apt/trusted.gpg.d/ ".
"--keyring=multistrap.gpg ". "--keyring=multistrap.gpg ".
" --import ${xdir}/usr/share/keyrings/${gpg} 2>/dev/null"); " --import ${xdir}/usr/share/keyrings/${gpg}");
if (-f "${dir}/etc/apt/trusted.gpg.d/multistrap.gpg") { $retval /= 256;
system ("cp ${dir}/etc/apt/trusted.gpg.d/multistrap.gpg ${dir}/etc/apt/trusted.gpg.d/trustdb.gpg"); die (_g("Secure Apt handling failed - try without authentication."))
} else { if ($retval != 0);
die (_g("Secure Apt handling failed - try without authentication."));
}
} }
system ("rm -rf ${xdir}"); system ("rm -rf ${xdir}");
} }
@ -370,7 +394,7 @@ if ((defined $setupsh) and (-x $setupsh)) {
$warn_count++; $warn_count++;
} }
} }
# run first set of hooks # run first set of hooks - probably unnecessary re setupscript.
&run_download_hooks(sort @{$hooks{'D'}}) if (defined $hooks{'D'}); &run_download_hooks(sort @{$hooks{'D'}}) if (defined $hooks{'D'});
my $err = &native if (not defined ($foreign) and $unpack eq "true"); my $err = &native if (not defined ($foreign) and $unpack eq "true");
if (defined $err and $err != 0) { if (defined $err and $err != 0) {
@ -1012,6 +1036,9 @@ cleanup=true
noauth=false noauth=false
# extract all downloaded archives (default is true) # extract all downloaded archives (default is true)
unpack=true unpack=true
# enable MultiArch for the specified architectures
# default is empty
multiarch=
# aptsources is a list of sections to be used for downloading packages # aptsources is a list of sections to be used for downloading packages
# and lists and placed in the /etc/apt/sources.list.d/multistrap.sources.list # and lists and placed in the /etc/apt/sources.list.d/multistrap.sources.list
# of the target. Order is not important # of the target. Order is not important
@ -1046,6 +1073,7 @@ will be created - it is not packed into a .tgz once complete.
} }
sub cascade { sub cascade {
$olddpkg = &check_multiarch_dpkg;
$file = shift; $file = shift;
$config = Config::Auto::parse($file, format => 'ini'); $config = Config::Auto::parse($file, format => 'ini');
if (not defined $config or (scalar keys %$config) == 0) { if (not defined $config or (scalar keys %$config) == 0) {
@ -1108,7 +1136,14 @@ sub cascade {
push (@{$hooks{'N'}}, $fl) if ($hf =~ /^native/); push (@{$hooks{'N'}}, $fl) if ($hf =~ /^native/);
} }
} }
my @d = split(' ', lc($keys{$section}{'debootstrap'})); my @ma=();
if ($olddpkg != 0) {
@ma = split(' ',lc($keys{$section}{'multiarch'}))
if (defined $keys{$section}{'multiarch'});
}
push @foreignarches, @ma;
my @d=();
@d = split(' ', lc($keys{$section}{'debootstrap'}));
push @debootstrap, @d; push @debootstrap, @d;
my @b = split(' ', lc($keys{$section}{'bootstrap'})) my @b = split(' ', lc($keys{$section}{'bootstrap'}))
if (defined $keys{$section}{'bootstrap'}); if (defined $keys{$section}{'bootstrap'});
@ -1138,11 +1173,33 @@ sub cascade {
# don't set suite or component if URL is of apt-ftparchive trailing-slash form # don't set suite or component if URL is of apt-ftparchive trailing-slash form
# regexp is: optional string in '[]', string without '[' or ']', string ending in '/' # regexp is: optional string in '[]', string without '[' or ']', string ending in '/'
$flatfile{$section}++ if (($sources{$section} =~ /^(\[.*\] )*[^\[\]]+ .+\/$/)); $flatfile{$section}++ if (($sources{$section} =~ /^(\[.*\] )*[^\[\]]+ .+\/$/));
if (exists $keys{$section}{'architecture'}) {
my $frgn_arch = $keys{$section}{'architecture'};
my @tmp=();
if (ref ($keys{$section}{'packages'}) eq 'ARRAY') {
foreach my $p (@{$keys{$section}{'packages'}}) {
push @tmp, "$p:$frgn_arch";
}
} else {
foreach my $p (split(' ', $keys{$section}{'packages'})) {
push @tmp, "$p:$frgn_arch";
}
}
if ($olddpkg == 0) {
$packages{$section} = join(' ', @tmp);
} else {
my $dpkgmsg = sprintf (_g("ERR: Unsupportable option: 'architecture'. ".
"Current dpkg version does not support MultiArch. ".
"Packages for '%s' have been ignored.\n"), $section);
warn $dpkgmsg;
}
} else {
if (ref ($keys{$section}{'packages'}) eq 'ARRAY') { if (ref ($keys{$section}{'packages'}) eq 'ARRAY') {
$packages{$section}=join(' ', @{$keys{$section}{'packages'}}) if (not exists $packages{$section}); $packages{$section}=join(' ', @{$keys{$section}{'packages'}}) if (not exists $packages{$section});
} else { } else {
$packages{$section}=join(' ', $keys{$section}{'packages'}) if (not exists $packages{$section}); $packages{$section}=join(' ', $keys{$section}{'packages'}) if (not exists $packages{$section});
} }
}
$suites{$section}=$keys{$section}{'suite'} $suites{$section}=$keys{$section}{'suite'}
if (not exists $suites{$section} and not exists $flatfile{$section}); if (not exists $suites{$section} and not exists $flatfile{$section});
$components{$section}=$keys{$section}{'components'} $components{$section}=$keys{$section}{'components'}
@ -1170,6 +1227,39 @@ sub cascade {
@extrapkgs = keys %uniq; @extrapkgs = keys %uniq;
} }
# returns zero on success, non-zero on fail
sub check_multiarch_dpkg {
my $distro;
my $version;
my $retval = system ("which lsb_release >/dev/null");
$retval /= 256;
if ($retval == 1) {
# have to assume this is Debian, not Ubuntu
$distro = "debian";
} else {
$distro = lc(`lsb_release -is`);
chomp ($distro);
}
if ($distro eq "debian") {
$version = `dpkg -l dpkg|grep dpkg`;
chomp ($version);
$version =~ s/^ii[ ]+dpkg[ ]+([0-9\.]+)[ ]+.+$/$1/;
# fill in the version which gets this support in Debian
$retval = system("dpkg --compare-versions $version '>=' 1.20");
$retval /= 256;
return $retval;
} else {
# only Ubuntu explicitly supported here
# looking for >= 1.16.0~ubuntu4
$version = `dpkg -l dpkg|grep dpkg`;
chomp ($version);
$version =~ s/^ii[ ]+dpkg[ ]+([^ ]+)[ ]+.+$/$1/;
$retval = system("dpkg --compare-versions $version '>=' 1.16.0~ubuntu4");
$retval /= 256;
return $retval;
}
}
sub _g { sub _g {
return gettext(shift); return gettext(shift);
} }
@ -1272,10 +1362,16 @@ sub dump_config {
print "additional:\t\t$plural".join (", ", sort @extrapkgs)."\n" if (scalar @extrapkgs > 0); print "additional:\t\t$plural".join (", ", sort @extrapkgs)."\n" if (scalar @extrapkgs > 0);
print "reinstall:\t\t".join (", ", sort (@reinstall))."\n" if (scalar @reinstall > 0); print "reinstall:\t\t".join (", ", sort (@reinstall))."\n" if (scalar @reinstall > 0);
if (defined $arch and $arch ne "") { if (defined $arch and $arch ne "") {
printf ("arch:\t\t\t"._g("Architecture to download: %s\n"), $arch); printf ("Architecture:\t\t"._g("Architecture to download: %s\n"), $arch);
} else { } else {
$msg .= sprintf(_g("Cannot determine architecture from '%s'.\n"), $file); $msg .= sprintf(_g("Cannot determine architecture from '%s'.\n"), $file);
} }
if ($olddpkg != 0) {
printf "MultiArch:\t\t%s\n",_g("Currently installed dpkg does not support MultiArch.");
} else {
$plural = ngettext("Foreign architecture", "Foreign architectures", scalar @foreignarches);
printf ("MultiArch:\t\t%s: %s\n", $plural, join(" ", sort @foreignarches));
}
if (defined $dir and $dir ne "") { if (defined $dir and $dir ne "") {
printf ("dir:\t\t\t"._g("Output directory: '%s'\n"), $dir); printf ("dir:\t\t\t"._g("Output directory: '%s'\n"), $dir);
} else { } else {

View file

@ -67,6 +67,9 @@ Example configuration:
# whether to add the /suite to be explicit about where apt # whether to add the /suite to be explicit about where apt
# needs to look for packages. Default is false. # needs to look for packages. Default is false.
explicitsuite=false explicitsuite=false
# enable MultiArch for the specified architectures
# default is empty
multiarch=
# aptsources is a list of sections to be used # aptsources is a list of sections to be used
# the /etc/apt/sources.list.d/multistrap.sources.list # the /etc/apt/sources.list.d/multistrap.sources.list
# of the target. Order is not important # of the target. Order is not important
@ -675,4 +678,42 @@ people on the debian-embedded@lists.debian.org mailing list and
does not parse correctly. You would need to put the C<--simulate> output does not parse correctly. You would need to put the C<--simulate> output
on a pastebin website and put the URL in your message. on a pastebin website and put the URL in your message.
=head1 MultiArch support
To enable multiarch inside a chroot, there is no need to set the second
architecture in C<apt>, C<apt> will ask C<dpkg> which will look in
F</etc/dpkg/dpkg.cfg> or F</etc/dpkg/dpkg.cfg.d/> and then retrieve the
Packages data for each architecture specified using the option:
foreign-architecture armel
For multiple architectures, specify the option once for each
architecture.
Using the MultiArch option in the C<General> section of your C<multistrap>
configuration file will create a file F</etc/dpkg/dpkg.cfg.d/multiarch>
which will implement this support. This option can be repeated (for
compatibility with how dpkg works) or as a space-delimited list of
architectures on a single line.
See also http://wiki.debian.org/Multiarch/
[General]
...
MultiArch=armel armhf
Each Section will install packages from the base architecture unless
the C<Architecture> option is specified for particular sections.
[Foreign]
packages=libgcc1 libc6
architecture=armel
source=http://ftp.uk.debian.org/debian
keyring=debian-archive-keyring
suite=sid
In the C<--simulate> output, the architecture(s) specified in the
MultiArch option will be listed under the "Foreign architectures"
listing.
=cut =cut