[tor-commits] [tor-browser-build/master] Bug 23631: Use rootless containers

gk at torproject.org gk at torproject.org
Thu Feb 25 15:09:40 UTC 2021


commit 90c077db1d398041c75e6e4ebc56fb80570eb027
Author: Nicolas Vigier <boklm at torproject.org>
Date:   Tue Jun 16 20:03:56 2020 +0200

    Bug 23631: Use rootless containers
---
 README                                             |  20 +-
 README.HACKING                                     |  23 ++
 projects/common/runc-config.json                   | 267 ---------------------
 projects/container-image/config                    |   4 +-
 projects/debootstrap-image/config                  |  80 ------
 .../{debootstrap-image => mmdebstrap-image}/build  |   0
 projects/mmdebstrap-image/config                   |  59 +++++
 .../mmdebstrap-image/mmdebstrap-no-user-ns.patch   |  30 +++
 projects/mmdebstrap/build                          |   8 +
 projects/mmdebstrap/config                         |   5 +
 rbm                                                |   2 +-
 rbm.conf                                           |  92 +++----
 12 files changed, 172 insertions(+), 418 deletions(-)

diff --git a/README b/README
index e37f20d..8ebccf6 100644
--- a/README
+++ b/README
@@ -4,12 +4,10 @@ Tor Browser Build
 Installing build dependencies
 -----------------------------
 
-To build Tor Browser, you need a Linux distribution that has support
-for runc (such as Debian Buster, Ubuntu 16.04, Fedora 30, etc ...).
-
-Your user account should have sudo access, which is required to be able
-to extract container file systems, start containers and copy files to and
-from containers.
+To build Tor Browser, you need a recent Linux distribution with support
+for user_namespaces(7) (such as Debian Buster, Ubuntu 16.04, Fedora 30,
+etc ...). You will need to install the uidmap package, providing the
+newuidmap and newgidmap commands.
 
 The sources of most components are downloaded using git, which needs to
 be installed.
@@ -40,12 +38,20 @@ If you are running Debian or Ubuntu, you can install them with:
                   libio-captureoutput-perl libjson-perl libpath-tiny-perl \
                   libstring-shellquote-perl libsort-versions-perl \
                   libdigest-sha-perl libdata-uuid-perl libdata-dump-perl \
-                  libfile-copy-recursive-perl libfile-slurp-perl git runc
+                  libfile-copy-recursive-perl libfile-slurp-perl git \
+                  uidmap
 
 The build system is based on rbm, which is included as a git submodule
 in the rbm/ directory. You can fetch the rbm git submodule by running
 'make submodule-update'.
 
+The build uses user_namespaces(7), which are disabled by default on Debian.
+To enable them you can use the following command as root:
+
+  # sysctl -w kernel.unprivileged_userns_clone=1
+
+You can enable them permanently by adding the setting to /etc/sysctl.d/
+
 
 Starting a build
 ----------------
diff --git a/README.HACKING b/README.HACKING
index 0d3eeb8..506502d 100644
--- a/README.HACKING
+++ b/README.HACKING
@@ -305,6 +305,29 @@ The path to the container should be printed on the screen in case you
 want to backup its rootfs to be able to look at it later.
 
 
+Manually removing old containers
+--------------------------------
+
+When a build finishes or when you exit a debugging shell, the old
+container should automatically be removed. In some cases however, for
+example your computer is rebooted in the middle of a build, some old
+container directories may be left in the tmp directory. Some of the
+files in the container directories are owned by subordinate user ids
+(see the subuid man page), which will prevent you from removing them
+with your normal user id. To remove them you can open a container
+shell (a new User namespace) using the following command:
+
+   $ ./rbm/container run -- /bin/bash
+
+From this shell you should be able to remove the old containers
+directories in the tmp directory.
+
+It is also possible to pass the rm command directly without opening a
+shell:
+
+   $ ./rbm/container run -- rm -Rf ./tmp/rbm-*
+
+
 Testing an rbm patch
 --------------------
 
diff --git a/projects/common/runc-config.json b/projects/common/runc-config.json
deleted file mode 100644
index b078b97..0000000
--- a/projects/common/runc-config.json
+++ /dev/null
@@ -1,267 +0,0 @@
-{
-	"ociVersion": "1.0.0[% IF !c("var_p/runc_spec100") %]-rc1[% END %]",
-	"platform": {
-		"os": "linux",
-		"arch": "amd64"
-	},
-	"process": {
-		"terminal": [% IF c("interactive") %]true[% ELSE %]false[% END %],
-		"user": {
-			"uid": 0,
-			"gid": 0
-		},
-		"args": [
-			"/rbm/run"
-		],
-		"env": [
-			"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
-			"TERM=xterm"
-		],
-		"cwd": "/",
-[% IF c("var_p/runc_spec100") -%]
-		"capabilities": {
-			"bounding": [
-				"CAP_AUDIT_WRITE",
-				"CAP_KILL",
-				"CAP_NET_BIND_SERVICE",
-				"CAP_SETGID",
-				"CAP_SETUID",
-				"CAP_MKNOD",
-				"CAP_SYS_CHROOT",
-[% IF c("var/container/CAP_SYS_ADMIN") -%]
-				"CAP_SYS_ADMIN",
-[% END -%]
-				"CAP_FSETID",
-				"CAP_FOWNER",
-				"CAP_DAC_OVERRIDE",
-				"CAP_CHOWN"
-			],
-			"effective": [
-				"CAP_AUDIT_WRITE",
-				"CAP_KILL",
-				"CAP_NET_BIND_SERVICE",
-				"CAP_SETGID",
-				"CAP_SETUID",
-				"CAP_MKNOD",
-				"CAP_SYS_CHROOT",
-[% IF c("var/container/CAP_SYS_ADMIN") -%]
-				"CAP_SYS_ADMIN",
-[% END -%]
-				"CAP_FSETID",
-				"CAP_FOWNER",
-				"CAP_DAC_OVERRIDE",
-				"CAP_CHOWN"
-			],
-			"inheritable": [
-				"CAP_AUDIT_WRITE",
-				"CAP_KILL",
-				"CAP_NET_BIND_SERVICE",
-				"CAP_SETGID",
-				"CAP_SETUID",
-				"CAP_MKNOD",
-				"CAP_SYS_CHROOT",
-[% IF c("var/container/CAP_SYS_ADMIN") -%]
-				"CAP_SYS_ADMIN",
-[% END -%]
-				"CAP_FSETID",
-				"CAP_FOWNER",
-				"CAP_DAC_OVERRIDE",
-				"CAP_CHOWN"
-			],
-			"permitted": [
-				"CAP_AUDIT_WRITE",
-				"CAP_KILL",
-				"CAP_NET_BIND_SERVICE",
-				"CAP_SETGID",
-				"CAP_SETUID",
-				"CAP_MKNOD",
-				"CAP_SYS_CHROOT",
-[% IF c("var/container/CAP_SYS_ADMIN") -%]
-				"CAP_SYS_ADMIN",
-[% END -%]
-				"CAP_FSETID",
-				"CAP_FOWNER",
-				"CAP_DAC_OVERRIDE",
-				"CAP_CHOWN"
-			],
-			"ambient": [
-				"CAP_AUDIT_WRITE",
-				"CAP_KILL",
-				"CAP_NET_BIND_SERVICE",
-				"CAP_SETGID",
-				"CAP_SETUID",
-				"CAP_MKNOD",
-				"CAP_SYS_CHROOT",
-[% IF c("var/container/CAP_SYS_ADMIN") -%]
-				"CAP_SYS_ADMIN",
-[% END -%]
-				"CAP_FSETID",
-				"CAP_FOWNER",
-				"CAP_DAC_OVERRIDE",
-				"CAP_CHOWN"
-			]
-		},
-[% ELSE -%]
-		"capabilities": [
-			"CAP_AUDIT_WRITE",
-			"CAP_KILL",
-			"CAP_NET_BIND_SERVICE",
-			"CAP_SETGID",
-			"CAP_SETUID",
-			"CAP_MKNOD",
-			"CAP_SYS_CHROOT",
-[% IF c("var/container/CAP_SYS_ADMIN") -%]
-			"CAP_SYS_ADMIN",
-[% END -%]
-			"CAP_FSETID",
-			"CAP_FOWNER",
-			"CAP_DAC_OVERRIDE",
-			"CAP_CHOWN"
-		],
-[% END -%]
-		"noNewPrivileges": true
-	},
-	"root": {
-		"path": "rootfs",
-		"readonly": false
-	},
-	"hostname": "runc",
-	"mounts": [
-		{
-			"destination": "/proc",
-			"type": "proc",
-			"source": "proc"
-		},
-		{
-			"type": "bind",
-			"source": "/etc/resolv.conf",
-			"destination": "/etc/resolv.conf",
-			"options": [
-				"rbind",
-				"ro"
-			]
-		},
-		{
-			"destination": "/dev",
-			"type": "tmpfs",
-			"source": "tmpfs",
-			"options": [
-				"nosuid",
-				"strictatime",
-				"mode=755",
-				"size=65536k"
-			]
-		},
-		{
-			"destination": "/dev/pts",
-			"type": "devpts",
-			"source": "devpts",
-			"options": [
-				"nosuid",
-				"noexec",
-				"newinstance",
-				"ptmxmode=0666",
-				"mode=0620",
-				"gid=5"
-			]
-		},
-		{
-			"destination": "/dev/shm",
-			"type": "tmpfs",
-			"source": "shm",
-			"options": [
-				"nosuid",
-				"noexec",
-				"nodev",
-				"mode=1777",
-				"size=65536k"
-			]
-		},
-		{
-			"destination": "/dev/mqueue",
-			"type": "mqueue",
-			"source": "mqueue",
-			"options": [
-				"nosuid",
-				"noexec",
-				"nodev"
-			]
-		},
-		{
-			"destination": "/sys",
-			"type": "sysfs",
-			"source": "sysfs",
-			"options": [
-				"nosuid",
-				"noexec",
-				"nodev",
-				"ro"
-			]
-		},
-		{
-			"destination": "/sys/fs/cgroup",
-			"type": "cgroup",
-			"source": "cgroup",
-			"options": [
-				"nosuid",
-				"noexec",
-				"nodev",
-				"relatime",
-				"ro"
-			]
-		}
-	],
-	"hooks": {},
-	"linux": {
-		"resources": {
-			"devices": [
-				{
-					"allow": false,
-					"access": "rwm"
-				}
-			]
-		},
-		"namespaces": [
-			{
-				"type": "pid"
-			},
-			{
-				"type": "ipc"
-			},
-			{
-				"type": "uts"
-			},
-[% IF c("var/container/disable_network/" _ c("exec_name")) -%]
-			{
-				"type": "network",
-				"path": "/var/run/netns/rbm-[% sha256(c("build_id", { error_if_undef => 1 })) %]"
-			},
-[% END -%]
-			{
-				"type": "mount"
-			}
-		],
-		"maskedPaths": [
-			"/proc/kcore",
-			"/proc/latency_stats",
-			"/proc/timer_stats",
-[% IF c("var_p/runc_spec100") -%]
-			"/proc/timer_list",
-			"/sys/firmware",
-[% END -%]
-			"/proc/sched_debug"
-		],
-		"readonlyPaths": [
-			"/proc/asound",
-			"/proc/bus",
-			"/proc/fs",
-			"/proc/irq",
-			"/proc/sys",
-			"/proc/sysrq-trigger"
-		]
-	},
-	"solaris": {
-		"cappedCPU": {},
-		"cappedMemory": {}
-	}
-}
diff --git a/projects/container-image/config b/projects/container-image/config
index 7520b8e..e0b8b13 100644
--- a/projects/container-image/config
+++ b/projects/container-image/config
@@ -70,9 +70,9 @@ remote_get: |
     SET dst = shell_quote(c('get_dst', { error_if_undef => 1 }));
   -%]
   mkdir -p "[% dst %]"
-  sudo tar -C "[% c("var/container/dir") %]/rootfs" -czf "[% dst %]/[% c("filename") %]" .
+  [% c("rbmdir") %]/container archive '[% c("var/container/dir") %]' "[% dst %]/[% c("filename") %]"
 
 input_files:
-  - project: debootstrap-image
+  - project: mmdebstrap-image
     target:
       - '[% c("var/container/suite") %]-[% c("var/container/arch") %]'
diff --git a/projects/debootstrap-image/config b/projects/debootstrap-image/config
deleted file mode 100644
index 5098e29..0000000
--- a/projects/debootstrap-image/config
+++ /dev/null
@@ -1,80 +0,0 @@
-# vim: filetype=yaml sw=2
-filename: 'container-image_[% c("var/container/suite") %]-[% c("var/container/arch") %]-[% c("version") %].tar.gz'
-version: 3
-pkg_type: build
-
-var:
-  ubuntu_version: 20.04.1
-
-  container:
-    use_container: 1
-    # We need CAP_SYS_ADMIN for debootstrap to work
-    CAP_SYS_ADMIN: 1
-
-pre: |
-  #!/bin/sh
-  set -e
-  export DEBIAN_FRONTEND=noninteractive
-  apt-get update -y -q
-  apt-get install -y -q debian-archive-keyring ubuntu-keyring debootstrap
-  debootstrap --arch=[% c("var/container/arch") %] [% c("var/container/debootstrap_opt") %] [% c("var/container/suite") %] base-image [% c("var/container/debootstrap_mirror") %]
-  [% IF c("var/apt_package_filename") || c("var/apt_utils_package_filename") || c("var/libapt_inst_package_filename") || c("var/libapt_pkg_package_filename") -%]
-    mkdir ./base-image/apt-update
-    mv [% c("var/apt_package_filename") %] [% c("var/apt_utils_package_filename") %] \
-       [% c("var/libapt_inst_package_filename") %] [% c("var/libapt_pkg_package_filename") %] \
-       ./base-image/apt-update
-    mount proc ./base-image/proc -t proc
-    mount sysfs ./base-image/sys -t sysfs
-    chroot ./base-image dpkg -i -R /apt-update
-    umount ./base-image/proc
-    umount ./base-image/sys
-  [% END -%]
-  [% IF c("var/minimal_apt_version") -%]
-    apt_version=$(dpkg --admindir=$(pwd)/base-image/var/lib/dpkg -s apt | grep '^Version: ' | cut -d ' ' -f 2)
-    echo "apt version: $apt_version"
-    dpkg --compare-versions "$apt_version" ge '[% c("var/minimal_apt_version") %]'
-  [% END -%]
-  tar -C ./base-image -czf [% dest_dir %]/[% c("filename") %] .
-
-targets:
-  jessie-amd64:
-    var:
-      minimal_apt_version: 1.0.9.8.7
-      # CVE-2020-27350
-      apt_packages_baseurl: https://deb.freexian.com/extended-lts/pool/main/a/apt
-      apt_package_filename: apt_1.0.9.8.7_amd64.deb
-      apt_package_sha256sum: 02d5c6240e3410234e91facd4279c1acdce1523b583e05fac7ad64bdc75db7c7
-      apt_utils_package_filename: apt-utils_1.0.9.8.7_amd64.deb
-      apt_utils_package_sha256sum: aa6f0cc7cf2e7cc6e5c56782019cd651d26b01d280aef4d25288587e198ff2d3
-      libapt_inst_package_filename: libapt-inst1.5_1.0.9.8.7_amd64.deb
-      libapt_inst_package_sha256sum: a85c99a64f3d6cdde5bf0849649c2d5f21c7513987854628659ea014bc3eb214
-      libapt_pkg_package_filename: libapt-pkg4.12_1.0.9.8.7_amd64.deb
-      libapt_pkg_package_sha256sum: 0db2410376516f3420594647afc72dc99b48a44877eae4e8c79444a8244e988f
-
-      container:
-        suite: jessie
-        arch: amd64
-
-  buster-amd64:
-    var:
-      minimal_apt_version: 1.8.2
-      container:
-        suite: buster
-        arch: amd64
-
-input_files:
-  - URL: 'https://cdimage.ubuntu.com/ubuntu-base/releases/[% c("var/ubuntu_version") %]/release/ubuntu-base-[% c("var/ubuntu_version") %]-base-amd64.tar.gz'
-    filename: 'container-image_ubuntu-base-[% c("var/ubuntu_version") %]-base-amd64.tar.gz'
-    sha256sum: 97f6cbcf41f39272c84e32b6f926ed5d6906c6e463a557025181f4aa191ad667
-  - URL: '[% c("var/apt_packages_baseurl") %]/[% c("var/apt_package_filename") %]'
-    sha256sum: '[% c("var/apt_package_sha256sum") %]'
-    enable: '[% c("var/apt_package_filename") %]'
-  - URL: '[% c("var/apt_packages_baseurl") %]/[% c("var/apt_utils_package_filename") %]'
-    sha256sum: '[% c("var/apt_utils_package_sha256sum") %]'
-    enable: '[% c("var/apt_utils_package_filename") %]'
-  - URL: '[% c("var/apt_packages_baseurl") %]/[% c("var/libapt_inst_package_filename") %]'
-    sha256sum: '[% c("var/libapt_inst_package_sha256sum") %]'
-    enable: '[% c("var/libapt_inst_package_filename") %]'
-  - URL: '[% c("var/apt_packages_baseurl") %]/[% c("var/libapt_pkg_package_filename") %]'
-    sha256sum: '[% c("var/libapt_pkg_package_sha256sum") %]'
-    enable: '[% c("var/libapt_pkg_package_filename") %]'
diff --git a/projects/debootstrap-image/build b/projects/mmdebstrap-image/build
similarity index 100%
rename from projects/debootstrap-image/build
rename to projects/mmdebstrap-image/build
diff --git a/projects/mmdebstrap-image/config b/projects/mmdebstrap-image/config
new file mode 100644
index 0000000..102053d
--- /dev/null
+++ b/projects/mmdebstrap-image/config
@@ -0,0 +1,59 @@
+# vim: filetype=yaml sw=2
+filename: 'container-image_[% c("var/container/suite") %]-[% c("var/container/arch") %]-[% c("version") %].tar.gz'
+version: 1
+pkg_type: build
+
+var:
+  ubuntu_version: 20.04.1
+
+  container:
+    use_container: 1
+
+pre: |
+  #!/bin/sh
+  set -e
+  rootdir=$(pwd)
+  export DEBIAN_FRONTEND=noninteractive
+  apt-get update -y -q
+  apt-get install -y -q debian-archive-keyring ubuntu-keyring mmdebstrap gnupg patch
+
+  export SOURCE_DATE_EPOCH='[% c("timestamp") %]'
+  tar -xf [% c('input_files_by_name/mmdebstrap') %]
+  # As a user namespace inside an other user namespace doesn't seem to work,
+  # we patch mmdebstrap to avoid creating a new user namespace
+  patch -d mmdebstrap -p1 < mmdebstrap-no-user-ns.patch
+  ./mmdebstrap/mmdebstrap --mode=unshare [% c("var/container/mmdebstrap_opt") %] [% c("var/container/suite") %] output.tar.gz [% c("var/container/debian_mirror") %]
+
+  [% IF c("var/minimal_apt_version") -%]
+    mkdir base-image
+    tar -C base-image -xf output.tar.gz ./var/lib/dpkg
+    apt_version=$(dpkg --admindir=$rootdir/base-image/var/lib/dpkg -s apt | grep '^Version: ' | cut -d ' ' -f 2)
+    echo "apt version: $apt_version"
+    dpkg --compare-versions "$apt_version" ge '[% c("var/minimal_apt_version") %]'
+  [% END -%]
+
+  mv output.tar.gz [% dest_dir %]/[% c("filename") %]
+
+targets:
+  jessie-amd64:
+    var:
+      minimal_apt_version: 1.0.9.8.6
+
+      container:
+        suite: jessie
+        arch: amd64
+
+  buster-amd64:
+    var:
+      minimal_apt_version: 1.8.2
+      container:
+        suite: buster
+        arch: amd64
+
+input_files:
+  - project: mmdebstrap
+    name: mmdebstrap
+  - URL: 'https://cdimage.ubuntu.com/ubuntu-base/releases/[% c("var/ubuntu_version") %]/release/ubuntu-base-[% c("var/ubuntu_version") %]-base-amd64.tar.gz'
+    filename: 'container-image_ubuntu-base-[% c("var/ubuntu_version") %]-base-amd64.tar.gz'
+    sha256sum: 97f6cbcf41f39272c84e32b6f926ed5d6906c6e463a557025181f4aa191ad667
+  - filename: mmdebstrap-no-user-ns.patch
diff --git a/projects/mmdebstrap-image/mmdebstrap-no-user-ns.patch b/projects/mmdebstrap-image/mmdebstrap-no-user-ns.patch
new file mode 100644
index 0000000..15c547e
--- /dev/null
+++ b/projects/mmdebstrap-image/mmdebstrap-no-user-ns.patch
@@ -0,0 +1,30 @@
+diff --git a/mmdebstrap b/mmdebstrap
+index 9b7d892..5d85a74 100755
+--- a/mmdebstrap
++++ b/mmdebstrap
+@@ -204,6 +204,7 @@ sub get_tar_compressor {
+ }
+ 
+ sub test_unshare {
++    return 1;
+     my $verbose = shift;
+     if ($EFFECTIVE_USER_ID == 0) {
+         my $msg = "cannot use unshare mode when executing as root";
+@@ -382,7 +383,7 @@ sub get_unshare_cmd {
+     my $idmap = shift;
+ 
+     my $unshare_flags
+-      = $CLONE_NEWUSER | $CLONE_NEWNS | $CLONE_NEWPID | $CLONE_NEWUTS
++      = $CLONE_NEWNS | $CLONE_NEWPID | $CLONE_NEWUTS
+       | $CLONE_NEWIPC;
+ 
+     if (0) {
+@@ -457,6 +458,8 @@ sub get_unshare_cmd {
+                     $gidmapcmd .= " $hostid $nsid $range";
+                 }
+             }
++	    $uidmapcmd = "";
++	    $gidmapcmd = "";
+             my $idmapcmd = '';
+             if ($uidmapcmd ne "") {
+                 0 == system "newuidmap $ppid $uidmapcmd"
diff --git a/projects/mmdebstrap/build b/projects/mmdebstrap/build
new file mode 100644
index 0000000..ac0f21b
--- /dev/null
+++ b/projects/mmdebstrap/build
@@ -0,0 +1,8 @@
+#!/bin/bash
+[% c("var/set_default_env") -%]
+tar xf [% project %]-[% c("version") %].tar.gz
+mv [% project %]-[% c("version") %] [% project %]
+[% c('tar', {
+        tar_src => [ project ],
+        tar_args => '-czf ' _ dest_dir _ '/' _ c('filename'),
+    }) %]
diff --git a/projects/mmdebstrap/config b/projects/mmdebstrap/config
new file mode 100644
index 0000000..8fbfc97
--- /dev/null
+++ b/projects/mmdebstrap/config
@@ -0,0 +1,5 @@
+# vim: filetype=yaml sw=2
+version: 655857e5259436755f34b908d07a6ebd4c8b0303
+git_url: http://gitlab.mister-muffin.de/josch/mmdebstrap.git
+git_hash: '[% c("version") %]'
+filename: '[% project %]-src-[% c("version") %]-[% c("var/build_id") %].tar.gz'
diff --git a/rbm b/rbm
index 15c8476..cfb4018 160000
--- a/rbm
+++ b/rbm
@@ -1 +1 @@
-Subproject commit 15c84760ebe3f2677d1212aa00ef6f7485446a69
+Subproject commit cfb4018d34400e43837e77754519b3c2761b7ae6
diff --git a/rbm.conf b/rbm.conf
index 14a55a6..ba13cc0 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -495,13 +495,13 @@ gpg_wrapper: |
         exec [% c('gpg_bin') %] [% c('gpg_args') %] --with-fingerprint [% gpg_kr %] "$@"
   fi
 
-remote_start: '[% IF c("var/container/use_container") && ! c("var/container/global_disable") %][% c("runc/remote_start") %][% END %]'
-remote_exec: '[% IF c("var/container/use_container") && ! c("var/container/global_disable") %][% c("runc/remote_exec") %][% END %]'
-remote_put: '[% IF c("var/container/use_container") && ! c("var/container/global_disable") %][% c("runc/remote_put") %][% END %]'
-remote_get: '[% IF c("var/container/use_container") && ! c("var/container/global_disable") %][% c("runc/remote_get") %][% END %]'
-remote_finish: '[% IF c("var/container/use_container") && ! c("var/container/global_disable") %][% c("runc/remote_finish") %][% END %]'
+remote_start: '[% IF c("var/container/use_container") && ! c("var/container/global_disable") %][% c("container/remote_start") %][% END %]'
+remote_exec: '[% IF c("var/container/use_container") && ! c("var/container/global_disable") %][% c("container/remote_exec") %][% END %]'
+remote_put: '[% IF c("var/container/use_container") && ! c("var/container/global_disable") %][% c("container/remote_put") %][% END %]'
+remote_get: '[% IF c("var/container/use_container") && ! c("var/container/global_disable") %][% c("container/remote_get") %][% END %]'
+remote_finish: '[% IF c("var/container/use_container") && ! c("var/container/global_disable") %][% c("container/remote_finish") %][% END %]'
 
-runc:
+container:
   remote_start: |
     #!/bin/sh
     set -e
@@ -511,11 +511,9 @@ runc:
       ls -l '[% c("remote_srcdir") %]' >&2
       exit 1
     fi
-    mkdir -p '[% c("var/container/dir") %]'/rootfs/rbm
-    sudo tar -C '[% c("var/container/dir") %]'/rootfs -xf $(ls -1 '[% c("remote_srcdir", { error_if_undef => 1 }) %]/container-image_'*)
-    [% SET user = c("var/container/user") -%]
-    [% c("remote_exec", { exec_as_root => 1, exec_cmd => 'id ' _ user
-        _ ' >/dev/null 2>&1 || adduser -m ' _ user _ ' || useradd -m ' _ user }) %]
+    [% c("rbmdir") %]/container extract '[% c("var/container/dir") %]' '[% c("remote_srcdir", { error_if_undef => 1 }) %]/container-image_'*
+    test -d '[% c("var/container/dir") %]'/home/rbm || \
+      [% c("rbmdir") %]/container run --chroot='[% c("var/container/dir") %]' -- /usr/sbin/useradd -m [% c("var/container/user") %]
 
   remote_exec: |
     #!/bin/sh
@@ -523,26 +521,27 @@ runc:
     [% IF c("interactive") -%]
       echo Container directory: [% shell_quote(c("var/container/dir")) %]
     [% END -%]
-    mkdir -p '[% c("var/container/dir", { error_if_undef => 1 }) %]'/rootfs/rbm
-    echo '#!/bin/sh' > '[% c("var/container/dir") %]'/rootfs/rbm/cmd
-    echo [% shell_quote(c('exec_cmd')) %] >> '[% c("var/container/dir") %]'/rootfs/rbm/cmd
-    echo '#!/bin/sh' > '[% c("var/container/dir") %]'/rootfs/rbm/run
-    [% IF c('exec_as_root'); SET user = 'root'; ELSE; SET user = c("var/container/user", { error_if_undef => 1 }); END; %]
-    echo 'su - [% user %] -c /rbm/cmd' >> '[% c("var/container/dir") %]'/rootfs/rbm/run
-    chmod +x '[% c("var/container/dir") %]'/rootfs/rbm/cmd
-    chmod +x '[% c("var/container/dir") %]'/rootfs/rbm/run
-    cat > '[% c("var/container/dir") %]'/config.json << EOF
-    [% INCLUDE 'runc-config.json' %]
-    EOF
-    [% IF c("var/container/disable_network/" _ c("exec_name")) -%]
-      sudo ip netns add 'rbm-[% sha256(c("build_id", { error_if_undef => 1 })) %]'
-      # make sure the lo interface is up (see bug 31293)
-      sudo ip netns exec 'rbm-[% sha256(c("build_id", { error_if_undef => 1 })) %]' ip link set lo up
-    [% END -%]
-    sudo runc [% IF c("var_p/runc100") %]run[% ELSE %]start[% END %] -b '[% c("var/container/dir") %]' rbm-[% sha256(c("build_id", { error_if_undef => 1 })) %] [% IF c("runc_hide_stderr") %]2>/dev/null[% END %]
+    mkdir -p '[% c("var/container/dir", { error_if_undef => 1 }) %]'/rbm
+    echo '#!/bin/sh' > '[% c("var/container/dir") %]'/rbm/cmd
+    echo [% shell_quote(c('exec_cmd')) %] >> '[% c("var/container/dir") %]'/rbm/cmd
+    echo '#!/bin/sh' > '[% c("var/container/dir") %]'/rbm/run
     [% IF c("var/container/disable_network/" _ c("exec_name")) -%]
-      sudo ip netns delete 'rbm-[% sha256(c("build_id", { error_if_undef => 1 })) %]'
+      # Some programs such as gradle need the lo interface to be up.
+      # See for example tor-browser#31293
+      echo 'ip link set lo up' >> '[% c("var/container/dir") %]'/rbm/run
     [% END -%]
+    [% IF c('exec_as_root'); SET user = 'root'; ELSE; SET user = c("var/container/user", { error_if_undef => 1 }); END; %]
+    echo 'su - [% user %] -c /rbm/cmd' >> '[% c("var/container/dir") %]'/rbm/run
+    chmod +x '[% c("var/container/dir") %]'/rbm/cmd
+    chmod +x '[% c("var/container/dir") %]'/rbm/run
+    [%
+       IF c("var/container/disable_network/" _ c("exec_name"));
+         SET disable_network = '--disable-network';
+       ELSE;
+         SET disable_network = '';
+       END;
+    -%]
+    [% c("rbmdir") %]/container run [% disable_network %] --chroot='[% c("var/container/dir") %]' -- /rbm/run
 
   remote_put: |
     #!/bin/sh
@@ -551,12 +550,7 @@ runc:
       SET src = shell_quote(c('put_src', { error_if_undef => 1 }));
       SET dst = shell_quote(c('put_dst', { error_if_undef => 1 }));
     -%]
-    sudo mkdir -p '[% c("var/container/dir") %]'/rootfs/[% dst %]
-    sudo cp -aP [% src %] '[% c("var/container/dir") %]'/rootfs/[% dst %]
-    # On Ubuntu, the /root/.profile file contains a `mesg n` line which is
-    # producing some `stdin: is not a tty` messages. To hide them, we hide
-    # stderr from this part by setting runc_hide_stderr.
-    [% c("remote_exec", { exec_as_root => 1, exec_cmd => 'chown -R ' _ c("var/container/user") _ ' ' _ dst, runc_hide_stderr => 1 }) %]
+    [% c("rbmdir") %]/container put '[% c("var/container/dir") %]' [% src %] [% dst %] [% c("var/container/user") %]
 
   remote_get: |
     #!/bin/sh
@@ -565,24 +559,12 @@ runc:
       SET src = shell_quote(c('get_src', { error_if_undef => 1 }));
       SET dst = shell_quote(c('get_dst', { error_if_undef => 1 }));
     -%]
-    mkdir -p [% dst %]
-    srcdir='[% c("var/container/dir", { error_if_undef => 1 }) %]'/rootfs/[% src %]
-    sudo chown -R $(whoami) "$srcdir"
-    if [ $(ls -1 "$srcdir"/* 2> /dev/null | wc -l) -gt 0 ]
-    then
-      for file in "$srcdir"/*
-      do
-        bname="$(basename "$file")"
-        test -e [% dst %]/"$bname" && rm -Rf [% dst %]/"$bname"
-        mv -f "$file" [% dst %]/
-      done
-    fi
+    [% c("rbmdir") %]/container get '[% c("var/container/dir") %]' [% src %] [% dst %]
 
   remote_finish: |
     #!/bin/sh
     set -e
-    sudo rm -Rf '[% c("var/container/dir", { error_if_undef => 1 }) %]'/rootfs '[% c("var/container/dir", { error_if_undef => 1 }) %]'/config.json
-    rmdir '[% c("var/container/dir") %]'
+    [% c("rbmdir") %]/container remove '[% c("var/container/dir") %]'
 
 ENV:
   TZ: UTC
@@ -592,18 +574,6 @@ ENV:
   use IO::CaptureOutput qw(capture_exec);
   (
     var_p => {
-      # runc100 is true if we are using runc >= 1.0.0
-      # we assume that any version that is not 0.1.1 is >= 1.0.0
-      runc100 => sub {
-        my ($out) = capture_exec('sudo', 'runc', '--version');
-        return !($out =~ m/^runc version 0.1.1/);
-      },
-      # runc_spec100 is true if runc spec is at least 1.0.0
-      # We will need to update this when there is a new spec version available
-      runc_spec100 => sub {
-        my ($out) = capture_exec('sudo', 'runc', '--version');
-        return $out =~ m/^.*spec: 1\.[0-9]+\.[0-9]+(?:-dev)?$/m;
-      },
       nightly_torbrowser_version => sub {
         state $version = '';
         return $version if $version;



More information about the tor-commits mailing list