Update README for archival
[reddit.git] / scripts / wrap-job
blob80962f1a031b45b7578f9d536cf1a6fd584cba98
1 #!/usr/bin/python
2 """
3 Wrap a command, setuid/setgid, change directory to the reddit
4 code, and send output to syslog.
6 The following environment variables may be used to control
7 the environment the wrapped command runs in:
9 REDDIT_USER
11 The user to run the job as. Defaults to "reddit".
13 REDDIT_GROUP
15 The group to run the job as. Defaults to $REDDIT_USER.
17 REDDIT_ROOT
19 The root directory of the reddit package. It's where the makefile lives.
21 REDDIT_LOG_FACILITY
23 The syslog facility to write messages to.
24 """
26 import os
27 import sys
28 import grp
29 import pwd
30 import syslog
31 import subprocess
34 CONSUMER_PREFIX = "reddit-consumer-"
37 # drop permissions
38 user = os.environ.get("REDDIT_USER", "reddit")
39 group = os.environ.get("REDDIT_GROUP", user)
40 uid = pwd.getpwnam(user).pw_uid
41 gid = grp.getgrnam(group).gr_gid
42 os.setgroups([])
43 os.setgid(gid)
44 os.setuid(uid)
46 # change directory to the reddit code root
47 root = os.environ.get("REDDIT_ROOT", "/opt/reddit/lib/public/r2")
48 os.chdir(root)
50 # configure syslog
51 job_name = os.environ.get("UPSTART_JOB", "-".join(sys.argv[1:]))
52 if job_name.startswith(CONSUMER_PREFIX):
53 # consumers are a bit different from crons, while crons want an
54 # ident of reddit-job-JOBNAME, we want consumers to have an ident
55 # of CONSUMERNAME_INSTANCE
56 job_name = (job_name[len(CONSUMER_PREFIX):] +
57 "_" +
58 os.environ.get("UPSTART_INSTANCE", ""))
59 facility = getattr(syslog, "LOG_" + os.environ.get("REDDIT_LOG_FACILITY", "CRON"))
60 syslog.openlog(ident=job_name, facility=facility)
62 # run the wrapped command
63 child = subprocess.Popen(sys.argv[1:],
64 stdout=subprocess.PIPE,
65 stderr=subprocess.STDOUT,
66 bufsize=1)
68 # write out to syslog
69 while True:
70 line = child.stdout.readline()
72 if not line:
73 break
75 line = line.rstrip('\n')
76 syslog.syslog(syslog.LOG_NOTICE, line)
77 print line
79 # our success depends on our child's success
80 child.wait()
81 sys.exit(child.returncode)