autoserv revision 394ff51dcddaf845dd41b16335a164d55c4f365f
1#!/usr/bin/python -u
2#
3# Copyright 2007 Google Inc. Released under the GPL v2
4
5"""
6Run an control file through the server side engine
7"""
8
9__author__ = """\
10mbligh@google.com (Martin J. Bligh)
11"""
12
13from common.check_version import check_python_version
14check_python_version()
15
16import sys, os, re, server_job, hosts.site_host, utils, traceback
17
18usage = """\
19usage: autoserv
20	[-m machine,[machine,...]] # list of machines to pass to control file
21	[-M machines_file]         # list of machines (from a file)
22	[-c]                       # control file is a client side control
23	[-r resultsdir]            # specify results directory (default '.')
24	[-i]                       # reinstall machines before running the job
25	[-I]                       # reinstall machines after running the job
26	[-b]                       # reboot all specified machines after the job
27	[-l label]                 # label for the job (arbitrary string)
28	[-u user]                  # username for the job (email address)
29	[-v]                       # verify the machines only
30	[-R]                       # repair the machines
31	[-n]                       # no teeing the status to stdout/stderr
32	<control file>             # name of the control file to run
33	[args ...]                 # args to pass through to the control file
34"""
35
36args = sys.argv[1:]
37parser = utils.AutoservOptionParser(args)
38
39# Get a useful value for running 'USER'
40realuser = os.environ.get('USER')
41if not realuser:
42	realuser = 'anonymous'
43
44machines = parser.parse_opts_param('-m', None, split = ',')
45machines_file = parser.parse_opts_param('-M', None)
46results  = parser.parse_opts_param('-r', os.path.abspath('.'))
47results  = os.path.abspath(results)
48label    = parser.parse_opts_param('-l', '')
49user     = parser.parse_opts_param('-u', realuser)
50client   = parser.parse_opts('-c')
51reboot   = parser.parse_opts('-b')
52install_before = parser.parse_opts('-i')
53install_after  = parser.parse_opts('-I')
54verify   = parser.parse_opts('-v')
55repair   = parser.parse_opts('-R')
56no_tee   = parser.parse_opts('-n')
57
58if getattr(hosts.site_host, 'site_parse_options', None):
59	hosts.site_host.site_parse_options(parser)
60
61if len(parser.args) < 1 and not verify and not repair:
62	print usage
63	sys.exit(-1)
64
65if machines_file:
66	machines = []
67	for m in open(machines_file, 'r').readlines():
68		m = re.sub('#.*', '', m).strip()   # remove comments, spaces
69		if m:
70			machines.append(m)
71	print "Read list of machines from file: %s" % machines_file
72	print ','.join(machines)
73
74if machines:
75	for machine in machines:
76		if not machine or re.search('\s', machine):
77			print "Invalid machine %s" % str(machine)
78			sys.exit(1)
79	machines = list(set(machines))
80	machines.sort()
81
82# We have a control file unless it's just a verify/repair job
83if len(parser.args) > 0:
84	control = parser.args[0]
85else:
86	control = None
87
88job = server_job.server_job(control, parser.args[1:], results, label,
89							user, machines, client)
90debug_dir = os.path.join(results, 'debug')
91if no_tee:
92	job.stdout.redirect(os.path.join(debug_dir, 'autoserv.stdout'))
93	job.stderr.redirect(os.path.join(debug_dir, 'autoserv.stderr'))
94else:
95	job.stdout.tee_redirect(os.path.join(debug_dir, 'autoserv.stdout'))
96	job.stderr.tee_redirect(os.path.join(debug_dir, 'autoserv.stderr'))
97
98if repair:
99	job.repair()
100	sys.exit(0)
101elif verify:
102	job.verify()
103	sys.exit(0)
104
105try:
106	job.run(reboot, install_before, install_after)
107except:
108	job.aborted = True
109	traceback.print_exc()
110
111# if the job was aborted, return a non-zero error code
112if getattr(job, 'aborted', False):
113	sys.exit(1)
114