+++ Joachim Breitner [2012-10-13 17:10 +0200]:
> Version: 0.63.2-1
> 
> Hi,
> 
> any news on this bug? I’d really like to have a way to modify the
> schroot session that sbuild starts before the build.

Here's a patch against current git/0.64.0 which does the following:
renames 'chroot-setup-commands' to 'chroot-user-setup-commands'
Adds 'chroot-system-setup-commands' which runs as soon as the chroot
is set-up, so before the 'update' phase and thus useul for adding
repos. That command is run as root.
The cleanup command is now run as root too. (I decided not to add a
matching 'system' cleanup coammnd as they'd both run at the same time
and this seemed kind of pointless: we have enough options already.

Adds some info to the sbuild man-page about which commands are run
outside the chroot, which inside, which as root, which as build user.

It also includes slightly half-arsed and not tested extra substitution
tokens for hostarch and chrootpath so that these could be passed to
commands. However I couldn't actually work out how to find the chroot
path so that bit is still 'fixme'. This part probably doesn't work, if
at all (My tests with %substitutions didn't seem to work at all even
with the existing code...)

This stuff solves my immediate problem but I'm not sure that it's the
best answer.

Is there actually a good reason for running the current
'chroot-setup-commands' ('chroot-user-setup-commands' above) and
'chroot-cleanup-commands' as the build user? Does anyone use this
functionality? Is it part of the sbuild security model?

Is it useful to have hooks both before update
(chroot-system-setup-commands) and after update/dependency install
(chroot-user-setup-commands)? I can only think of uses for
'chroot-system-setup-commands', but then I'm not a typical sbuild user.

Should we just keep it to 4 scripts setup/cleanup internal/external
all run as root and as early/late as possible?

And I've left '--setup-hook' as replaced by
--chroot-user-setup-commands, but maybe it would be better if it was
now replaced by --chroot-system-setup-commands given the complaint in
#608840 that it used to run as root?

Or, now that I've written the code, should we just have the five
commands as described on the man page:

The 'pre/post-build-' commands are run external to the chroot. The
'chroot-setup-' commands are run inside the chroot. They are all 
run as root except 'chroot-system-setup-' commands.

Here is a summary of the ordering, user, internal/external, and point
of running:
--pre-build-commands           root  ext  after chroot session setup
--chroot-system-setup-commands root  int  after chroot initialisation, before 
'update'
--chroot-user-setup-commands   user  int  after update and dependency-install, 
before build
--chroot-cleanup-commands      root  int  after build, before session is closed
--post-build-commands          root  ext  after session is shut down

(Input on those descriptions welcome)

Patch attached. 

Wookey
-- 
Principal hats:  Linaro, Emdebian, Wookware, Balloonboard, ARM
http://wookware.org/
commit 0dc43b424e3d37b50616145f021961eaa4b582e6
Author: Wookey <woo...@wookware.org>
Date:   Tue Jun 11 18:36:10 2013 +0100

    Add chroot-system-setup-command run earlier and as root
    Rename chroot-setup-command to chroot-user-setup-command
    Add base code for hostarch substitutions in commands

diff --git a/debian/changelog b/debian/changelog
index 2ac354a..02d7d9e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+sbuild (0.64.0-1wook1) unstable; urgency=low
+
+  * Add --chroot-system-setup-commands, run early and as root
+
+ -- Wookey <woo...@wookware.org>  Tue, 11 Jun 2013 18:39:03 +0100
+
 sbuild (0.64.0-1) unstable; urgency=low
 
   [ Thorsten Glaser ]
diff --git a/lib/Sbuild/Build.pm b/lib/Sbuild/Build.pm
index 0b2985c..eb50f9b 100644
--- a/lib/Sbuild/Build.pm
+++ b/lib/Sbuild/Build.pm
@@ -505,6 +505,15 @@ sub run_chroot_session_locked {
 	my $session = $self->get('Session');
 	my $resolver = $self->get('Dependency Resolver');
 
+	# Run specified chroot setup commands
+	$self->check_abort();
+	$self->run_external_commands("chroot-system-setup-commands",
+				     $self->get_conf('LOG_EXTERNAL_COMMAND_OUTPUT'),
+				     $self->get_conf('LOG_EXTERNAL_COMMAND_ERROR'));
+
+	$self->check_abort();
+
+
 	$self->check_abort();
 	$resolver->setup();
 
@@ -607,14 +616,14 @@ sub run_fetch_install_packages {
 	# Display message about chroot setup script option use being deprecated
 	if ($self->get_conf('CHROOT_SETUP_SCRIPT')) {
 	    my $msg = "setup-hook option is deprecated. It has been superceded by ";
-	    $msg .= "the chroot-setup-commands feature. setup-hook script will be ";
-	    $msg .= "run via chroot-setup-commands.\n";
+	    $msg .= "the chroot-user-setup-commands feature. setup-hook script will be ";
+	    $msg .= "run via chroot-user-setup-commands.\n";
 	    $self->log_warning($msg);
 	}
 
 	# Run specified chroot setup commands
 	$self->check_abort();
-	$self->run_external_commands("chroot-setup-commands",
+	$self->run_external_commands("chroot-user-setup-commands",
 				     $self->get_conf('LOG_EXTERNAL_COMMAND_OUTPUT'),
 				     $self->get_conf('LOG_EXTERNAL_COMMAND_ERROR'));
 
@@ -1000,6 +1009,7 @@ sub run_command {
     my $log_output = shift;
     my $log_error = shift;
     my $chroot = shift;
+    my $rootuser = shift;
 
     # Used to determine if we are to log from commands
     my ($out, $err, $defaults);
@@ -1022,7 +1032,7 @@ sub run_command {
 	    $err = $defaults->{'STREAMERR'} if ($log_error);
 	    $self->get('Session')->run_command(
 		{ COMMAND => \@{$command},
-		    USER => $self->get_conf('BUILD_USER'),
+		    USER => ($rootuser ? 'root' : $self->get_conf('BUILD_USER')),
 		    PRIORITY => 0,
 		    STREAMOUT => $out,
 		    STREAMERR => $err,
@@ -1053,13 +1063,18 @@ sub run_external_commands {
     return 1 if !(@commands);
 
     # Create appropriate log message and determine if the commands are to be
-    # run inside the chroot or not.
+    # run inside the chroot or not, and as root or not.
     my $chroot = 0;
+    my $rootuser = 1;  
     if ($stage eq "pre-build-commands") {
 	$self->log_subsection("Pre Build Commands");
-    } elsif ($stage eq "chroot-setup-commands") {
-	$self->log_subsection("Chroot Setup Commands");
+    } elsif ($stage eq "chroot-system-setup-commands") {
+	$self->log_subsection("Chroot System Setup Commands");
 	$chroot = 1;
+    } elsif ($stage eq "chroot-user-setup-commands") {
+	$self->log_subsection("Chroot User Setup Commands");
+	$chroot = 1;
+        $rootuser = 0;
     } elsif ($stage eq "chroot-cleanup-commands") {
 	$self->log_subsection("Chroot Cleanup Commands");
 	$chroot = 1;
@@ -1070,12 +1085,16 @@ sub run_external_commands {
     # Run each command, substituting the various percent escapes (like
     # %SBUILD_DSC) from the commands to run with the appropriate subsitutions.
     my $dsc = $self->get('DSC');
-    my $changes;
+    my ($changes, $chrootpath, $hostarch);
     $changes = $self->get('Changes File') if ($self->get('Changes File'));
+    $hostarch = $self->get('Host Arch') if ($self->get('Host Arch'));
+    $chrootpath = ""; # I can't see where to get the chroot path from. Fixme Roger!
     my %percent = (
 	"%" => "%",
 	"d" => $dsc, "SBUILD_DSC" => $dsc,
 	"c" => $changes, "SBUILD_CHANGES" => $changes,
+	"p" => $chrootpath,
+	"a" => $hostarch,
     );
     # Our escapes pattern, with longer escapes first, then sorted lexically.
     my $keyword_pat = join("|",
@@ -1093,7 +1112,7 @@ sub run_external_commands {
 	}
   my $command_str = join(" ", @{$command});
 	$self->log_subsubsection("$command_str");
-	$returnval = $self->run_command($command, $log_output, $log_error, $chroot);
+	$returnval = $self->run_command($command, $log_output, $log_error, $chroot, $rootuser);
 	$self->log("\n");
 	if (!$returnval) {
 	    $self->log_error("Command '$command_str' failed to run.\n");
diff --git a/lib/Sbuild/Conf.pm b/lib/Sbuild/Conf.pm
index 27b035c..3e6cc12 100644
--- a/lib/Sbuild/Conf.pm
+++ b/lib/Sbuild/Conf.pm
@@ -973,7 +973,8 @@ sub setup ($) {
 	    GROUP => 'Chroot options',
 	    DEFAULT => {
 		"pre-build-commands" => [],
-		"chroot-setup-commands" => [],
+		"chroot-system-setup-commands" => [],
+		"chroot-user-setup-commands" => [],
 		"chroot-cleanup-commands" => [],
 		"post-build-commands" => [],
 	    },
@@ -984,7 +985,11 @@ sub setup ($) {
         [\'foo\', \'arg1\', \'arg2\'],
         [\'bar\', \'arg1\', \'arg2\', \'arg3\'],
     ],
-    "chroot-setup-commands" => [
+    "chroot-system-setup-commands" => [
+        [\'foo\', \'arg1\', \'arg2\'],
+        [\'bar\', \'arg1\', \'arg2\', \'arg3\'],
+    ],
+    "chroot-user-setup-commands" => [
         [\'foo\', \'arg1\', \'arg2\'],
         [\'bar\', \'arg1\', \'arg2\', \'arg3\'],
     ],
@@ -1096,7 +1101,7 @@ if (\%individual_stalled_pkg_timeout) {
 END
 
     my $custom_setup = <<END;
-push(\@{\${\$conf->get('EXTERNAL_COMMANDS')}{"chroot-setup-commands"}},
+push(\@{\${\$conf->get('EXTERNAL_COMMANDS')}{"chroot-user-setup-commands"}},
 \$chroot_setup_script) if (\$chroot_setup_script);
 
     # Trigger log directory creation if needed
diff --git a/lib/Sbuild/Options.pm b/lib/Sbuild/Options.pm
index 4a232bf..b05237d 100644
--- a/lib/Sbuild/Options.pm
+++ b/lib/Sbuild/Options.pm
@@ -195,7 +195,7 @@ sub set_options {
 		       },
 		       "setup-hook=s" => sub {
 			my @command = split(/\s+/, $_[1]);
-			push(@{${$self->get_conf('EXTERNAL_COMMANDS')}{"chroot-setup-commands"}},
+			push(@{${$self->get_conf('EXTERNAL_COMMANDS')}{"chroot-user-setup-commands"}},
 			\@command);
 			   $self->set_conf('CHROOT_SETUP_SCRIPT', $_[1]);
 		       },
@@ -262,9 +262,14 @@ sub set_options {
 			   push(@{${$self->get_conf('EXTERNAL_COMMANDS')}{"pre-build-commands"}},
 				\@command);
 		       },
-			"chroot-setup-commands=s" => sub {
+			"chroot-system-setup-commands=s" => sub {
 			   my @command = split(/\s+/, $_[1]);
-			   push(@{${$self->get_conf('EXTERNAL_COMMANDS')}{"chroot-setup-commands"}},
+			   push(@{${$self->get_conf('EXTERNAL_COMMANDS')}{"chroot-system-setup-commands"}},
+				\@command);
+		       },
+			"chroot-user-setup-commands=s" => sub {
+			   my @command = split(/\s+/, $_[1]);
+			   push(@{${$self->get_conf('EXTERNAL_COMMANDS')}{"chroot-user-setup-commands"}},
 				\@command);
 		       },
 			"chroot-cleanup-commands=s" => sub {
diff --git a/man/sbuild.1.in b/man/sbuild.1.in
index a91a064..521465f 100644
--- a/man/sbuild.1.in
+++ b/man/sbuild.1.in
@@ -67,7 +67,8 @@ sbuild \- build debian packages from source
 .RB [ \-\-piuparts\-root\-arg=\fIoptions\fP ]
 .RB [ \-\-piuparts\-root\-args=\fIoptions\fP ]
 .RB [ \-\-pre\-build\-commands=\fIstring\fP ]
-.RB [ \-\-chroot\-setup\-commands=\fIstring\fP ]
+.RB [ \-\-chroot\-system\-setup\-commands=\fIstring\fP ]
+.RB [ \-\-chroot\-user\-setup\-commands=\fIstring\fP ]
 .RB [ \-\-chroot\-cleanup\-commands=\fIstring\fP ]
 .RB [ \-\-post\-build\-commands=\fIstring\fP ]
 .RB [ \-\-log\-external\-command\-output ]
@@ -412,6 +413,26 @@ through the use of the configuration files. In the configuration file, the list
 of commands to run are placed in a hash of arrays of arrays of strings
 corresponding to the commands to run.
 .PP
+The \fIpre/post-build-\fP commands are run external to the chroot. The
+\fIchroot\-setup\-\fP commands are run inside the chroot. They are all
+run as root except \fIchroot-system-setup-\fP commands, which is run as
+the current sbuild user.
+.PP
+Here is a summary of the ordering, user, internal/external, and point
+of running:
+.nf
+.br
+\f[CB]\-\-pre\-build\-commands            root  ext  After chroot session setup\fP
+.br
+\f[CB]\-\-chroot\-system\-setup\-commands  root  int  After chroot initialisation, before 'update'\fP
+.br
+\f[CB]\-\-chroot\-user\-setup\-commands    user  int  After update and dependency-install, before build\fP
+.br
+\f[CB]\-\-chroot\-cleanup\-commands       root  int  After build, before session is closed\fP
+.br
+\f[CB]\-\-post\-build\-commands           root  ext  After session is shut down\fP
+.fi
+.PP
 Here's an example of how to edit the configuration files to run "foo" and "bar"
 with arguments before a build starts.
 .PP

Reply via email to