-
Notifications
You must be signed in to change notification settings - Fork 4
/
run-sandbox
executable file
·108 lines (82 loc) · 3.27 KB
/
run-sandbox
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/usr/bin/python3
#
# Copyright (C) 2015 Codethink Limited
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
'''Commandline 'run things in a sandbox' tool.'''
import argparse
import logging
import sys
import sandboxlib
def info(message, *args):
# FIXME: disable by default, add --verbose flag
print(message % args)
logging.info(message % args)
def parse_args():
parser = argparse.ArgumentParser(description="Run something in a sandbox.")
parser.add_argument(
'sandbox', metavar='PATH', type=str,
help="path to sandbox (image file, or directory tree)")
parser.add_argument(
'command', metavar='COMMAND', type=str, nargs='?',
help="command to run in sandbox")
parser.add_argument(
'--cwd',
type=str, required=False,
help="current working directory for COMMAND")
parser.add_argument(
'--executor', '-e',
choices=['chroot', 'linux_user_chroot', 'linux-user-chroot', 'bubblewrap'],
type=str, default='chroot',
help="which sandboxing backend to use")
return parser.parse_args()
def run():
args = parse_args()
executor = sandboxlib.get_executor(args.executor)
if sandboxlib.load.appc.is_app_container_image(args.sandbox):
info("%s is an App Container image." % args.sandbox)
context = sandboxlib.load.appc.unpack_app_container_image(
args.sandbox)
with context as (rootfs_path, manifest):
if args.command is None:
command = manifest['app']['exec']
else:
command = args.command
cwd = None
if args.cwd is not None:
cwd = args.cwd
elif 'workingDirectory' in manifest['app']:
cwd = manifest['app']['workingDirectory']
env = sandboxlib.load.appc.BASE_ENVIRONMENT.copy()
if 'environment' in manifest['app']:
for item in manifest['app']['environment']:
env[item['name']] = item['value']
env['AC_APP_NAME'] = manifest['name']
sharing_config = executor.maximum_possible_isolation()
extra_mounts = [
(None, '/proc', 'proc', None)
]
exit, out, err = executor.run_sandbox(
rootfs_path, command, cwd=cwd, env=env,
extra_mounts=extra_mounts, **sharing_config)
# We'll take a punt on the output being valid UTF-8.
print(out.decode('utf-8'))
print(err.decode('utf-8'))
else:
# We should at minimum handle filesystem trees as well.
raise RuntimeError(
"Only App Container images are supported right now.")
try:
run()
except RuntimeError as e:
print("ERROR: %s" % e)