diff options
Diffstat (limited to 'lib/Sbuild/ChrootSchroot.pm')
-rw-r--r-- | lib/Sbuild/ChrootSchroot.pm | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/lib/Sbuild/ChrootSchroot.pm b/lib/Sbuild/ChrootSchroot.pm new file mode 100644 index 0000000..8c88284 --- /dev/null +++ b/lib/Sbuild/ChrootSchroot.pm @@ -0,0 +1,173 @@ +# +# Chroot.pm: chroot library for sbuild +# Copyright © 2005 Ryan Murray <rmurray@debian.org> +# Copyright © 2005-2008 Roger Leigh <rleigh@debian.org> +# Copyright © 2008 Simon McVittie <smcv@debian.org> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# <http://www.gnu.org/licenses/>. +# +####################################################################### + +package Sbuild::ChrootSchroot; + +use strict; +use warnings; + +use Sbuild qw(shellescape); + +BEGIN { + use Exporter (); + use Sbuild::Chroot; + our (@ISA, @EXPORT); + + @ISA = qw(Exporter Sbuild::Chroot); + + @EXPORT = qw(); +} + +sub new { + my $class = shift; + my $conf = shift; + my $chroot_id = shift; + + my $self = $class->SUPER::new($conf, $chroot_id); + bless($self, $class); + + return $self; +} + +sub begin_session { + my $self = shift; + my $chroot = $self->get('Chroot ID'); + + return 0 if !defined $chroot; + + # Don't use namespaces in compat mode. + if ($Sbuild::Sysconfig::compat_mode) { + $chroot =~ s/^[^:]+://msx; + } + + my $schroot_session=readpipe($self->get_conf('SCHROOT') . " -c $chroot --begin-session"); + chomp($schroot_session); + if ($?) { + print STDERR "Chroot setup failed\n"; + return 0; + } + + $self->set('Session ID', $schroot_session); + print STDERR "Setting up chroot $chroot (session id $schroot_session)\n" + if $self->get_conf('DEBUG'); + + my $info = $self->get('Chroots')->get_info($schroot_session); + if (defined($info) && + defined($info->{'Location'}) && -d $info->{'Location'}) { + $self->set('Priority', $info->{'Priority'}); + $self->set('Location', $info->{'Location'}); + $self->set('Session Purged', $info->{'Session Purged'}); + } else { + print STDERR $self->get('Chroot ID') . " chroot does not exist\n"; + return 0; + } + + return 0 if !$self->_setup_options(); + + return 1; +} + +sub end_session { + my $self = shift; + + return if $self->get('Session ID') eq ""; + + print STDERR "Cleaning up chroot (session id " . $self->get('Session ID') . ")\n" + if $self->get_conf('DEBUG'); + system($self->get_conf('SCHROOT'), '-c', $self->get('Session ID'), '--end-session'); + $self->set('Session ID', ""); + if ($?) { + print STDERR "Chroot cleanup failed\n"; + return 0; + } + + return 1; +} + +sub _get_exec_argv { + my $self = shift; + my $dir = shift; + my $user = shift; + + return ($self->get_conf('SCHROOT'), + '-d', $dir, + '-c', $self->get('Session ID'), + '--run-session', + @{$self->get_conf('SCHROOT_OPTIONS')}, + '-u', "$user", '-p', '--'); +} + +sub get_internal_exec_string { + my $self = shift; + + return if $self->get('Session ID') eq ""; + + return join " ", (map + { shellescape $_ } + $self->_get_exec_argv('/', 'root')); +} + +sub get_command_internal { + my $self = shift; + my $options = shift; + + return if $self->get('Session ID') eq ""; + + if (defined($options->{'DISABLE_NETWORK'}) && $options->{'DISABLE_NETWORK'}) { + print STDERR "Disabling the network for this command was requested but the schroot backend doesn't support this feature yet: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=802849\n" if $self->get_conf('DEBUG'); + } + + # Command to run. If I have a string, use it. Otherwise use the list-ref + my $command = $options->{'INTCOMMAND_STR'} // $options->{'INTCOMMAND'}; + + my $user = $options->{'USER'}; # User to run command under + my $dir; # Directory to use (optional) + $dir = $self->get('Defaults')->{'DIR'} if + (defined($self->get('Defaults')) && + defined($self->get('Defaults')->{'DIR'})); + $dir = $options->{'DIR'} if + defined($options->{'DIR'}) && $options->{'DIR'}; + + if (!defined $user || $user eq "") { + $user = $self->get_conf('USERNAME'); + } + + if (!defined($dir)) { + $dir = '/'; + } + + my @cmdline = $self->_get_exec_argv($dir, $user); + + if (ref $command) { + push @cmdline, @$command; + } else { + push @cmdline, ('/bin/sh', '-c', $command); + $command = [split(/\s+/, $command)]; + } + $options->{'USER'} = $user; + $options->{'COMMAND'} = $command; + $options->{'EXPCOMMAND'} = \@cmdline; + $options->{'CHDIR'} = undef; + $options->{'DIR'} = $dir; +} + +1; |