diff options
author | Sam Thursfield <sam.thursfield@codethink.co.uk> | 2015-05-22 12:38:50 +0100 |
---|---|---|
committer | Sam Thursfield <sam.thursfield@codethink.co.uk> | 2015-05-22 12:38:50 +0100 |
commit | 8aec6d1a52b6386d2d9d664471a9a47cc62e9078 (patch) | |
tree | 0140d1f101df6154d3f1181c34b1b158fb5c5770 | |
parent | efe56eb94d868870ac67e2a4fe4521f82df86bda (diff) | |
download | sandboxlib-8aec6d1a52b6386d2d9d664471a9a47cc62e9078.tar.gz |
Add 'cwd' option to run_sandbox() functions.
Also, set it correctly when running an App Container image.
-rwxr-xr-x | run-sandbox | 8 | ||||
-rw-r--r-- | sandboxlib/chroot.py | 34 | ||||
-rw-r--r-- | sandboxlib/linux_user_chroot.py | 15 |
3 files changed, 46 insertions, 11 deletions
diff --git a/run-sandbox b/run-sandbox index 42f6085..9abcf81 100755 --- a/run-sandbox +++ b/run-sandbox @@ -79,7 +79,13 @@ def run(): command = manifest['app']['exec'] else: command = args.command - executor.run_sandbox(rootfs_path, command) + + if 'workingDirectory' in manifest['app']: + cwd = manifest['app']['workingDirectory'] + else: + cwd = None + + executor.run_sandbox(rootfs_path, command, cwd=cwd) else: # We should at minimum handle filesystem trees as well. raise RuntimeError( 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) |