#! python import cgi import cgitb import os import sys import re import datetime import pandokia.text_table STEUERMANN_DIR_HERE sys.path.insert(0, addpath) import steuermann.config import steuermann.run_all cgitb.enable() form = cgi.FieldStorage(keep_blank_values=1) cginame = os.getenv("SCRIPT_NAME") auth_users = ( 'sienkiew', 'cslocum' ) permission_modify=0 if 'REMOTE_USER' in os.environ : if os.environ["REMOTE_USER"] in auth_users : permission_modify = 1 elif 'USER' in os.environ : if os.environ["REMOTE_USER"] == os.environ['USER'] : permission_modify = 1 html_header='''Content-type: text/html %(title)s ''' html_trailer=''' ''' ########## def sqltime(arg) : if arg is None : return None if '.' in arg : x = arg.split('.') d = datetime.datetime.strptime(x[0],'%Y-%m-%d %H:%M:%S') d = d.replace(microsecond=int((x[1]+'000000')[0:6])) else : x = time.strptime(arg,'%Y-%m-%d %H:%M:%S') d = datetime.datetime(year=x[0], month=x[1], day=x[2], hour=x[3], minute=x[4], second=x[5] ) # not in 2.4: # d = datetime.datetime.strptime(arg,'%Y-%m-%d %H:%M:%S') return d ########## def normalize_run_name(db, name) : if name == 'daily_latest' : c = db.execute("SELECT max(run) FROM sm_runs WHERE run like 'daily_%'") run, = c.fetchone() return run return name # make sure the name provided is valid def validate_name(form): name = re.match('(.*)/(.*):(.*)/(.*)', form['name'].value) run = name.group(1) host = name.group(2) table = name.group(3) cmd = name.group(4) db = steuermann.config.open_db() c = db.cursor() c.execute("SELECT status, start_time, end_time, notes FROM sm_status WHERE run = ? AND host = ? AND tablename = ? AND cmd = ?",( run, host, table, cmd ) ) x = c.fetchone() if x is None : print "No such record in database",run,host,table,cmd sys.exit(0) return run, host, table, cmd, x ########## # if no action specified, show the list of runs # if 'action' in form : action = form['action'].value else : action = 'index' if action == 'index' : print html_header % { 'title' : 'Steuermann' } print "runs
"%cginame print "crons
"%cginame print html_trailer sys.exit(0) ########## # list the runs elif action == 'crons' : print html_header % { 'title' : 'Steuermann List' } db = steuermann.config.open_db() c = db.cursor() c.execute("SELECT host, name, decollision, start_time, end_time, duration, status FROM sm_crons ORDER BY start_time desc") tt = pandokia.text_table.text_table() tt.set_html_table_attributes("border=1") tt.define_column('host') tt.define_column('name') tt.define_column('start_time') tt.define_column('end_time') tt.define_column('duration') tt.define_column('status') if permission_modify : # tt.define_column('delete') pass link="%s?action=%s&host=%s&name=%s&decol=%s" for host, name, decollision, start_time, end_time, duration, status in c : row = tt.get_row_count() short_name = name.split('--')[0] tt.set_value(row, 'host', host ) tt.set_value(row, 'name', text=short_name, link=link%(cginame,'cronlog',host,name,decollision) ) tt.set_value(row, 'start_time', start_time) if end_time is None : end_time = '' if end_time.startswith(start_time[0:11]) : tt.set_value(row, 'end_time', end_time[11:]) else : tt.set_value(row, 'end_time', end_time) tt.set_value(row, 'duration', duration) tt.set_value(row, 'status', status) if permission_modify : # tt.set_value(row, 'delete', 'arf') pass print tt.get_html() print html_trailer sys.exit(0) elif action == 'runs' : print html_header % { 'title' : 'Steuermann List' } print 'sort: ' for x in ( 'name_asc', 'name_desc', 'time_asc', 'time_desc' ) : print "%s"%(cginame,x,x) print "

" db = steuermann.config.open_db() c = db.cursor() order='create_time DESC' if 'order' in form : x = form['order'].value if x == 'name_asc' : order = 'run ASC' elif x == 'name_desc' : order = 'run DESC' elif x == 'time_asc' : order ='create_time ASC' elif x == 'time_desc' : order ='create_time DESC' c.execute('SELECT run, create_time, errors FROM sm_runs ORDER BY %s'%order) print "" for run, create_time, errors in c : if errors is None : c2 = db.cursor() c2.execute("select count(*) from sm_status where run = ? and status > '0' and status < 'A'", (run,)) errors = c2.fetchone() errors = errors[0] # I was thinking of caching the computed value back into # the sm_runs table and then invalidating it any time we add # to the sm_status, but it is so fast that I don't need that # optimization right now. print "" print "" print ""%errors print "" print "" print "
" if run.startswith('daily_20'): print "%s"%(cginame, run, run) elif run.startswith('etc_hst_daily') or run.startswith('etc_jwst_daily'): print "%s"%(cginame, run, run) else: print "%s"%(cginame, run, run) print "%s" if permission_modify : print "delete"%(cginame, run) print "
" print html_trailer sys.exit(0) ########## # status means show the status of a particular run # elif action == 'delete' : if permission_modify : print 'content-type: text/plain\n' in_run = form['run'].value db = steuermann.config.open_db() in_run = normalize_run_name(db,in_run) c = db.cursor() c1 = db.cursor() print "RUN=",in_run c.execute("SELECT run FROM sm_runs WHERE run LIKE ?",(in_run,)) for run, in c : print "echo run ",run filename = '%s/run/%s'%(steuermann.config.logdir,run) print "rm -rf ",filename c.execute("DELETE FROM sm_runs WHERE run LIKE ?",(in_run,)) c.execute("DELETE FROM sm_status WHERE run LIKE ?",(in_run,)) db.commit() print "" print "Database record deleted, but not log files" sys.exit(0) ########## # elif action == 'status' : db = steuermann.config.open_db() import steuermann.report steuermann.report.cginame = cginame print html_header % { 'title' : 'Steuermann Status' } print '' run = form['run'].value run = normalize_run_name(db,run) print steuermann.report.report_html( db, run, info_callback=steuermann.report.info_callback_gui ) print html_trailer sys.exit(0) elif action == 'cronlog' : print 'content-type: text/plain' print '' host = form['host'].value name = form['name'].value decol = form['decol'].value db = steuermann.config.open_db() c = db.cursor() c.execute("SELECT host, name, decollision, start_time, end_time, status, logfile FROM sm_crons WHERE host = ? AND name = ? and decollision = ?", (host, name, decol) ) for host, name, decollision, start_time, end_time, status, logfile in c : print "----------" print "%s: %s\n"%(host,name) print "decol=%s"%decollision print start_time print end_time print "status=",status print "----------" f=open( steuermann.config.logdir + '/cron/' + logfile,"r") sys.stdout.write(f.read()) f.close() sys.exit(0) ########## # log means show the result of a particular node from a run # elif action == 'log' : print 'content-type: text/plain' print '' run, host, table, cmd, x = validate_name(form) status, start_time, end_time, notes = x print "%s %s:%s/%s"%(run, host, table, cmd) print "status: %s"%status print "" print "start: %s"%start_time print "end : %s"%end_time start_time = sqltime(start_time) end_time = sqltime(end_time) if isinstance(end_time,datetime.datetime) and isinstance(end_time,datetime.datetime) : try : print "dur : %s"%(end_time-start_time) except Exception : pass if not notes is None : print "notes:" for x in [ ' ' + x for x in notes.split('\n') ] : print x print "" loglist = [ steuermann.run_all.make_log_file_name( run, host, table, cmd), # compat mode until we delete the old files '%s/%s/%s:%s.%s.log'%(steuermann.config.logdir,run,host,table,cmd), # more compat mode '%s/run/%s/%s:%s.%s.log'%(steuermann.config.logdir,run,host,table,cmd), ] for filename in loglist : try : f=open(filename,'r') break except IOError: f = None if f : print "--------------------" while 1 : x = f.read(65536) if x == '' : break x = x.replace('\0','') sys.stdout.write(x) else : print "No log file found. tried " print loglist sys.exit(0) elif action == 'run_log': run, host, table, cmd, x = validate_name(form) print html_header %{'title': form['name'].value} host_logs = steuermann.config.host_logs run_logs = os.path.join(host_logs, form['name'].value) print run_logs print '

' tb = pandokia.text_table.text_table() for row, log in enumerate(sorted(os.listdir(run_logs))): size= os.stat(run_logs + '/' + log).st_size tb.set_value(row, 0, html= "%s" %(cginame, form['name'].value, log, log) ) tb.set_value(row,1, size) print tb.get_html() print html_trailer sys.exit(0) elif action == 'show_run_log': run, host, table, cmd, x = validate_name(form) log_name = form['log_name'].value host_logs = steuermann.config.host_logs log = os.path.join(host_logs, form['name'].value, log_name) print 'content-type: text/plain' print print log print '#'*len(log) print print if not os.path.exists(log): print 'ERROR - %s does not exist' %log else: file = open(log) print file.read() file.close() sys.exit(0) ########## # info means show information about the system # elif action == 'info' : print html_header % { 'title': 'Steuermann Info' } print 'db credentials: ',steuermann.config.db_creds,'
' print 'logdir: ',steuermann.config.logdir,'
' db = steuermann.config.open_db() cur = db.cursor() cur.execute("select count(*) from sm_status") l = cur.fetchone() print "database records: %s\n"%l[0],'
' cur.execute("select count(*) from sm_runs") l = cur.fetchone() print "runs: %s\n"%l[0],'
' print html_trailer sys.exit(0) ########## print html_header print '' print 'no recognized action?' print html_trailer