Package: sbuild
Version: 0.73.0-4
Severity: wishlist
The attached patch is a proof of concept for a docker chroot backend
for sbuild. It contains some hardcoded crap in the setup phase, but
that's about it (docker images generally have no build-essential, so
that needs to be installed; not sure about user, group, and sbuild
dir that seems weird).
-- System Information:
Debian Release: buster/sid
APT prefers unstable
APT policy: (900, 'unstable'), (900, 'testing'), (500, 'unstable-debug'),
(500, 'buildd-unstable'), (100, 'experimental'), (1, 'experimental-debug')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
Kernel: Linux 4.11.0-1-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_IE.UTF-8, LC_CTYPE=en_IE.UTF-8 (charmap=UTF-8),
LANGUAGE=en_IE.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
Versions of packages sbuild depends on:
ii adduser 3.115
ii libsbuild-perl 0.73.0-4
ii perl 5.24.1-5
Versions of packages sbuild recommends:
pn autopkgtest <none>
ii debootstrap 1.0.90
ii schroot 1.6.10-4
Versions of packages sbuild suggests:
ii deborphan 1.7.28.8-0.3+b1
ii kmod 24-1
ii wget 1.19.1-4
-- Configuration Files:
/etc/sbuild/sbuild.conf changed [not included]
-- no debconf information
--
Debian Developer - deb.li/jak | jak-linux.org - free software dev
| Ubuntu Core Developer |
When replying, only quote what is necessary, and write each reply
directly below the part(s) it pertains to ('inline'). Thank you.
diff --git a/Sbuild/Build.pm b/Sbuild.b/Build.pm
index b8a4b40..26b124b 100644
--- a/Sbuild/Build.pm
+++ b/Sbuild.b/Build.pm
@@ -52,6 +52,7 @@ use Sbuild::Base;
use Sbuild::ChrootInfoSchroot;
use Sbuild::ChrootInfoSudo;
use Sbuild::ChrootInfoAutopkgtest;
+use Sbuild::ChrootInfoDocker;
use Sbuild::ChrootRoot;
use Sbuild::Sysconfig qw($version $release_date);
use Sbuild::Sysconfig;
@@ -419,6 +420,8 @@ sub run_chroot_session {
$chroot_info = Sbuild::ChrootInfoSchroot->new($self->get('Config'));
} elsif ($self->get_conf('CHROOT_MODE') eq 'autopkgtest') {
$chroot_info = Sbuild::ChrootInfoAutopkgtest->new($self->get('Config'));
+ } elsif ($self->get_conf('CHROOT_MODE') eq 'docker') {
+ $chroot_info = Sbuild::ChrootInfoDocker->new($self->get('Config'));
} else {
$chroot_info = Sbuild::ChrootInfoSudo->new($self->get('Config'));
}
diff --git a/Sbuild.b/ChrootDocker.pm b/Sbuild.b/ChrootDocker.pm
new file mode 100644
index 0000000..9889980
--- /dev/null
+++ b/Sbuild.b/ChrootDocker.pm
@@ -0,0 +1,157 @@
+#
+# Chroot.pm: chroot library for sbuild
+# Copyright (C) 2005 Ryan Murray <[email protected]>
+# Copyright (C) 2005-2008 Roger Leigh <[email protected]>
+# Copyright (C) 2008 Simon McVittie <[email protected]>
+# Copyright (C) 2017 Julian Andres Klode <[email protected]> (docker)
+#
+# 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::ChrootDocker;
+
+use strict;
+use warnings;
+
+use POSIX qw(setsid);
+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');
+
+ my $session=readpipe("docker create --rm $chroot sleep 999999999999");
+ chomp($session);
+ if ($?) {
+ print STDERR "Chroot setup failed\n";
+ return 0;
+ }
+ readpipe("docker start $session");
+ if ($?) {
+ print STDERR "Chroot setup failed\n";
+ return 0;
+ }
+ readpipe("docker exec -it $session mkdir /build /var/lib/sbuild");
+ if ($?) {
+ print STDERR "Chroot setup failed\n";
+ return 0;
+ }
+ readpipe("docker exec -it $session adduser --gecos \"\" --disabled-login jak");
+ if ($?) {
+ print STDERR "Chroot setup failed\n";
+ return 0;
+ }
+ readpipe("docker exec -it $session addgroup sbuild");
+ if ($?) {
+ print STDERR "Chroot setup failed\n";
+ return 0;
+ }
+ system("docker exec -it $session sed -i s#deb.debian.org#172.17.0.1:3142# /etc/apt/sources.list");
+ system("docker exec -it $session apt-get update");
+ system("docker exec -it $session apt-get -y install build-essential");
+
+ $self->set('Session ID', $session);
+ $self->set('Session Purged', 1);
+ $self->set('Location', '/');
+
+ return 0 if !$self->_setup_options();
+
+ return 1;
+}
+
+sub end_session {
+ my $self = shift;
+ my $session = $self->get('Session ID');
+ return if $session eq "";
+
+ readpipe("docker kill $session");
+ if ($?) {
+ print STDERR "Chroot setup failed\n";
+ return 0;
+ }
+
+ return 1;
+}
+
+sub get_command_internal {
+ my $self = shift;
+ my $options = shift;
+ my $session = $self->get('Session ID');
+
+ # 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');
+ }
+
+ my @cmdline = ("docker", "exec", "-i", $session);
+
+ if ($user ne "root") {
+ push @cmdline, "/sbin/runuser", '-u', $user, '--';
+ }
+
+ if (defined($dir)) {
+ my $shelldir = shellescape $dir;
+ push @cmdline, 'sh', '-c', "cd $shelldir && exec \"\$@\"", 'exec';
+ } else {
+ $dir = '/';
+ }
+
+ 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;
diff --git a/Sbuild.b/ChrootInfoDocker.pm b/Sbuild.b/ChrootInfoDocker.pm
new file mode 100644
index 0000000..8cbb40e
--- /dev/null
+++ b/Sbuild.b/ChrootInfoDocker.pm
@@ -0,0 +1,76 @@
+#
+# ChrootInfo.pm: chroot utility library for sbuild
+# Copyright © 2005-2009 Roger Leigh <[email protected]>
+#
+# 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::ChrootInfoDocker;
+
+use Sbuild::ChrootInfo;
+use Sbuild::ChrootDocker;
+
+use strict;
+use warnings;
+
+BEGIN {
+ use Exporter ();
+ our (@ISA, @EXPORT);
+
+ @ISA = qw(Exporter Sbuild::ChrootInfo);
+
+ @EXPORT = qw();
+}
+
+sub new {
+ my $class = shift;
+ my $conf = shift;
+
+ my $self = $class->SUPER::new($conf);
+ bless($self, $class);
+
+ return $self;
+}
+
+sub get_info {
+ my %tmp = ('Namespace' => '',
+ 'Name' => '',
+ 'Priority' => 0,
+ 'Location' => '',
+ 'Session Purged' => 0);
+ return \%tmp;
+}
+
+sub get_info_all {
+ my $self = shift;
+
+ my $chroots = {};
+
+ $self->set('Chroots', $chroots);
+}
+
+sub _create {
+ my $self = shift;
+ my $chroot_id = shift;
+
+ my $chroot = undef;
+
+ $chroot = Sbuild::ChrootDocker->new($self->get('Config'), $chroot_id);
+
+ return $chroot;
+}
+
+1;
diff --git a/Sbuild/Conf.pm b/Sbuild.b/Conf.pm
index b70f721..0de79e3 100644
--- a/Sbuild/Conf.pm
+++ b/Sbuild.b/Conf.pm
@@ -654,7 +654,7 @@ sub setup ($) {
die "Bad chroot mode \'" . $conf->get('CHROOT_MODE') . "\'"
if !isin($conf->get('CHROOT_MODE'),
- qw(schroot sudo autopkgtest));
+ qw(schroot sudo autopkgtest docker));
},
DEFAULT => 'schroot',
HELP => 'Mechanism to use for chroot virtualisation. Possible value are "schroot" (default), "sudo" and "autopkgtest".',
diff --git a/Sbuild/Utility.pm b/Sbuild.b/Utility.pm
index 6e367e6..65bf38f 100644
--- a/Sbuild/Utility.pm
+++ b/Sbuild.b/Utility.pm
@@ -21,6 +21,7 @@
# Import default modules into main
package main;
use Sbuild qw($devnull);
+use Sbuild::ChrootInfoDocker;
use Sbuild::ChrootInfoSchroot;
use Sbuild::ChrootInfoSudo;
use Sbuild::Sysconfig;
@@ -90,6 +91,8 @@ sub setup ($$$) {
$chroot_info = Sbuild::ChrootInfoSchroot->new($conf);
} elsif ($conf->get('CHROOT_MODE') eq 'autopkgtest') {
$chroot_info = Sbuild::ChrootInfoAutopkgtest->new($conf);
+ } elsif ($conf->get('CHROOT_MODE') eq 'docker') {
+ $chroot_info = Sbuild::ChrootInfoDocker->new($conf);
} else {
$chroot_info = Sbuild::ChrootInfoSudo->new($conf);
}