-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Package: sbuild
Version: 0.62.6-1
Tags: patch

Hi

sbuild fails to install packages into the chroot using the apt resolver, if the building user has a uid or gid > 99999999. I guess the aptitude resolver will fail too.

Local sources
─────────────

sbuild_0.62.6-1~lhm1.dsc exists in .; copying to chroot

Check arch
──────────

Merged Build-Depends: build-essential, fakeroot
Filtered Build-Depends: build-essential, fakeroot
dpkg-deb: building package `sbuild-build-depends-core-dummy' in `/build/resolver-owjRNQ/apt_archive/sbuild-build-depends-core-dummy.deb'.
E: Corrupted archive
E: Errors apply to file '/«CHROOT»/build/resolver-owjRNQ/apt_archive/sbuild-build-depends-core-dummy.deb'
OK
Reading package lists...

This "E:"s are from 'apt-ftparchive generate' complaining about a "broken" deb file, because the include data.tar.gz and control.tar.gz contain "invalid" uid / gid fields, as GNU tar includes large uids / gids in "GNU 256-bit encoding".

- From a busybox git commit:

/*
 * GNU tar uses "base-256 encoding" for very large numbers (>8 billion).
 * Encoding is binary, with highest bit always set as a marker
 * and sign in next-highest bit:
 * 80 00 .. 00 - zero
 * bf ff .. ff - largest positive number
 * ff ff .. ff - minus 1
 * c0 00 .. 00 - smallest negative number
 *

The attached patch detects a broken 'apt-ftparchive generate' run, rebuilds the dummy package using FAKEROOT, and reruns apt-ftparchive on the fixed package.

Comments welcome,

Jan-Marek
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)

iEYEARECAAYFAk5qyM4ACgkQj6MK58wZA3dYtgCcCj+6chw8QI/59mIzDFFig2wA
+dMAoJvkbRSPrRAXuRASF6XouKKC5mc3
=nM5F
-----END PGP SIGNATURE-----
diff --git a/lib/Sbuild/ResolverBase.pm b/lib/Sbuild/ResolverBase.pm
index 4ed99f5..af2455a 100644
--- a/lib/Sbuild/ResolverBase.pm
+++ b/lib/Sbuild/ResolverBase.pm
@@ -500,6 +500,24 @@ sub get_dpkg_status {
     return \%result;
 }
 
+sub run_dpkg_deb_internal {
+    my $self = shift;
+    my $session = $self->get('Session');
+    
+    my @dpkg_deb_cmd = ('dpkg-deb', '--build',
+			$self->get('Dummy package directory'),
+			$self->get('Dummy package file'));
+
+    unshift(@dpkg_deb_cmd, $self->get_conf('FAKEROOT'))
+	if ($self->get('Try fakeroot'));
+
+    $session->run_command(
+	{ COMMAND => \@dpkg_deb_cmd,
+	  USER => $self->get_conf('BUILD_USER'),
+	  PRIORITY => 0});
+    return $?;
+}
+
 # Create an apt archive. Add to it if one exists.
 sub setup_apt_archive {
     my $self = shift;
@@ -573,6 +591,9 @@ sub setup_apt_archive {
     my $dummy_deb = $dummy_archive_dir . '/' . $dummy_pkg_name . '.deb';
     my $dummy_dsc = $dummy_archive_dir . '/' . $dummy_pkg_name . '.dsc';
 
+    $self->set('Dummy package directory', $session->strip_chroot_path($dummy_pkg_dir));
+    $self->set('Dummy package file', $session->strip_chroot_path($dummy_deb));
+
     if (!(mkdir($dummy_pkg_dir) && mkdir($dummy_pkg_dir . '/DEBIAN'))) {
 	$self->log_warning('Could not create build-depends dummy dir ' . $dummy_pkg_dir . '/DEBIAN: ' . $!);
         $self->cleanup_apt_archive();
@@ -694,11 +715,7 @@ EOF
     }
 
     #Now build the package:
-    $session->run_command(
-	{ COMMAND => ['dpkg-deb', '--build', $session->strip_chroot_path($dummy_pkg_dir), $session->strip_chroot_path($dummy_deb)],
-	  USER => $self->get_conf('BUILD_USER'),
-	  PRIORITY => 0});
-    if ($?) {
+    if ($self->run_dpkg_deb_internal()) {
 	$self->log("Dummy package creation failed\n");
         $self->cleanup_apt_archive();
 	return 0;
@@ -897,15 +914,34 @@ EOF
     delete $env->{'APT_CONFIG'};
 
     # Run apt-ftparchive to generate Packages and Sources files.
-    $host->run_command(
-        { COMMAND => ['apt-ftparchive', '-q=2', 'generate', $tmpfilename],
-          USER => $self->get_conf('USERNAME'),
-          PRIORITY => 0,
-          DIR => '/'});
-    if ($?) {
-        $env->{'APT_CONFIG'} = $apt_config_value;
-	unlink $tmpfilename;
-        return 0;
+    while (1) {
+	$host->run_command(
+	    { COMMAND => ['apt-ftparchive', '-q=2', 'generate', $tmpfilename],
+	      USER => $self->get_conf('USERNAME'),
+	      PRIORITY => 0,
+	      DIR => '/'});
+	if ($? || (-s "$dummy_archive_dir/Packages" == 0)) {
+
+	    # Generation failed, so try to use fakeroot as fallback.
+	    # Some apt-ftparchive fail on GNU tar "base-256 encoded" u/gids,
+	    # when building with u/gid > 99999999.
+	    if (! defined $self->get('Try fakeroot')) {
+		$self->log("Possibly broken apt-ftparchive detected - trying fakeroot workaround.\n");
+		$self->set('Try fakeroot', 1);
+		if ($self->run_dpkg_deb_internal()) {
+		    $self->log("Dummy package creation failed\n");
+		    $self->log("If you have a uid or gid > 99999999 install fakeroot in the chroot.\n");
+		    $self->cleanup_apt_archive();
+		    return 0;
+		}
+		next;
+	    }
+
+	    $env->{'APT_CONFIG'} = $apt_config_value;
+	    unlink $tmpfilename;
+	    return 0;
+	}
+	last;
     }
 
     # Get output for Release file

Reply via email to