Skip to content

Instantly share code, notes, and snippets.

@wmanley
Created August 30, 2016 22:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wmanley/243cbcbe7c3cb938acc4cf5d689fde22 to your computer and use it in GitHub Desktop.
Save wmanley/243cbcbe7c3cb938acc4cf5d689fde22 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
import argparse
import errno
import json
import os
import shutil
import subprocess
import sys
import tempfile
import unshare
def main(argv):
parser = argparse.ArgumentParser()
parser.add_argument("--repo")
# Arguments to be forwarded onto ostree commit
parser.add_argument("-b", "--branch")
parser.add_argument("--orphan", action="store_true")
parser.add_argument("--with", nargs='*')
parser.add_argument("commit")
parser.add_argument("command", nargs="?", default="/bin/sh")
parser.add_argument("args", nargs=argparse.REMAINDER, default=[])
args = parser.parse_args(argv[1:])
if args.branch is None:
args.branch = args.commit
mkdir_p("%s/workdirs" % args.repo)
workdir = tempfile.mkdtemp(dir="%s/workdirs" % args.repo)
mkdir_p("%s/rootfs" % workdir)
def preexec_fn():
unshare.unshare(unshare.CLONE_NEWNS)
subprocess.check_call(['mount', '--make-rprivate', '/'])
subprocess.check_call(["rofiles-fuse", "checkout", "rootfs"])
proc = None
try:
subprocess.check_call([
'ostree', '--repo=%s' % args.repo, 'checkout',
'--require-hardlinks', args.commit, '%s/checkout' % workdir])
with open('%s/config.json' % workdir, 'w') as f:
json.dump(runc_config(
[args.command] + args.args), f)
proc = subprocess.Popen(
["runc", 'start', 'ostree-run'],
preexec_fn=preexec_fn, cwd=workdir)
exit_status = proc.wait()
if exit_status == 0:
commit_args = ["ostree", "--repo=%s" % args.repo, "commit",
"--link-checkout-speedup",
"--tree=dir=%s/checkout" % workdir]
if args.branch:
commit_args.append('--branch=%s' % args.branch)
if args.orphan:
commit_args.append('--orphan')
if args.branch is None and args.orphan is None:
commit_args.append('--branch=%s' % args.commit)
subprocess.check_call(commit_args)
except:
if proc:
proc.kill()
raise
finally:
shutil.rmtree(workdir, ignore_errors=True)
pass
return exit_status
def runc_config(args, mounts=()):
additional_mounts = []
for x in mounts:
additional_mounts.append({
"destination": "/tmp/ostree/%s" % os.path.basename(x),
"type": "bind",
"source": x
})
return {
"ociVersion": "1.0.0-rc1",
"platform": {
"os": "linux",
"arch": "amd64"
},
"process": {
"terminal": True,
"user": {
"uid": 0,
"gid": 0
},
"args": args,
"env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"TERM=xterm"
],
"cwd": "/",
"capabilities": [
"CAP_AUDIT_WRITE",
"CAP_KILL",
"CAP_NET_BIND_SERVICE"
],
"rlimits": [
{
"type": "RLIMIT_NOFILE",
"hard": 1024,
"soft": 1024
}
],
"noNewPrivileges": True
},
"root": {
"path": "rootfs",
"readonly": False
},
"hostname": "runc",
"mounts": [
{
"destination": "/proc",
"type": "proc",
"source": "proc"
},
{
"destination": "/dev",
"type": "tmpfs",
"source": "tmpfs",
"options": [
"nosuid",
"strictatime",
"mode=755",
"size=65536k"
]
},
{
"destination": "/dev/pts",
"type": "devpts",
"source": "devpts",
"options": [
"nosuid",
"noexec",
"newinstance",
"ptmxmode=0666",
"mode=0620",
"gid=5"
]
},
{
"destination": "/dev/shm",
"type": "tmpfs",
"source": "shm",
"options": [
"nosuid",
"noexec",
"nodev",
"mode=1777",
"size=65536k"
]
},
{
"destination": "/dev/mqueue",
"type": "mqueue",
"source": "mqueue",
"options": [
"nosuid",
"noexec",
"nodev"
]
},
{
"destination": "/sys",
"type": "sysfs",
"source": "sysfs",
"options": [
"nosuid",
"noexec",
"nodev",
"ro"
]
},
{
"destination": "/sys/fs/cgroup",
"type": "cgroup",
"source": "cgroup",
"options": [
"nosuid",
"noexec",
"nodev",
"relatime",
"ro"
]
}
] + additional_mounts,
"hooks": {},
"linux": {
"resources": {
"devices": [
{
"allow": False,
"access": "rwm"
}
]
},
"namespaces": [
{
"type": "pid"
},
{
"type": "network"
},
{
"type": "ipc"
},
{
"type": "uts"
},
{
"type": "mount"
}
],
"maskedPaths": [
"/proc/kcore",
"/proc/latency_stats",
"/proc/timer_stats",
"/proc/sched_debug"
],
"readonlyPaths": [
"/proc/asound",
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"solaris": {
"cappedCPU": {},
"cappedMemory": {}
}
}
def mkdir_p(dirname, mode=0777):
try:
os.makedirs(dirname, mode)
except OSError as e:
if e.errno != errno.EEXIST:
raise
if __name__ == '__main__':
sys.exit(main(sys.argv))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment