449
|
1 #!/usr/bin/env python |
|
2 |
|
3 import os.path |
|
4 import sys |
|
5 import shlex |
|
6 import traceback |
|
7 import time |
|
8 |
|
9 from optparse import OptionParser |
|
10 |
|
11 CONFIG_FILE = os.environ.get("JOBDAEMON_CFG", "jobdaemon.cfg") |
|
12 |
|
13 SLEEP = int(os.environ.get("JOBDAEMON_SLEEP", "60")) |
|
14 |
|
15 def fork(job): |
|
16 pid = os.fork() |
|
17 if pid: return pid |
|
18 os.execv(job[0], job) |
|
19 return -1 # never reached |
|
20 |
|
21 class Jobs(object): |
|
22 |
|
23 def __init__(self, filename): |
|
24 self.load_config(filename) |
|
25 |
|
26 def load_config(self, filename): |
|
27 print >> sys.stderr, "loading config file '%s'" % filename |
|
28 plan, jobs = [], [] |
|
29 f = open(filename, "r") |
|
30 try: |
|
31 while True: |
|
32 line = f.readline() |
|
33 if not line: break |
|
34 line = line.strip() |
|
35 if not line or line.startswith("#"): |
|
36 continue |
|
37 if line.startswith("BLOCKER:"): |
|
38 line = line[len("BLOCKER:"):].strip() |
|
39 plan.append((jobs, line)) |
|
40 jobs = [] |
|
41 continue |
|
42 jobs.append(shlex.split(line)) |
|
43 finally: |
|
44 f.close() |
|
45 |
|
46 if jobs: plan.append((jobs, None)) |
|
47 |
|
48 self.plan = plan |
|
49 |
|
50 def run_jobs(self, jobs): |
|
51 pids = [] |
|
52 for job in jobs: |
|
53 try: |
|
54 pids.append(fork(job)) |
|
55 except: |
|
56 traceback.print_exc() |
|
57 |
|
58 for pid in pids: |
|
59 try: |
|
60 os.waitpid(pid, 0) |
|
61 except: |
|
62 traceback.print_exc() |
|
63 |
|
64 def run(self): |
|
65 for jobs, blocker in self.plan: |
|
66 self.run_jobs(jobs) |
|
67 if blocker: |
|
68 try: |
|
69 os.system(blocker) |
|
70 except: |
|
71 traceback.print_exc() |
|
72 |
|
73 def main(): |
|
74 |
|
75 global config_changed |
|
76 |
|
77 parser = OptionParser() |
|
78 |
|
79 parser.add_option( |
|
80 "-c", "--config", dest="config", |
|
81 help="load configuration from file", |
|
82 metavar="FILE", default=CONFIG_FILE) |
|
83 |
|
84 parser.add_option( |
|
85 "-s", "--sleep", dest="sleep_time", |
|
86 help="sleep time between runs", |
|
87 type="int", |
|
88 metavar="TIME", default=SLEEP) |
|
89 |
|
90 (options, _) = parser.parse_args() |
|
91 |
|
92 if not os.path.isfile(options.config): |
|
93 print >> sys.stderr, "config file '%s' does not exists." |
|
94 sys.exit(1) |
|
95 |
|
96 modtime = os.stat(options.config).st_mtime |
|
97 |
|
98 jobs = Jobs(options.config) |
|
99 |
|
100 while True: |
|
101 if os.path.isfile(options.config): |
|
102 nmodtime = os.stat(options.config).st_mtime |
|
103 if nmodtime > modtime: |
|
104 modtime = nmodtime |
|
105 jobs = Jobs(options.config) |
|
106 jobs.run() |
|
107 time.sleep(options.sleep_time) |
|
108 |
|
109 if __name__ == '__main__': |
|
110 main() |