autoserv.py revision f7243e1e10d8157877a8c99b718f01d3a8cc43f2
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, signal 17 18# Create separate process group 19os.setpgrp() 20 21# Implement SIGTERM handler 22def handle_sigint(signum, frame): 23 signal.signal(signal.SIGTERM, signal.SIG_DFL) 24 os.killpg(os.getpgrp(), signal.SIGTERM) 25 26# Set signal handler 27signal.signal(signal.SIGTERM, handle_sigint) 28 29 30usage = """\ 31usage: autoserv 32 [-m machine,[machine,...]] # list of machines to pass to control file 33 [-M machines_file] # list of machines (from a file) 34 [-c] # control file is a client side control 35 [-r resultsdir] # specify results directory (default '.') 36 [-i] # reinstall machines before running the job 37 [-I] # reinstall machines after running the job 38 [-b] # reboot all specified machines after the job 39 [-l label] # label for the job (arbitrary string) 40 [-u user] # username for the job (email address) 41 [-v] # verify the machines only 42 [-R] # repair the machines 43 [-n] # no teeing the status to stdout/stderr 44 <control file> # name of the control file to run 45 [args ...] # args to pass through to the control file 46""" 47 48args = sys.argv[1:] 49parser = utils.AutoservOptionParser(args) 50 51# Get a useful value for running 'USER' 52realuser = os.environ.get('USER') 53if not realuser: 54 realuser = 'anonymous' 55 56machines = parser.parse_opts_param('-m', None, split = ',') 57machines_file = parser.parse_opts_param('-M', None) 58results = parser.parse_opts_param('-r', os.path.abspath('.')) 59results = os.path.abspath(results) 60label = parser.parse_opts_param('-l', '') 61user = parser.parse_opts_param('-u', realuser) 62client = parser.parse_opts('-c') 63reboot = parser.parse_opts('-b') 64install_before = parser.parse_opts('-i') 65install_after = parser.parse_opts('-I') 66verify = parser.parse_opts('-v') 67repair = parser.parse_opts('-R') 68no_tee = parser.parse_opts('-n') 69 70 71if len(parser.args) < 1 and not verify and not repair: 72 print usage 73 sys.exit(-1) 74 75if machines_file: 76 machines = [] 77 for m in open(machines_file, 'r').readlines(): 78 m = re.sub('#.*', '', m).strip() # remove comments, spaces 79 if m: 80 machines.append(m) 81 print "Read list of machines from file: %s" % machines_file 82 print ','.join(machines) 83 84if machines: 85 for machine in machines: 86 if not machine or re.search('\s', machine): 87 print "Invalid machine %s" % str(machine) 88 sys.exit(1) 89 machines = list(set(machines)) 90 machines.sort() 91 92# We have a control file unless it's just a verify/repair job 93if len(parser.args) > 0: 94 control = parser.args[0] 95else: 96 control = None 97 98job = server_job.server_job(control, parser.args[1:], results, label, 99 user, machines, client) 100debug_dir = os.path.join(results, 'debug') 101if no_tee: 102 job.stdout.redirect(os.path.join(debug_dir, 'autoserv.stdout')) 103 job.stderr.redirect(os.path.join(debug_dir, 'autoserv.stderr')) 104else: 105 job.stdout.tee_redirect(os.path.join(debug_dir, 'autoserv.stdout')) 106 job.stderr.tee_redirect(os.path.join(debug_dir, 'autoserv.stderr')) 107 108if repair: 109 job.repair() 110 sys.exit(0) 111elif verify: 112 job.verify() 113 sys.exit(0) 114 115try: 116 job.run(reboot, install_before, install_after) 117except: 118 job.aborted = True 119 traceback.print_exc() 120 121# if the job was aborted, return a non-zero error code 122if getattr(job, 'aborted', False): 123 sys.exit(1) 124