1 from modules.base import Automatia
6 except: import simplejson as json
8 class OrchestraAutomatia(Automatia):
9 """Abstract helper module to wrap an Orchestra score.
11 Use this helper to implement any item that can be directly
12 mapped to a single Orchestra score.
14 Override do_magic() if you want to do more than just wrap a single
15 score (almost multiple scores should almost certainly be instead made
16 multiple items in make-magic)
21 score_target = config.default_orchestra_target
26 """Execute an Orchestra score."""
27 if self.score_name == None:
28 raise NotImplementedError(self.module_name + '.score_name')
38 def execute_score(name, scope='one',
39 target=config.default_orchestra_target, args={},
41 """Execute an Orchestra score, block for completion, then return
42 the result as a (job_id, result) tuple.
44 Will raise ``util.OrchestraError`` on any Orchestra failure.
47 oc = util.OrchestraClient()
48 job_id = oc.submit_job(name, scope, target, args)
49 result = oc.wait_for_completion(job_id, timeout=timeout)
51 if result['Status'] == 'OK':
52 return (job_id, result, )
54 raise util.OrchestraError(repr(result))
56 class OrchestraMetadataAutomatia(OrchestraAutomatia):
57 '''Helper module to wrap an Orchestra score and update task metadata from the result
60 # Mapping from orchestra response variables to metadata key names
61 orchestra_response_map = None
63 def get_variable_from_results(self, results, resultvarname):
64 '''look through orchestra results and find the value keyed on resultvarname
66 FIXME: THIS SHOULD BE IN util.py
67 pre: results status is OK and players have completed the score
69 # response looks like:
70 # {u'Status': u'OK', u'Players': {u'orchestra.player.hostname.example': {u'Status': u'OK', u'Response': {u'echo': u'{"PATH": "/usr/bin:/usr/sbin:/bin:/sbin", "PWD": "/var/lib/service/player", "IFS": " \\t\\n", "ORC_foo": "bar", "ORC_fish": "heads"}'}}}}
71 assert results['Status'] == 'OK'
72 for player,result in results['Players'].items():
73 if result['Status'] != 'OK': continue
74 for score,playerresponse in result['Response'].items():
75 playerresponse = json.loads(playerresponse) # UGH. This should NOT be in here FIXME: Move unrolling to OrchestraClient
76 if playerresponse.has_key(resultvarname):
77 return playerresponse[resultvarname]
78 return KeyError("Variable '"+resultvarname+"' not returned by any Orchestra player")
81 if self.orchestra_response_map == None:
82 raise NotImplementedError(str(self.module_name+'.orchestra_response_map'))
83 results = self.execute_score(self.score_args)
85 for response_var,metadata_key in self.orchestra_response_map.items():
86 task_metadata_update[metadata_key] = self.get_variable_from_results(results, response_var)
88 return dict(task_metadata_update=metadata_update)