summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Thursfield <sam.thursfield@codethink.co.uk>2015-05-28 11:27:54 +0000
committerSam Thursfield <sam.thursfield@codethink.co.uk>2015-05-28 14:04:13 +0000
commit886bdedc8ccf1466aac706b531c861ab1ea207b7 (patch)
treed865ac26a07518e60faf8858d88876c40f4eb109
parent4d0ecf53471755d376405bcdee657435d3f31cdf (diff)
downloadsandboxlib-886bdedc8ccf1466aac706b531c861ab1ea207b7.tar.gz
Add sandbox_module_for_platform() method
This decides what is the best module to use on the current platform.
-rw-r--r--sandboxlib/__init__.py67
1 files changed, 67 insertions, 0 deletions
diff --git a/sandboxlib/__init__.py b/sandboxlib/__init__.py
index fc1c3cf..3aeaf1c 100644
--- a/sandboxlib/__init__.py
+++ b/sandboxlib/__init__.py
@@ -22,7 +22,11 @@ docstrings that describe the different parameters.
'''
+import logging
+import platform
+import shutil
import subprocess
+import sys
def maximum_possible_isolation():
@@ -87,6 +91,69 @@ def run_sandbox(rootfs_path, command, cwd=None, extra_env=None,
values as well.
'''
+ raise NotImplementedError()
+
+
+def Popen(command, stderr=None, stdout=None, **sandbox_config):
+ '''Start a subprocess in a sandbox and return straight away.
+
+ This function aims to function like subprocess.Popen(), but with the
+ subprocess running inside a sandbox. It returns a subprocess.Popen
+ instance as soon as 'command' starts executing.
+
+ The 'stderr' and 'stdout' parameters accept None, a file-like object, a
+ file descriptor (integer), or subprocess.PIPE. The only difference from
+ the subprocess.Popen() function is that 'None' means 'ignore all output'
+ rather than 'inherit parent's stdout': if you want to forward output from
+ the subprocess to stdout, you must pass `stdout=sys.stdout`.
+
+ The sandbox_config arguments are the same as the run_command() function. In
+ most cases you should use run_command() instead of this, but there are
+ certain cases where Popen() could be useful. The run_command() function
+ buffers all data from stdout and stderr of the subprocess in memory, which
+ is impractical if there is a huge amount of data.
+
+ '''
+ raise NotImplementedError()
+
+
+def find_program(program_name):
+ # Python 3.3 and newer provide a 'find program in PATH' function. Otherwise
+ # we fall back to the `which` program.
+ if sys.version_info.major >= 3 and sys.version_info.minor >= 3:
+ program_path = shutil.which(program_name)
+ else:
+ try:
+ argv = ['which', program_name]
+ program_path = subprocess.check_output(argv).strip()
+ except subprocess.CalledProcessError as e:
+ logging.debug("Error searching for %s: %s", program_name, e)
+ program_path = None
+ return program_path
+
+
+def sandbox_module_for_platform():
+ '''Returns an execution module that will work on the current platform.'''
+
+ log = logging.getLogger("sandboxlib")
+
+ backend = None
+
+ if platform.uname() == 'Linux':
+ log.info("Linux detected, looking for 'linux-user-chroot'.")
+ linux_user_chroot_program = find_program('linux-user-chroot')
+ if linux_user_chroot_program is not None:
+ log.info("Found %s, choosing 'linux_user_chroot' module.",
+ linux_user_chroot_program)
+ backend = sandboxlib.linux_user_chroot
+ else:
+ log.debug("Did not find 'linux-user-chroot' program in PATH.")
+
+ if backend is None:
+ log.info("Choosing 'chroot' sandbox module.")
+ backend = sandboxlib.chroot
+
+ return backend
BASE_ENVIRONMENT = {