diff options
Diffstat (limited to 'steuermann')
-rw-r--r-- | steuermann/hosts.ini | 7 | ||||
-rw-r--r-- | steuermann/nodes.py | 36 | ||||
-rw-r--r-- | steuermann/run.py | 26 | ||||
-rw-r--r-- | steuermann/run_all.py | 15 | ||||
-rw-r--r-- | steuermann/run_cron.py | 38 | ||||
-rw-r--r-- | steuermann/specfile.exy | 2 |
6 files changed, 100 insertions, 24 deletions
diff --git a/steuermann/hosts.ini b/steuermann/hosts.ini index abc114c..d750134 100644 --- a/steuermann/hosts.ini +++ b/steuermann/hosts.ini @@ -86,6 +86,13 @@ like=linux:csh workdir=/arzach/data1/iraf/steuermann maxproc=4 +[etcbrady] +hostname=etcbrady +like=linux:csh +workdir=/home/iraf/sm_work +; because each thing wants all the processors +maxproc=1 + [localhost] like=ssb diff --git a/steuermann/nodes.py b/steuermann/nodes.py index 476734a..3ad4639 100644 --- a/steuermann/nodes.py +++ b/steuermann/nodes.py @@ -11,6 +11,11 @@ import fnmatch class command_tree(object): + # list of additional files to import after this one; this is just + # here so we have a place to put it. It is appended by the parser + # and consumed by read_file_list() + import_list = [ ] + # a dict that maps currently known node names to node objects node_index = None @@ -315,11 +320,34 @@ current_file_name = None def read_file_list( file_list ) : global current_file_name di = command_tree( ) - for x in file_list : - current_file_name = x - sc = specfile.specfileScanner( open(x,'r').read() ) + imported = { } + while len(file_list) > 0 : + + print "START",file_list + # first name off the list + current_file_name = file_list[0] + file_list = file_list[1:] + print "LIST",file_list + + # see if it imported already + if current_file_name in imported : + print "SKIP",current_file_name + continue + imported[current_file_name] = 1 + + print "READING ",current_file_name + # read/parse + sc = specfile.specfileScanner( open(current_file_name,'r').read() ) p = specfile.specfile( scanner=sc, data=di ) + result = specfile.wrap_error_reporter( p, 'start' ) + + # if there were any import statements in the file, add those files to the list + file_list += di.import_list + di.import_list = [ ] + + print "END",file_list + di.finish() return di @@ -328,5 +356,3 @@ if __name__=='__main__': n = read_file_list( sys.argv[1:] ) print show_nodes(n.node_index) - - diff --git a/steuermann/run.py b/steuermann/run.py index 388b366..77db2f1 100644 --- a/steuermann/run.py +++ b/steuermann/run.py @@ -29,9 +29,14 @@ import os.path import traceback import sys import errno - import ConfigParser +def config_yes_no(d,which) : + if not which in d : + return False + s = d[which] + return s.strip()[0].lower() in ( 'y', 't', '1' ) + debug=0 ##### @@ -73,8 +78,15 @@ class runner(object): # start a process def run( self, node, run_name, logfile_name, no_run = False ): + '''run a process + return is: + D - host disabled + M - not run max proc limit + R - running +''' try : + try : args = self.get_host_info(node.host) except Exception, e : @@ -83,13 +95,16 @@ class runner(object): print e raise + if ( config_yes_no(args,'disable') ) : + return 'D' + hostname = args['hostname'] if 'maxproc' in args : n = int(self.howmany.get(hostname,0)) if n >= int(args['maxproc']) : # print "decline to run %s - %d other already running"%(node.name,n) - return False + return 'M' n = n + 1 self.howmany[hostname] = n @@ -154,8 +169,9 @@ class runner(object): logfile.flush() # debug - just say the name of the node we would run - if no_run : - run = [ 'echo', 'no_run - node=', node.name ] + + if ( no_run ) : + run = [ 'echo', 'disable run - node=', node.name ] # start running the process if debug : @@ -174,7 +190,7 @@ class runner(object): # remember the process is running self.all_procs[node.name] = n - return True + return 'R' except Exception, e : log_traceback() diff --git a/steuermann/run_all.py b/steuermann/run_all.py index 0c81fbf..b87ba7d 100644 --- a/steuermann/run_all.py +++ b/steuermann/run_all.py @@ -451,10 +451,21 @@ def run_step( runner, xnodes, run_name, db ) : no_sleep = 1 keep_running = 1 else : - if tmp : - # returns true/false whether it actually ran it - it may not because of resource limits + if tmp == 'R' : db.execute("UPDATE sm_status SET start_time = ?, status = 'R' WHERE ( run = ? AND host = ? AND tablename = ? AND cmd = ? )", ( str(datetime.datetime.now()), run_name, host, table, cmd ) ) + elif tmp == 'D' : + # same as skip above + x.finished = 1 + no_sleep = 1 + keep_running = 1 + db.execute("UPDATE sm_status SET start_time = ?, status = 'S' WHERE ( run = ? AND host = ? AND tablename = ? AND cmd = ? )", + ( str(datetime.datetime.now()), run_name, host, table, cmd ) ) + elif tmp == 'M' : + # hit max proc - not run, but try again later + pass + else : + print "WARNING: runner.run() returned unknown code %s"%str(tmp) db.commit() diff --git a/steuermann/run_cron.py b/steuermann/run_cron.py index 5779e1e..f2a01b3 100644 --- a/steuermann/run_cron.py +++ b/steuermann/run_cron.py @@ -58,18 +58,32 @@ def main() : node.script_type = 'r' # remote runner = steuermann.run.runner( nodes = { node.name : node } ) - runner.run( node=node, run_name='', logfile_name = steuermann.config.logdir + '/cron/' + logfile ) - - n = 0.1 - while 1 : - exited = runner.poll() - if exited : - break - if n < 2.0 : - n = n * 2.0 - time.sleep(n) - - status = exited[1] + logname = logfile_name = steuermann.config.logdir + '/cron/' + logfile + st = runner.run( node=node, run_name='', logfile_name = logname ) + + if st == 'D' : + fp = open(logname,"w") + fp.write('execution on host is disabled in hosts.ini\n') + fp.close() + status = 'S' + + elif st == 'M' : + fp = open(logname,"w") + fp.write('host is at max proc limit - how did this happen?') + fp.close() + status = '?' + + elif st == 'R' : + n = 0.1 + while 1 : + exited = runner.poll() + if exited : + break + if n < 2.0 : + n = n * 2.0 + time.sleep(n) + + status = exited[1] end_time = datetime.datetime.now() td = end_time - start_time diff --git a/steuermann/specfile.exy b/steuermann/specfile.exy index 7cdf1f3..cb2aa36 100644 --- a/steuermann/specfile.exy +++ b/steuermann/specfile.exy @@ -24,6 +24,7 @@ parser specfile: token string: '"[^"]*"' token SLASH: "/" token COLON: ":" + token IMPORT: "IMPORT" rule start: table_list END {{ return table_list }} @@ -38,6 +39,7 @@ parser specfile: command_list # command_list is a list of (command, pos) where command is the text from the file and pos is the location in the file {{ self.data.add_command_list( table_name, hostlist, command_list ) }} + | IMPORT string {{ self.data.import_list.append( string[1:-1] ) }} rule command_list: # one or more commands, appended together into a list |