From ab464736eca13089ccb597d0b1335ccdf062d034 Mon Sep 17 00:00:00 2001 From: codehelp Date: Sun, 15 Nov 2009 23:15:44 +0000 Subject: [PATCH] Add support for adding extra packages at the end of the run. Work around dash and dpkg-divert issue. Use dpkg -X to avoid problems with data.tar.bz2 and check that the /bin/sh symlink exists. git-svn-id: http://emdebian.org/svn/current@6686 563faec7-e20c-0410-992a-a66f704d0ccd --- debian/changelog | 5 +- em_multistrap | 119 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 105 insertions(+), 19 deletions(-) diff --git a/debian/changelog b/debian/changelog index e7e0a0d..dac1095 100644 --- a/debian/changelog +++ b/debian/changelog @@ -9,8 +9,11 @@ emdebian-rootfs (2.0.4) unstable; urgency=low * [INTL:pt] Initial Portuguese program translation (Closes: #555485) * improve flexibility of genmanpages with changes from po4a. * [INTL:pt] Portuguese translation for manpage (Closes: #556293) + * Add support for adding extra packages at the end of the run. Work + around dash and dpkg-divert issue. Use dpkg -X to avoid problems + with data.tar.bz2 and check that the /bin/sh symlink exists. - -- Neil Williams Sun, 15 Nov 2009 12:34:59 +0000 + -- Neil Williams Sun, 15 Nov 2009 23:09:17 +0000 emdebian-rootfs (2.0.3) unstable; urgency=low diff --git a/em_multistrap b/em_multistrap index 8ad3c2d..4c4a426 100755 --- a/em_multistrap +++ b/em_multistrap @@ -29,7 +29,7 @@ use vars qw/ $progname $ourversion $dstrap $extra @aptsources $dir $include $arch $foreign $suite $url $unpack $sourcedir $msg @e $sourcesname $libdir $dpkgdir @debootstrap %suites $mirror $etcdir $repo @dirs @touch %sources $section %keys $host $key $value $type - $file $config $tidy $noauth $keyring %keyrings $deflist /; + $file $config $tidy $noauth $keyring %keyrings $deflist @extrapkgs /; setlocale(LC_MESSAGES, ""); textdomain("multistrap"); @@ -73,7 +73,7 @@ while( @ARGV ) { die "$progname: "._g("Unknown option")." $_.\n"; } } -$msg = printf (_g("Need a configuration file - use %s -f\n"), $progname); +$msg = sprintf (_g("Need a configuration file - use %s -f\n"), $progname); die ($msg) if (not defined $file); $config = Config::Auto::parse("$file"); @@ -116,6 +116,7 @@ foreach $section (sort keys %keys) $packages{$section}=$keys{$section}{'packages'}; $suites{$section}=$keys{$section}{'suite'}; $keyrings{$section}=$keys{$section}{'keyring'}; + push @extrapkgs, split (' ', lc($keys{$section}{'additional'})); } } # Translators: fields are: programname, versionstring, configfile. @@ -127,6 +128,10 @@ if (not defined $arch) $arch = $host; printf (_g("Defaulting architecture to native: %s\n"),$arch); } +elsif ($arch eq $host) +{ + printf (_g("Defaulting architecture to native: %s\n"),$arch); +} else { printf (_g("Using foreign architecture: %s\n"), $arch); @@ -283,13 +288,20 @@ printf (_g("Getting package lists: apt-get %s update\n"), $config_str); $retval = system ("apt-get $config_str update"); die (sprintf (_g("apt update failed. Exit value: %d\n"), ($retval/256))) if ($retval != 0); -$str = join (' ', values %packages) . " "; +my $required = &get_required_debs; +$str = join (' ', @$required); chomp($str); -$str .= join (' ', values %keyrings) . " "; +$str .= join (' ', values %packages) . " "; chomp($str); -my $required = &get_required_debs; -$str .= join (' ', @$required); +$str .= join (' ', values %keyrings) . " "; chomp($str); +my %uniq=(); +my @s = split (' ', $str); +foreach my $a (@s) +{ + $uniq{$a}++; +} +$str = join (' ', sort keys %uniq); print "apt-get -y $config_str install $str\n"; $retval = system ("apt-get -y $config_str install $str"); die (sprintf (_g("apt download failed. Exit value: %d\n"),($retval/256))) @@ -298,6 +310,7 @@ die (sprintf (_g("apt download failed. Exit value: %d\n"),($retval/256))) &force_unpack if ($unpack eq "true"); system ("touch ${dir}${libdir}lists/lock"); &native if (not defined ($foreign)); +&add_extra_packages; (not defined $tidy) ? system ("apt-get $config_str update") : &tidy_apt; if (-l "${dir}lib64" ) { my $r = readlink "${dir}lib64"; @@ -313,13 +326,39 @@ if (-l "${dir}lib64" ) { } exit 0; +sub add_extra_packages +{ + $str = join (' ', @extrapkgs); + print "apt-get -y $config_str install $str\n"; + $retval = system ("apt-get -y $config_str install $str"); + &force_unpack (@extrapkgs) if ($unpack eq "true"); + system ("touch ${dir}${libdir}lists/lock"); + &native if (not defined ($foreign)); +} + sub force_unpack { + my (@limits) = @_; my %unpack=(); + my %filter = (); opendir (DEBS, "${dir}${cachedir}archives/") or die (_g("Cannot read apt archives directory.\n")); @archives=grep(/.*\.deb$/, readdir DEBS); closedir (DEBS); + if (@limits) + { + foreach my $l (@limits) + { + foreach my $file (@archives) + { + if ($file =~ m:$l:) + { + $filter{$l} = "$file"; + } + } + } + @archives = sort values %filter; + } print _g("I: Calculating obsolete packages\n"); foreach $deb (sort @archives) { @@ -349,19 +388,21 @@ sub force_unpack } $unpack{$package}=$version; } - open (LOCK, ">${dir}${libdir}lists/lock"); - close (LOCK); - opendir (DEBS, "${dir}${cachedir}archives/") - or die (_g("Cannot read apt archives directory.\n")); - @archives=grep(/.*\.deb$/, readdir DEBS); - closedir (DEBS); + if (not @limits) + { + open (LOCK, ">${dir}${libdir}lists/lock"); + close (LOCK); + opendir (DEBS, "${dir}${cachedir}archives/") + or die (_g("Cannot read apt archives directory.\n")); + @archives=grep(/.*\.deb$/, readdir DEBS); + closedir (DEBS); + } my $old = `pwd`; chomp ($old); chdir ("${dir}"); foreach $deb (sort @archives) { printf (_g("I: Extracting %s...\n"), $deb); - system ("ar -p \"./${cachedir}archives/$deb\" data.tar.gz | zcat | tar -xf -"); my $ver=`LC_ALL=C dpkg -f ./${cachedir}archives/$deb Version`; my $pkg=`LC_ALL=C dpkg -f ./${cachedir}archives/$deb Package`; chomp ($ver); @@ -369,9 +410,7 @@ sub force_unpack mkdir ("./tmp"); my $tmpdir = `mktemp -p ./tmp -d -t multistrap.XXXXXX`; chomp ($tmpdir); - mkdir ("./${tmpdir}/listing"); - system ("ar -p \"./${cachedir}archives/$deb\" data.tar.gz > ./${tmpdir}/listing/data.tar.gz"); - my $datatar = `tar -tzf ./${tmpdir}/listing/data.tar.gz`; + my $datatar = `LC_ALL=C dpkg -X ./${cachedir}archives/$deb ${dir}`; my @lines = split("\n", $datatar); open (LIST, ">>./${dpkgdir}info/${pkg}.list"); foreach my $l (@lines) @@ -383,7 +422,6 @@ sub force_unpack print LIST "$l\n"; } close (LIST); - system ("rm -rf ./${tmpdir}/listing"); system ("dpkg -e ./${cachedir}archives/$deb ${tmpdir}/"); opendir (MAINT, "./${tmpdir}"); my @maint=grep(!m:\.\.?:, readdir (MAINT)); @@ -417,7 +455,7 @@ sub force_unpack foreach my $line (@lines) { chomp ($line); - my $md5=`md5sum ./$line | cut -d" " -f1`; + my $md5=`LC_ALL=C md5sum ./$line | cut -d" " -f1`; chomp ($md5); print STATUS " $line $md5\n"; } @@ -444,6 +482,45 @@ sub force_unpack print _g("I: Unpacking complete.\n"); } +sub check_bin_sh +{ + $dir = shift; + my $old = `pwd`; + chomp ($old); + # dash refuses to configure if no existing shell is found. + # (always expects a diversion to already exist). + # (works OK in subsequent upgrades.) #546528 + unlink ("$dir/var/lib/dpkg/info/dash.postinst"); + # now ensure that a usable shell is available as /bin/sh + if (not -l "$dir/bin/sh") + { + print (_g("ERR: ./bin/sh symbolic link does not exist.\n")); + if (-f "$dir/bin/dash") + { + print (_g("INF: Setting ./bin/sh -> ./bin/dash\n")); + chdir ("$dir/bin"); + symlink ("dash", "sh"); + chdir ("$old"); + } + elsif (-f "$dir/bin/bash") + { + print (_g("INF: ./bin/dash not found. Setting ./bin/sh -> ./bin/bash\n")); + chdir ("$dir/bin"); + symlink ("bash", "sh"); + chdir ("$old"); + } + } + if (-l "$dir/bin/sh") + { + print ("${dir}bin/sh found OK:\n"); + system ("(cd $dir ; ls -lh bin/sh)"); + } + else + { + die ("No shell."); + } +} + sub tidy_apt { print _g("I: Tidying up apt cache and list data.\n"); @@ -497,6 +574,8 @@ sub native "DEBCONF_NONINTERACTIVE_SEEN=true ". "LC_ALL=C LANGUAGE=C LANG=C"; printf (_g("I: dpkg configuration settings:\n\t%s\n"), $env); + # check that we have a workable shell inside the chroot + &check_bin_sh("$dir"); system ("$str $env chroot $dir dpkg --configure -a"); } @@ -599,6 +678,10 @@ cleanup=true noauth=false # extract all downloaded archives (default is true) unpack=true +# 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 +# of the target. Order is not important +aptsources=Grip Updates # the order of sections is not important. # the debootstrap option determines which repository # is used to calculate the list of Priority: required packages.