diff options
Diffstat (limited to 'sandboxlib/chroot.py')
-rw-r--r-- | sandboxlib/chroot.py | 34 |
1 files changed, 27 insertions, 7 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) |