-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathdocker-rundev
More file actions
executable file
·95 lines (75 loc) · 2.72 KB
/
docker-rundev
File metadata and controls
executable file
·95 lines (75 loc) · 2.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/python3
import argparse
from contextlib import contextmanager
from subprocess import call, check_call, SubprocessError
import re
import os
import sys
import tempfile
def die(fmt, *k):
sys.stderr.write("error: %s\n" % (fmt % k))
sys.exit(1)
def shellquote(cmd):
if isinstance(cmd, str):
return cmd if re.match(r"[a-zA-Z0-9_,.+=:/-]+\Z", cmd) else repr(cmd)
else:
assert all(isinstance(x, str) for x in cmd)
return " ".join(map(shellquote, cmd))
@contextmanager
def overlay(source):
assert ":" not in source
assert "=" not in source
with tempfile.TemporaryDirectory() as tmp:
diff = os.path.join(tmp, "diff")
mnt = os.path.join(tmp, "mnt")
os.mkdir(diff)
os.mkdir(mnt)
try:
check_call(["unionfs-fuse", "-o", "cow,allow_root", "%s=RW:%s=RO" % (diff, source), mnt])
yield mnt
finally:
call(["fusermount", "-u", mnt])
def run_docker(args, source):
cmd = ["docker", "run", "--rm",
"-w", "/source",
"-v", "/tmp",
"-v", "%s:/source" % source]
for name in "target", "cache":
path = getattr(args, name)
if path:
os.path.isdir(path) or os.makedirs(path)
cmd.extend(("-v", "%s:/%s:rw" % (os.path.realpath(path), name)))
if args.root:
cmd.extend(("-u", "0:0"))
else:
cmd.extend(("-u", "%d:%d" % (os.getuid(), os.getgid())))
for group in os.getgroups():
cmd.extend(("--group-add", str(group)))
if not os.path.isdir(args.source):
die("source must be a directory: %r", args.source)
cmd.extend(args.extra)
print(shellquote(cmd))
return call(cmd)
def main():
parser = argparse.ArgumentParser("docker-rundev",
usage="docker-rundev [ OPTIONS ] [ -- DOCKER_OPTIONS ] ...")
parser.add_argument("extra", metavar="...", nargs=argparse.REMAINDER,
help="arguments to be provided to 'docker run'")
parser.add_argument("-s", "--source", default=".",
help="host path of the source dir (mounted as /source with an overlay)")
parser.add_argument("-t", "--target",
help="host path of the target dir (mounted as /target)")
parser.add_argument("-c", "--cache",
help="host path of the cache dir (mounted as /cache)")
parser.add_argument("-r", "--root", action="store_true",
help="run container as root")
args = parser.parse_args()
if args.extra and args.extra[0] == "--":
args.extra.pop(0)
try:
with overlay(args.source) as source_mnt:
return run_docker(args, source_mnt)
except SubprocessError as e:
die("%s", e)
if __name__ == "__main__":
sys.exit(main())