aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--steuermann/config.py6
-rw-r--r--steuermann/nodes.py9
-rw-r--r--steuermann/run_all.py1
-rw-r--r--steuermann/specfile.exy87
-rw-r--r--x.in15
5 files changed, 91 insertions, 27 deletions
diff --git a/steuermann/config.py b/steuermann/config.py
index 3a001a7..a2beda2 100644
--- a/steuermann/config.py
+++ b/steuermann/config.py
@@ -1,8 +1,8 @@
-db_creds = '/ssbwebv1/data2/steuermann/steuermann.db'
+db_creds = 'steuermann.db'
def open_db() :
import sqlite3
return sqlite3.connect(db_creds)
-logdir = '/ssbwebv1/data2/steuermann/logs'
-host_logs = '/ssbwebv1/data2/steuermann/host_logs'
+logdir = 'logs'
+host_logs = 'host_logs'
diff --git a/steuermann/nodes.py b/steuermann/nodes.py
index e364f57..095b3d3 100644
--- a/steuermann/nodes.py
+++ b/steuermann/nodes.py
@@ -82,7 +82,7 @@ class command_tree(object):
def add_command_list( self, table, hostlist, command_list ) :
for host in set(hostlist) :
this_table = '%s:%s' % ( host, table )
- for command, script, script_type, after_clause, pos in command_list :
+ for command, script, script_type, after_clause, pos, resources in command_list :
# this happens once for each CMD clause
# command is the name of this command
# script is the script to run
@@ -96,7 +96,7 @@ class command_tree(object):
print "# warning: %s already used on line %s"%(command,self.node_index[command].input_line)
# create the node
- self.node_index[command]=node(command, script, script_type, nice_pos( current_file_name, pos) )
+ self.node_index[command]=node(command, script, script_type, nice_pos( current_file_name, pos), resources )
for before_name, required, pos in after_clause :
# this happens once for each AFTER clause
@@ -195,7 +195,7 @@ def wildcard_name( wild, name ) :
# true if the before node is finished running.
#
class node(object) :
- def __init__(self, name, script, script_type, input_line) :
+ def __init__(self, name, script, script_type, input_line, resources) :
# the fully qualified name of the node
self.name = name
@@ -203,6 +203,9 @@ class node(object) :
self.script = script
self.script_type = script_type
+ # what "resources" it requires
+ self.resources = resources
+
# what line of the input file specified this node; this is
# a string of the form "foo.bar 123"
self.input_line = input_line
diff --git a/steuermann/run_all.py b/steuermann/run_all.py
index 6bdf5d6..1dcade4 100644
--- a/steuermann/run_all.py
+++ b/steuermann/run_all.py
@@ -164,6 +164,7 @@ def print_node(xnodes, x, print_recursive, print_all, indent=0, print_cmd=1):
if print_all :
l = [ a.name for a in xnodes[x].predecessors ]
print ' '*indent, " AFTER", ' '.join(l)
+ print ' '*indent, " RESOURCES", ' '.join([ "%s=%s"%(aa, xnodes[x].resources[aa]) for aa in sorted(xnodes[x].resources) ])
if print_recursive :
for x in l :
print_node( xnodes, x, print_recursive, print_all, indent=indent+8)
diff --git a/steuermann/specfile.exy b/steuermann/specfile.exy
index 35304a5..38211aa 100644
--- a/steuermann/specfile.exy
+++ b/steuermann/specfile.exy
@@ -21,6 +21,7 @@ parser specfile:
token RUN: "RUN"
token LOCAL: "LOCAL"
token IMPORT: "IMPORT"
+ token RESOURCE: "RESOURCE"
token DEBUG: "DEBUG"
token name: "[a-zA-Z0-9_.-]+"
token STAR: "\*"
@@ -31,14 +32,24 @@ parser specfile:
token SLASH: "/"
token COLON: ":"
token hostgroup: "@[a-zA-Z0-9_.-]+"
+ token number: "[0-9]+"
+ token RES_ALL: "all"
+ token RES_AVAILABLE: "available"
# watch carefully: none of the keywords are "END" on a line by themselves
token CONDITIONS: 'CONDITIONS[^"]*\n[\s]*END[ \t]*\n'
- rule start: table_list END {{ return table_list }}
+ ##
+ # This is the whole file
+ rule start: table_list "$" {{ return table_list }}
+
+ ##
+ #
rule table_list: table_section +
+ ##
+ #
rule table_section:
DEBUG string {{ print "-->debug: %s"%string }}
| hostgroup_def
@@ -48,14 +59,17 @@ parser specfile:
name {{ hostlist.append(name) }}
| hostgroup {{ hostlist = hostlist + nodes.get_hostgroup( hostgroup ) }}
)+
- command_cond<<tablename,hostlist>> +
+ cond_command<<tablename,hostlist>> +
| IMPORT string {{ self.data.import_list.append( string[1:-1] ) }}
##
+ #
rule hostgroup_def :
HOSTGROUP hostgroup {{ nodes.define_hostgroup( hostgroup) }}
( hostgroup_front<<hostgroup>> hostgroup_back<<hostgroup,hostgroup_front>> )+
+ ##
+ #
rule hostgroup_front<<hg>> :
IF name
{{ return nodes.check_condition(name, self._scanner.filename ) }}
@@ -63,34 +77,79 @@ parser specfile:
{{ return not nodes.check_condition(name, self._scanner.filename ) }}
| {{ return True }}
+ ##
+ #
rule hostgroup_back<<hg,accept_nodes>> :
COLON (
name {{ if accept_nodes : nodes.add_hostgroup( hg, name ) }}
| hostgroup {{ if accept_nodes : nodes.add_hostgroup( hg, hostgroup ) }}
)*
- rule command_cond<<table_name,hostlist>> :
- IF name COLON command {{ if nodes.check_condition(name, self._scanner.filename ) : self.data.add_command_list( table_name, hostlist, [ command ] ) }}
- | IFNOT name COLON command {{ if not nodes.check_condition(name, self._scanner.filename ) : self.data.add_command_list( table_name, hostlist, [ command ] ) }}
- | command {{ self.data.add_command_list( table_name, hostlist, [ command ] ) }}
+ ##
+ #
+ rule cond_command<<table_name,hostlist>> :
+ IF name COLON command
+ {{ if nodes.check_condition(name, self._scanner.filename ) : self.data.add_command_list( table_name, hostlist, [ command ] ) }}
+ | IFNOT name COLON command
+ {{ if not nodes.check_condition(name, self._scanner.filename ) : self.data.add_command_list( table_name, hostlist, [ command ] ) }}
+ | command
+ {{ self.data.add_command_list( table_name, hostlist, [ command ] ) }}
- rule command:
+ ##
# a single command, including any number of AFTER clauses
- CMD {{ cmd_pos = self._scanner.get_pos() }}
- cmdname {{ cmd_name=cmdname; script=cmdname; x_after_clause = [ ] }}
- [ RUN string {{ script = string[1:-1]; script_type='r' }}
- | LOCAL string {{ script = string[1:-1]; script_type='l' }}
+ rule command:
+ CMD
+ {{ cmd_pos = self._scanner.get_pos() }}
+ {{ script_type = 'l' }}
+ {{ resources = { 'cpu' : 1 } }}
+ cmdname
+ {{ cmd_name=cmdname; script=cmdname; x_after_clause = [ ] }}
+ [
+ RUN string
+ {{ script = string[1:-1]; script_type='r' }}
+ |
+ LOCAL string
+ {{ script = string[1:-1]; script_type='l' }}
]
- ( {{ after_pos = self._scanner.get_pos() }}
- AFTER optword after_spec {{ x_after_clause.append( (after_spec, optword, after_pos) ) }}
+ (
+ {{ after_pos = self._scanner.get_pos() }}
+
+ [
+ RESOURCE resource_defs
+ {{ resources.update(resource_defs) }}
+ ]
+
+ AFTER optword after_spec
+ {{ x_after_clause.append( (after_spec, optword, after_pos) ) }}
)*
- {{ return ( cmd_name, script, script_type, x_after_clause, cmd_pos ) }}
+ {{ return ( cmd_name, script, script_type, x_after_clause, cmd_pos, resources ) }}
+ ##
+ #
+ rule resource_defs:
+ {{ rl = { } }}
+ (
+ name
+ "="
+ (
+ number
+ {{ ans = int(number) }}
+ | RES_ALL
+ {{ ans = 'all' }}
+ | RES_AVAILABLE
+ {{ ans = 'available' }}
+ )
+ {{ rl[name] = ans }}
+ ) *
+ {{ print rl ; return rl }}
+
+ ##
# in the AFTER clause, you can say OPT to mean the node is optional (not an error if it does not exist)
rule optword:
OPT {{ return 0 }}
| {{ return 1 }}
+ ##
rule after_spec:
wildname {{ rval = wildname }}
[ COLON wildname {{ rval = rval + ':' + wildname }} ]
diff --git a/x.in b/x.in
index a5ab004..fc4db90 100644
--- a/x.in
+++ b/x.in
@@ -1,9 +1,10 @@
TABLE a HOST host_a
- CMD A RUN "a" AFTER Z
- CMD B RUN "b" AFTER A
- CMD C RUN "c" AFTER X
- CMD D AFTER B
- CMD F AFTER *
+ CMD A RUN "a" AFTER Z
+ CMD B RUN "b" RESOURCE arf=1 chocolate=2 banana=5 AFTER A
+# CMD C RUN "c" AFTER X
+ CMD D AFTER B
+ CMD F RESOURCE stuff = all AFTER *
+ CMD G RESOURCE stuff = available AFTER D
+ CMD E RESOURCE AFTER D
- CMD E AFTER Z
- CMD Z
+ CMD Z