[debhelper-devel] [debhelper] 01/02: Add minimal R³ support for debhelper

Niels Thykier nthykier at moszumanska.debian.org
Sat Sep 16 20:18:01 UTC 2017


This is an automated email from the git hooks/post-receive script.

nthykier pushed a commit to branch support-rrr
in repository debhelper.

commit f1abfad7fbe3a5fa7fb4b837b1e05ce6c1eda50b
Author: Niels Thykier <niels at thykier.net>
Date:   Sat Sep 16 14:51:53 2017 +0000

    Add minimal R³ support for debhelper
    
    Signed-off-by: Niels Thykier <niels at thykier.net>
---
 debian/changelog               |  8 +++++
 dh_fixperms                    |  2 +-
 dh_installchangelogs           |  5 +--
 dh_installdocs                 |  2 +-
 dh_testroot                    | 13 +++++++-
 lib/Debian/Debhelper/Dh_Lib.pm | 70 +++++++++++++++++++++++++++++++-----------
 6 files changed, 77 insertions(+), 23 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 47258fa..6b298a8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -17,6 +17,14 @@ debhelper (10.9) UNRELEASED; urgency=medium
     (Closes: #626685)
   * dh_gencontrol: Ensure that dbgsym packages do not inherit the
     "Important" field.
+  * Dh_Lib.pm: Add support for R³ (Rules-Requires-Root field) to
+    enable package builds without requiring root (or only
+    selectively require root).
+  * dh_fixperms: Skip "chown" calls when R³ is set to anything but
+    "binary-targets".
+  * dh_isntallchangelogs: Ditto.
+  * dh_installdocs: Ditto.
+  * dh_testroot: Update check for root to support R³.
 
   [ Felipe Sateler ]
   * dh_systemd_enable: Refactor and add support for timer units.
diff --git a/dh_fixperms b/dh_fixperms
index 4a550b5..8816f9f 100755
--- a/dh_fixperms
+++ b/dh_fixperms
@@ -99,7 +99,7 @@ on_pkgs_in_parallel {
 
 		# General permissions fixing.
 		complex_doit("find $tmp ${find_exclude_options} -print0",
-					 "2>/dev/null | xargs -0r chown --no-dereference 0:0");
+					 "2>/dev/null | xargs -0r chown --no-dereference 0:0") if should_use_root();
 		find_and_reset_perm($tmp, 'go=rX,u+rw,a-s', '! -type l');
 	
 		# Fix up permissions in usr/share/doc, setting everything to not
diff --git a/dh_installchangelogs b/dh_installchangelogs
index 3c377a5..5ae9be3 100755
--- a/dh_installchangelogs
+++ b/dh_installchangelogs
@@ -120,8 +120,9 @@ sub install_binNMU_changelog {
 		close $output or error("Couldn't close $output_fn: $!");
 		utime $stat[8], $stat[9], $output_fn;
 
-		chown 0, 0, $output_fn, $output_fn_binary
-			or error "chown: $!";
+		if (should_use_root()) {
+			chown(0, 0, $output_fn, $output_fn_binary) or error("chown: $!");
+		}
 
 		umask $mask;
 
diff --git a/dh_installdocs b/dh_installdocs
index 8ffa4bf..6e7e556 100755
--- a/dh_installdocs
+++ b/dh_installdocs
@@ -305,7 +305,7 @@ foreach my $package (getpackages()) {
 				doit("cp", '--reflink=auto', "-a", $doc, $target_dir);
 			}
 		}
-		doit("chown","-R","0:0","$tmp/usr/share/doc");
+		doit("chown","-R","0:0","$tmp/usr/share/doc") if should_use_root();
 		doit("chmod","-R","u+rw,go=rX","$tmp/usr/share/doc");
 	}
 
diff --git a/dh_testroot b/dh_testroot
index ed324e8..ce1f16c 100755
--- a/dh_testroot
+++ b/dh_testroot
@@ -24,8 +24,19 @@ our $VERSION = DH_BUILTIN_VERSION;
 
 inhibit_log();
 
-if ($< != 0) {
+my $requirements = Debian::Debhelper::Dh_Lib::root_requirements();
+
+# By declaration; nothing requires root and this command must be a no-op in that case.
+exit 0 if $requirements eq 'none';
+# The builder /can/ choose to ignore the requirements and just call us as root.
+# If so, we do not bother checking the requirements any further.
+exit 0 if $< == 0;
+if ($requirements eq 'legacy-root') {
 	error("You must run this as root (or use fakeroot).");
+} else {
+	my $env = $ENV{'DPKG_GAIN_ROOT_CMD'};
+	error("Package needs targetted root but builder has not provided a gain-root command via \${DPKG_GAIN_ROOT_CMD}")
+		if not $env;
 }
 
 =head1 SEE ALSO
diff --git a/lib/Debian/Debhelper/Dh_Lib.pm b/lib/Debian/Debhelper/Dh_Lib.pm
index 80a6543..0371895 100644
--- a/lib/Debian/Debhelper/Dh_Lib.pm
+++ b/lib/Debian/Debhelper/Dh_Lib.pm
@@ -65,6 +65,7 @@ our (@EXPORT, %dh);
 	    &glob_expand_error_handler_silently_ignore DH_BUILTIN_VERSION
 	    &print_and_complex_doit &default_sourcedir &qx_cmd
 	    &compute_doc_main_package &is_so_or_exec_elf_file
+	    &should_use_root
 );
 
 # The Makefile changes this if debhelper is installed in a PREFIX.
@@ -497,6 +498,7 @@ sub rename_path {
 sub reset_perm_and_owner {
 	my ($mode, @paths) = @_;
 	my $_mode;
+	my $use_root = should_use_root();
 	# Dark goat blood to tell 0755 from "0755"
 	if (length( do { no warnings "numeric"; $mode & "" } ) ) {
 		# 0755, leave it alone.
@@ -507,12 +509,14 @@ sub reset_perm_and_owner {
 	}
 	if ($dh{VERBOSE}) {
 		verbose_print(sprintf('chmod %#o -- %s', $_mode, escape_shell(@paths)));
-		verbose_print(sprintf('chown 0:0 -- %s', escape_shell(@paths)));
+		verbose_print(sprintf('chown 0:0 -- %s', escape_shell(@paths))) if $use_root;
 	}
 	return if $dh{NO_ACT};
 	for my $path (@paths) {
 		chmod($_mode, $path) or error(sprintf('chmod(%#o, %s): %s', $mode, $path, $!));
-		chown(0, 0, $path) or error("chown(0, 0, $path): $!");
+		if ($use_root) {
+			chown(0, 0, $path) or error("chown(0, 0, $path): $!");
+		}
 	}
 }
 
@@ -1273,22 +1277,7 @@ sub is_cross_compiling {
 	}
 }
 
-# Returns source package name
-sub sourcepackage {
-	open (my $fd, '<', 'debian/control') ||
-	    error("cannot read debian/control: $!\n");
-	while (<$fd>) {
-		chomp;
-		s/\s+$//;
-		if (/^Source:\s*(.*)/i) {
-			close($fd);
-			return $1;
-		}
-	}
 
-	close($fd);
-	error("could not find Source: line in control file.");
-}
 
 # Returns a list of packages in the control file.
 # Pass "arch" or "indep" to specify arch-dependant (that will be built
@@ -1299,7 +1288,13 @@ sub sourcepackage {
 # As a side effect, populates %package_arches and %package_types
 # with the types of all packages (not only those returned).
 my (%package_types, %package_arches, %package_multiarches, %packages_by_type,
-    %package_sections);
+    %package_sections, $sourcepackage, %rrr);
+# Returns source package name
+sub sourcepackage {
+	getpackages() if not defined($sourcepackage);
+	return $sourcepackage;
+}
+
 sub getpackages {
 	my ($type) = @_;
 	error("getpackages: First argument must be one of \"arch\", \"indep\", or \"both\"")
@@ -1327,6 +1322,22 @@ sub getpackages {
 	};
 
 	$packages_by_type{$_} = [] for qw(both indep arch all-listed-in-control-file);
+	while (<$fd>) {
+		chomp;
+		s/\s+$//;
+		if (/^Source:\s*(.*)/i) {
+			$sourcepackage = $1;
+			next;
+		} elsif (/^Rules-Requires-Root:\s*(.*)/i) {
+			for my $keyword (split(' ', $1)) {
+				$rrr{$keyword} = 1;
+			}
+			next;
+		}
+		last if (!$_ or eof); # end of stanza.
+	}
+	error("could not find Source: line in control file.") if not defined($sourcepackage);
+	$rrr{'binary-targets'} = 1 if not %rrr;
 
 	while (<$fd>) {
 		chomp;
@@ -1399,6 +1410,29 @@ sub getpackages {
 	return @{$packages_by_type{$type}};
 }
 
+# Return true if we should use root.
+# - Takes an optional keyword; if passed, this will return true if the keyword is listed in R^3 (Rules-Requires-Root)
+# - If the optional keyword is omitted or not present in R^3 and R^3 is not 'binary-targets', then returns false
+# - Returns true otherwise (i.e. keyword is in R^3 or R^3 is 'binary-targets')
+sub should_use_root {
+	my ($keyword) = @_;
+	getpackages() if not %rrr;
+
+	return 0 if exists($rrr{'no'});
+	return 1 if exists($rrr{'binary-targets'});
+	return 0 if not defined($keyword);
+	return 1 if exists($rrr{$keyword});
+	return 0;
+}
+
+sub root_requirements {
+	getpackages() if not %rrr;
+
+	return 'none' if exists($rrr{'no'});
+	return 'legacy-root' if exists($rrr{'binary-targets'});
+	return 'targetted-promotion';
+}
+
 # Returns the arch a package will build for.
 #
 # Deprecated: please switch to the more descriptive

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debhelper/debhelper.git




More information about the debhelper-devel mailing list