Package: dpkg
Version: 1.14.25
Severity: normal
dpkg --unpack needs to be able to work without executing any maintainer
scripts, just
extracting the data.tar.gz, decompressing the control.tar.gz, moving maintainer
scripts
to the var/lib/dpkg/info/ directory, handling var/lib/dpkg/status and
var/lib/dpkg/available
and leaving the status of the package as "Status: install ok unpacked"
This mode is particularly important for debootstrap usage when the archives are
for a
different architecture to the host system. I've had to implement two versions
of this
support, one in shell and one in perl, for Emdebian. The main objective is to
achieve
a debootstrap that leaves an almost complete filesystem with every file in
place and
only needing 'dpkg --configure -a' to be run on the actual machine.
Emdebian Grip has a particular need for this support, so that the debootstrap'd
directory
can be packed into a .tar.gz *without* needing to carry large numbers of .deb
packages in
var/cache/apt/archives/. It seems utterly pointless that 24Mb of .debs are
needed merely so
that the maintainer scripts can be created and executed before removing all the
.debs on
a machine where file I/O can be slow and space for the extra 24Mb is not
necessarily
available. It gets worse when such machines need to have more than a basic
debootstrap
in the installation image, e.g. when the user needs to make a complete
installation image
that includes a full XFCE GUI without any .debs in the tarball.
If the new mode could simply detect that the architecture of the .deb does not
match the
architecture of the host system (i.e. the system outside the chroot), it could
conceivably
do everything except executing any code/scripts installed by the package. This
would also
require that the unpack mode would be closer to the extract support that is
able to write
files to a nominated directory - i.e. running dpkg from outside the chroot and
writing to
files in $PREFIX/var/lib/dpkg etc.
Requiring that a directory '$PREFIX' is specified and that the $PREFIX cannot
be '/' should
minimise problems of this mode being used in a "normal" filesystem. As such,
maybe an option
to dpkg -e would be more appropriate than a change to dpkg --unpack.
This is the test code (perl version) that adds to the functionality available
with dpkg -e:
(I don't consider it fully debugged, it is merely here to show the steps that
Emdebian
currently needs due to the lack of this functionality within dpkg itself. The
final code
will be executed from the top level of what will become the chroot, but never
from '/'
and will repeat over each archive in no particular order.)
#!/usr/bin/perl
# $dir will eventually hold a prefix that cannot be /
$dir="";
$cachedir="var/cache/apt/";
$libdir = "var/lib/apt/"; # lists
$etcdir = "etc/apt/"; # sources
$dpkgdir = "var/lib/dpkg/"; # state
&force_unpack;
exit 0;
sub force_unpack
{
my %unpack=();
$deb = "wget_1.11.4-2_armel.deb";
{
print "I: Extracting $deb...\n";
system ("ar -p \"./${cachedir}archives/$deb\" data.tar.gz |
zcat | tar -xf -");
my $ver=`dpkg -f ./${cachedir}archives/$deb Version`;
my $pkg=`dpkg -f ./${cachedir}archives/$deb Package`;
chomp ($ver);
chomp ($pkg);
print " -> Unpacking control data...\n";
mkdir ("tmp/listing");
system ("ar -p \"./${cachedir}archives/$deb\" data.tar.gz >
tmp/listing/data.tar.gz");
my $datatar = `tar -tzf tmp/listing/data.tar.gz`;
my @lines = split("\n", $datatar);
open (LIST, ">>${dpkgdir}info/${pkg}.list");
foreach my $l (@lines)
{
chomp ($l);
$l =~ s:^\.::;
$l =~ s:^/$:/\.:;
$l =~ s:/$::;
print LIST "$l\n";
}
close (LIST);
# this needs to use mktemp -d and only remove that dir.
system ("rm -rf tmp/*");
system ("dpkg -e ./${cachedir}archives/$deb tmp/");
opendir (MAINT, "tmp");
my @maint=grep(!m:\.\.?:, readdir (MAINT));
closedir (MAINT);
open (AVAIL, ">>${dpkgdir}available");
open (STATUS, ">>${dpkgdir}status");
foreach my $mscript (@maint)
{
rename "tmp/$mscript", "${dpkgdir}info/$pkg.$mscript";
if ( $mscript eq "control" )
{
open (MSCRIPT, "${dpkgdir}info/$pkg.$mscript");
my @scr=<MSCRIPT>;
close (MSCRIPT);
my @avail = grep(!/^$/, @scr);
print AVAIL @avail;
print STATUS @avail;
print AVAIL "\n";
print STATUS "Status: install ok unpacked\n";
unlink ("${dpkgdir}info/$mscript");
}
}
close (AVAIL);
if ( -f "${dpkgdir}info/$pkg.conffiles")
{
print STATUS "Conffiles:\n";
print "I: Processing $pkg.conffiles\n";
open (CONF, "${dpkgdir}info/$pkg.conffiles");
my @lines=<CONF>;
close (CONF);
foreach my $line (@lines)
{
chomp ($line);
$md5=`md5sum $line | cut -d" " -f1`;
print STATUS " $line $md5\n";
}
}
print STATUS "\n";
close (STATUS);
}
}
The shell version is in the unpack_debootstrap routine in emrootfslib, part of
the emdebian-rootfs
package in sid and squeeze and in empbuilderlib lenny.
http://packages.debian.org/squeeze/all/emdebian-rootfs/filelist
-- System Information:
Debian Release: squeeze/sid
APT prefers unstable
APT policy: (500, 'unstable')
Architecture: amd64 (x86_64)
Kernel: Linux 2.6.26-1-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8) (ignored: LC_ALL
set to en_GB.UTF-8)
Shell: /bin/sh linked to /bin/bash
Versions of packages dpkg depends on:
ii coreutils 7.1-2 The GNU core utilities
ii libc6 2.9-4 GNU C Library: Shared libraries
ii lzma 4.43-14 Compression method of 7z format in
dpkg recommends no packages.
Versions of packages dpkg suggests:
ii apt 0.7.20.2 Advanced front-end for dpkg
-- no debconf information
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]