Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/bin/rainbow-run
diff options
context:
space:
mode:
Diffstat (limited to 'bin/rainbow-run')
-rwxr-xr-xbin/rainbow-run142
1 files changed, 142 insertions, 0 deletions
diff --git a/bin/rainbow-run b/bin/rainbow-run
new file mode 100755
index 0000000..3ce2590
--- /dev/null
+++ b/bin/rainbow-run
@@ -0,0 +1,142 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import pwd
+import grp
+
+from stat import S_ISREG, ST_MODE
+from os.path import join, isdir
+from optparse import OptionParser
+from pprint import pformat
+
+from rainbow.inject import inject
+from rainbow.permissions import PermissionSet
+from rainbow.util import make_reporter, trace, unshare, CLONE_NEWNS, read_envdir
+
+sys.excepthook = trace
+
+def main():
+ parser = OptionParser(version='0.1')
+ parser.add_option('-v', '--verbose', default=0, action='count',
+ help='Verbosity. Repeat for more verbose output.')
+ parser.add_option('-q', '--quiet', default=False, action='store_true',
+ help='Quiet. Disable all output.')
+ parser.add_option('-s', '--spool', default=None,
+ help='Location of the rainbow spool.')
+ parser.add_option('-e', '--envdir', default=None,
+ help="Location of an envdir describing the desired environment.")
+ parser.add_option('-E', '--env', default=[], action='append',
+ help="Environment bindings to override.")
+ parser.add_option('-c', '--cwd', default=None,
+ help="Working directory.")
+ parser.add_option('-f', '--fd', default=[], action='append',
+ help="File descriptor number to leave open.")
+ parser.add_option('-i', '--id', default=[], action='append',
+ help="ID of shared-data group.")
+ parser.add_option('-o', '--option', default=[], action='append',
+ help="Options: video, audio, serial, constant-uid, xephyr, network.")
+ parser.add_option('-p', '--permissions', default=None,
+ help="Location of a permissions.info file.")
+ parser.add_option('-u', '--user', default=None,
+ help="Owning user.")
+ parser.add_option('-r', '--resume-user', default=None,
+ help="Resume <user>.")
+ parser.add_option('-a', '--assistant', default=None,
+ help="Task-specific assistant.")
+ parser.add_option('-G', '--group', default=[], action='append',
+ help="Extra groups.")
+ opts, args = parser.parse_args()
+ if len(args) == 0:
+ parser.print_help()
+ exit(1)
+
+ report = make_reporter(opts.verbose, opts.quiet, sys.stdout)
+
+ def check_spool(opts):
+ return opts.spool
+
+ def check_env(opts):
+ return read_envdir(opts.envdir, opts.env)
+
+ def check_argv(args):
+ return args
+
+ def check_cwd(opts):
+ return opts.cwd
+
+ def check_fds(opts):
+ return [int(s) for s in opts.fd]
+
+ def check_owner(opts):
+ p = pwd.getpwnam(opts.user)
+ return p.pw_uid, p.pw_gid
+
+ def check_groups(opts):
+ return [grp.getgrnam(g)[2] for g in opts.group]
+
+ def check_xephyr(opts):
+ return 'xephyr' in opts.option
+
+ def check_constant_uid(opts):
+ return 'constant-uid' in opts.option
+
+ def check_audio(opts):
+ return 'audio' in opts.option
+
+ def check_video(opts):
+ return 'video' in opts.option
+
+ def check_serial(opts):
+ return 'serial' in opts.option
+
+ def check_network(opts):
+ return 'network' in opts.option
+
+ def check_resume_user(opts):
+ uid = None
+ if opts.resume_user:
+ uid = pwd.getpwnam(opts.resume_user).pw_uid
+ assert 10000 <= uid and uid < 60000
+ return uid
+
+ def check_data_ids(opts):
+ return opts.id
+
+ def check_assistant(opts):
+ return opts.assistant
+
+ uid, gid = check_owner(opts)
+ spool = check_spool(opts)
+
+ # Use empty env? Use partial env? Fail unless perfect?
+ env = check_env(opts)
+ argv = check_argv(args)
+ cwd = check_cwd(opts)
+
+ safe_fds = check_fds(opts)
+
+ groups = check_groups(opts)
+ pset = PermissionSet(opts.permissions or [])
+
+ # Dirty hack -- pass 'constant-uid' and 'strace' in as permissions. <MS>
+ for perm in ('constant-uid', 'audio', 'video', 'serial', 'network'):
+ pset._permissions.setdefault(perm, locals()['check_'+perm.replace('-','_')](opts))
+
+ data_ids = check_data_ids(opts)
+ assistant = check_assistant(opts)
+ xephyr = check_xephyr(opts)
+
+ resume_uid = check_resume_user(opts)
+ if resume_uid: report(1, "resuming uid (%d)", resume_uid)
+
+ args = (report, spool, env, argv, cwd, pset, safe_fds, uid, gid, resume_uid, groups, data_ids, assistant, xephyr)
+ report(1, 'rainbow:\n%s', pformat(args))
+
+ unshare(CLONE_NEWNS)
+ return inject(*args)
+
+if __name__ == '__main__':
+ main()
+
+# vim : et sw=4 ts=4 sts=4 :