blob: 513f0a73004d81b0ed56d78d933cd462a8a450c4 [file] [log] [blame]
mblighdcc04992007-07-26 19:42:55 +00001#!/usr/bin/python -u
2# monitor_queue <client> <spool_directory> <resultsdir> [<conmux_server>]
3import os, time, sys
4from subprocess import *
5import tempfile
6
mbligh88d32562007-09-11 20:18:58 +00007if (len(sys.argv) < 3):
8 print "Usage: monitor_queue <spool_directory> <resultsdir> [<conmux_server>]"
mblighdcc04992007-07-26 19:42:55 +00009 sys.exit(1)
mbligh88d32562007-09-11 20:18:58 +000010(spooldir, resultsdir) = [os.path.abspath(p) for p in sys.argv[1:3]]
11
12queue_name = os.path.basename(spooldir)
13dotmachines = os.path.join(spooldir, '.machines')
14if os.path.exists(dotmachines):
15 machines = [l.strip() for l in open(dotmachines).readlines() if len(l.strip())]
16else:
17 print "No .machines file in %s, assuming queue name \
18 is a machine" % queue_name
19 machines = [queue_name]
20
mblighdcc04992007-07-26 19:42:55 +000021if len(sys.argv) == 5:
22 console = sys.argv[4]
23else:
24 console = None
25if not os.path.exists(spooldir):
26 print "spooldir %s does not exist" % spooldir
27 sys.exit(1)
28if not os.path.exists(resultsdir):
29 print "resultsdir %s does not exist" % resultsdir
30 sys.exit(1)
31
32
mbligh88d32562007-09-11 20:18:58 +000033##### Control file templates #####
34SERV_MULTI = """# monitor_queue generated autoserv file (SERV_MULTI template)
35hosts = [hosts.ConmuxSSHHost(hostname, server=%s)
36 for hostname in machines]
37
38at = autotest.Autotest()
39
40control_path = %s
41results = %s
42
43def install_run(host):
44 at.install(host)
45 host_results = os.path.join(results, host.hostname)
46 at.run(control_path, host_results, host)
47
48parallel([subcommand(install_run, [host]) for host in hosts])"""
49
50
51SERV_SINGLE = """# monitor_queue generated autoserv file (SERV_SINGLE template)
52host = hosts.ConmuxSSHHost(machines[0], server=%s)
53
54at = autotest.Autotest()
55
56control_path = %s
57results = %s
58
59at.install(host)
60at.run(control_path, results, host)"""
61
62##### End control file templates #####
63
mblighdcc04992007-07-26 19:42:55 +000064def pick_job(jobs):
65 """Pick the next job to run. Currently we just pick the oldest job
66 However, this would be the place to put prioritizations."""
67 if not jobs:
68 return None
69 return sorted(jobs, key=lambda x:os.stat(x).st_mtime, reverse=True)[0]
70
71
mbligh88d32562007-09-11 20:18:58 +000072def __create_autoserv_wrapper(template, control_path, results):
mblighdcc04992007-07-26 19:42:55 +000073 """Create an autoserv file that runs an autotest file at
mbligh88d32562007-09-11 20:18:58 +000074 control_path on clients and outputs the results in results."""
mblighdcc04992007-07-26 19:42:55 +000075 # Create an autoserv control file to run this autotest control file
76 tmpfd, tmpname = tempfile.mkstemp()
77 tmp = os.fdopen(tmpfd, 'w')
mbligh88d32562007-09-11 20:18:58 +000078
79 print >> tmp, template % tuple([repr(s) for s in (console,
80 control_path,
81 results)])
mblighdcc04992007-07-26 19:42:55 +000082 return tmpname
83
84
85def run_job(control):
86 """Runs a control file from the spooldir.
87 Args:
88 control: A path to a control file. It is assumed to be an
89 Autotest control file in which case it will automatically
90 be wrapped with autoserv control commands and run with
91 autoserv. If the file name ends with .srv the wrapping
92 procedure will be skipped and the autoserv file will be
93 run directly.
94
95 Return:
96 The return code from the autoserv process.
97 """
98 # Make sure all the output directories are all setup
99 results = os.path.join(resultsdir, control)
100 if os.path.exists(results):
101 print "Resultsdir %s already present, " % results,
102 results = "%s.%d" % (results, int(time.time()))
103 print "changing to %s" % results
104 os.mkdir(results)
105 debug = os.path.join(results, 'debug')
106 os.mkdir(debug)
107
108 # If this is an autoserv file then don't create the wrapper control
109 is_autoserv_ctl = control.endswith('.srv')
110 control_path = os.path.abspath(os.path.join(spooldir, control))
111 # Otherwise create a tmp autoserv file just to launch the AT ctl file
112 if not is_autoserv_ctl:
mbligh88d32562007-09-11 20:18:58 +0000113 if len(machines) > 1:
114 # Run *AT* file on *all* machines in queue in *parallel*
115 template = SERV_MULTI
116 else:
117 # Run *AT* on *one* machine
118 template = SERV_SINGLE
119 control_path = __create_autoserv_wrapper(template,
120 control_path,
121 results)
mblighdcc04992007-07-26 19:42:55 +0000122
123 # Now run the job
124 exedir = os.path.abspath(os.path.dirname(sys.argv[0]))
125 autoserv_exe = os.path.abspath(os.path.join(exedir,
126 '..',
127 'server',
128 'autoserv'))
mbligh88d32562007-09-11 20:18:58 +0000129 autoserv_cmd = ' '.join([autoserv_exe,
130 '-m',
131 ','.join(machines),
132 control_path])
133
134 print "Starting job: %s" % control
135 print autoserv_cmd
mblighdcc04992007-07-26 19:42:55 +0000136
137 autoserv_log = open(os.path.join(debug, 'server.log'), 'w');
138 p = Popen(autoserv_cmd, shell=True, stdout=autoserv_log, stderr=STDOUT)
139 (pid, ret) = os.waitpid(p.pid, 0)
140 autoserv_log.close()
141
142 # If this was a tempfile then clean it up
143 if not is_autoserv_ctl:
144 os.unlink(control_path)
145 print "Completed job: %s (%d) " % (control, ret)
146
147 return ret
148
149
150dir = os.path.abspath(os.path.dirname(sys.argv[0]))
151runjob = os.path.join(dir, 'runjob')
152os.chdir(spooldir)
153print "monitoring spool directory: " + spooldir
154while True:
155 jobs = [j for j in os.listdir(spooldir) if not j.startswith('.')]
156 next_job = pick_job(jobs)
157 if not next_job:
158 time.sleep(10)
159 continue
160 ret = run_job(next_job)
mblighdcc04992007-07-26 19:42:55 +0000161 os.remove(next_job)