summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--exec/chroot.py58
-rw-r--r--sandbox.py69
2 files changed, 127 insertions, 0 deletions
diff --git a/exec/chroot.py b/exec/chroot.py
new file mode 100644
index 0000000..d393d50
--- /dev/null
+++ b/exec/chroot.py
@@ -0,0 +1,58 @@
+# Run a sandbox in a chroot.
+
+
+import contextlib
+import json
+import os
+import shutil
+import subprocess
+import tarfile
+import tempfile
+
+
+@contextlib.contextmanager
+def unpack_app_container_image(image_file):
+ tempdir = tempfile.mkdtemp()
+ try:
+ # FIXME: you gotta be root, sorry.
+ with tarfile.open(image_file, 'r') as tf:
+ tf.extractall(path=tempdir)
+
+ manifest_path = os.path.join(tempdir, 'manifest')
+ rootfs_path = os.path.join(tempdir, 'rootfs')
+
+ with open(manifest_path, 'r') as f:
+ manifest_data = json.load(f)
+
+ yield rootfs_path, manifest_data
+ finally:
+ shutil.rmtree(tempdir)
+
+
+def _run_sandbox_real(rootfs_path, manifest, command=None):
+ # FIXME: you gotta be root.
+ print manifest
+ if command is None:
+ # Use the command from the image
+ command = manifest['app']['exec']
+ if type(command) == str:
+ command = [command]
+ subprocess.call(['chroot', rootfs_path] + command)
+
+
+def run_sandbox(app_container_image=None,
+ rootfs_path=None,
+ manifest=None,
+ command=None):
+ if app_container_image is not None:
+ assert rootfs_path is None and manifest is None, \
+ "You cannot specify a rootfs_path or manifest when running an " \
+ "App Container image."
+ with unpack_app_container_image(app_container_image) as (rootfs_path, manifest):
+ return _run_sandbox_real(rootfs_path, manifest, command=command)
+ else:
+ _run_sandbox_real(rootfs_path, manifest, command=command)
+
+
+run_sandbox(app_container_image='/home/shared/baserock/baserock-minimal.aci',
+ command=['/bin/sh', '-c', 'echo foo && exit 1'])
diff --git a/sandbox.py b/sandbox.py
new file mode 100644
index 0000000..85107ae
--- /dev/null
+++ b/sandbox.py
@@ -0,0 +1,69 @@
+# Make a sandbox for running a command.
+
+# Sandbox could be: a baserock chroot, for the time being.
+
+# Image layout: /rootfs, /manifest
+
+
+import json
+import os
+import shutil
+import subprocess
+import sys
+import tarfile
+import tempfile
+
+
+def appc_manifest_for_command(command):
+ '''Fake an appc manifest.'''
+ manifest = {
+ 'acKind': 'ImageManifest',
+ 'acVersion': '0.5.2',
+ 'name': 'temp/temp1',
+ 'labels': [],
+ 'app': {
+ 'exec': command,
+ 'user': 'root',
+ 'group': 'root',
+ 'workingDirectory': '/temp.build',
+ }
+ }
+ return json.dumps(manifest)
+
+def make_sandbox_for_command(command, source_tar, target,
+ actool='/home/shared/baserock/appc-spec/actool/actool'):
+ '''Fake an appc image.
+
+ This is a dumb idea, because you have to unpack a tar, create a tar, then
+ unpack it again to run it.
+
+ Better to have the executor take manifest and rootfs separately.
+
+ '''
+ tempdir = tempfile.mkdtemp()
+
+ try:
+ manifest_path = os.path.join(tempdir, 'manifest')
+ rootfs_path = os.path.join(tempdir, 'rootfs')
+
+ with open(manifest_path, 'w') as f:
+ f.write(appc_manifest_for_command(command))
+
+ os.mkdir(rootfs_path)
+ # FIXME: You've probably got to run this as root.
+ with tarfile.TarFile(source_tar, 'r') as tf:
+ tf.extractall(path=rootfs_path)
+
+ subprocess.check_call(
+ [actool, 'build', tempdir, target],
+ stdout=sys.stdout,
+ stderr=sys.stderr)
+ print 'Created %s' % target
+ finally:
+ shutil.rmtree(tempdir)
+
+
+make_sandbox_for_command(
+ command=['/bin/sh', '-c', '"echo foo && exit 1"'],
+ source_tar='/home/shared/baserock-chroot-src/definitions/baserock-minimal.tar',
+ target='/home/shared/baserock/baserock-minimal.aci')