summaryrefslogtreecommitdiff
path: root/sandboxlib
diff options
context:
space:
mode:
authorSam Thursfield <sam.thursfield@codethink.co.uk>2015-05-22 12:38:50 +0100
committerSam Thursfield <sam.thursfield@codethink.co.uk>2015-05-22 12:38:50 +0100
commit8aec6d1a52b6386d2d9d664471a9a47cc62e9078 (patch)
tree0140d1f101df6154d3f1181c34b1b158fb5c5770 /sandboxlib
parentefe56eb94d868870ac67e2a4fe4521f82df86bda (diff)
downloadsandboxlib-8aec6d1a52b6386d2d9d664471a9a47cc62e9078.tar.gz
Add 'cwd' option to run_sandbox() functions.
Also, set it correctly when running an App Container image.
Diffstat (limited to 'sandboxlib')
-rw-r--r--sandboxlib/chroot.py34
-rw-r--r--sandboxlib/linux_user_chroot.py15
2 files changed, 39 insertions, 10 deletions
diff --git a/sandboxlib/chroot.py b/sandboxlib/chroot.py
index 3fe1857..157b9fe 100644
--- a/sandboxlib/chroot.py
+++ b/sandboxlib/chroot.py
@@ -13,21 +13,41 @@
# with this program. If not, see <http://www.gnu.org/licenses/>.
-'''Execute command in a sandbox, using 'chroot'.'''
+'''Execute command in a sandbox, using os.chroot().
+The code would be simpler if we just used the 'chroot' program, but it's not
+always practical to do that. First, it may not be installed. Second, we can't
+set the working directory of the program inside the chroot, unless we assume
+that the sandbox contains a shell and we do some hack like running
+`/bin/sh -c "cd foo && command"`. It's better to call the kernel directly.
+'''
+
+
+import os
import subprocess
+import sys
import sandboxlib
-def run_sandbox(rootfs_path, command, extra_env=None):
+def run_sandbox(rootfs_path, command, cwd=None, extra_env=None):
if type(command) == str:
command = [command]
- env = sandboxlib.BASE_ENVIRONMENT.copy()
- if extra_env is not None:
- env.update(extra_env)
+ env = sandboxlib.environment_vars(extra_env)
+
+ pid = os.fork()
+ if pid == 0:
+ # Child process. It's a bit messy that we create a child process and
+ # then a second child process, but it saves duplicating stuff from the
+ # 'subprocess' module.
+
+ # FIXME: you gotta be root for this one.
+ os.chroot(rootfs_path)
- # FIXME: you gotta be root for this one.
- subprocess.call(['chroot', rootfs_path] + command)
+ result = subprocess.call(command, cwd=cwd, env=env)
+ os._exit(result)
+ else:
+ # Parent process. Wait for child to exit.
+ os.waitpid(pid, 0)
diff --git a/sandboxlib/linux_user_chroot.py b/sandboxlib/linux_user_chroot.py
index 8957191..7af7608 100644
--- a/sandboxlib/linux_user_chroot.py
+++ b/sandboxlib/linux_user_chroot.py
@@ -21,10 +21,19 @@ import subprocess
import sandboxlib
-def run_sandbox(rootfs_path, command, extra_env=None):
+def run_sandbox(rootfs_path, command, cwd=None, extra_env=None):
if type(command) == str:
command = [command]
-
+
+ linux_user_chroot = 'linux-user-chroot'
+
+ linux_user_chroot_args = []
+
+ if cwd is not None:
+ linux_user_chroot_args.extend(['--chdir', cwd])
+
env = sandboxlib.environment_vars(extra_env)
- subprocess.call(['linux-user-chroot', rootfs_path] + command, env=env)
+ argv = (
+ [linux_user_chroot] + linux_user_chroot_args + [rootfs_path] + command)
+ subprocess.call(argv, env=env)