async def scan_one(reg, host, port, timeout=None, methods=None): if not methods: methods = ['identify'] if is_remote_host(host): try: host = get_host_ip_by_name(host) # IP reduces DNS traffic except socket.error as exc: if cylc.flow.flags.debug: raise sys.stderr.write("ERROR: %s: %s\n" % (exc, host)) return (reg, host, port, None) # NOTE: Connect to the suite by host:port, this was the # SuiteRuntimeClient will not attempt to check the contact file # which would be unnecessary as we have already done so. # NOTE: This part of the scan *is* IO blocking. client = SuiteRuntimeClient(reg, host=host, port=port, timeout=timeout) result = {} for method in methods: # work our way up the chain of identity methods, extract as much # information as we can before the suite rejects us try: msg = await client.async_request(method) except ClientTimeout as exc: LOG.exception(f"Timeout: name:{reg}, host:{host}, port:{port}") return (reg, host, port, MSG_TIMEOUT) except ClientError as exc: LOG.exception("ClientError") return (reg, host, port, result or None) else: result.update(msg) return (reg, host, port, result)
def main(parser, options, suite, *task_globs): if not options.state and not options.outputs: parser.error("Neither --state=STATE nor --output=OUTPUT is set") if options.state == "spawn": # Back compat. sys.stderr.write( "'cylc reset -s spawn' is deprecated; calling 'cylc spawn'\n") cmd = sys.argv[0].replace('reset', 'spawn') try: os.execvp(cmd, [cmd] + task_globs) except OSError as exc: if exc.filename is None: exc.filename = cmd raise SystemExit(exc) if not options.state: options.state = '' prompt('Reset task(s) %s in %s' % (task_globs, suite), options.force) pclient = SuiteRuntimeClient(suite, options.owner, options.host, options.port, options.comms_timeout) pclient( 'reset_task_states', { 'task_globs': task_globs, 'state': options.state, 'outputs': options.outputs })
def main(parser, options, suite, event_msg, event_id): LOG.info('Send to suite %s: "%s" (%s)', suite, event_msg, event_id) pclient = SuiteRuntimeClient(suite, options.owner, options.host, options.port) max_n_tries = int(options.max_n_tries) retry_intvl_secs = float(options.retry_intvl_secs) for i_try in range(max_n_tries): try: pclient('put_ext_trigger', { 'message': event_msg, 'id': event_id }, timeout=options.comms_timeout) except ClientError as exc: LOG.exception(exc) LOG.info(MSG_SEND_FAILED, i_try + 1, max_n_tries) if i_try == max_n_tries - 1: # final attempt raise CylcError('send failed') else: LOG.info(MSG_SEND_RETRY, retry_intvl_secs, options.comms_timeout) sleep(retry_intvl_secs) else: if i_try > 0: LOG.info(MSG_SEND_SUCCEED, i_try + 1, max_n_tries) break
def main(parser, options, suite, event_msg, event_id): LOG.info('Send to suite %s: "%s" (%s)', suite, event_msg, event_id) pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout) max_n_tries = int(options.max_n_tries) retry_intvl_secs = float(options.retry_intvl_secs) mutation_kwargs = { 'request_string': MUTATION, 'variables': { 'wFlows': [suite], 'eventMsg': event_msg, 'eventId': event_id, } } for i_try in range(max_n_tries): try: pclient('graphql', mutation_kwargs) except ClientError as exc: LOG.exception(exc) LOG.info(MSG_SEND_FAILED, i_try + 1, max_n_tries) if i_try == max_n_tries - 1: # final attempt raise CylcError('send failed') LOG.info(MSG_SEND_RETRY, retry_intvl_secs, options.comms_timeout) sleep(retry_intvl_secs) else: if i_try > 0: LOG.info(MSG_SEND_SUCCEED, i_try + 1, max_n_tries) break
def main(parser, options, suite, *task_globs): prompt('remove task(s) %s in %s' % (task_globs, suite), options.force) pclient = SuiteRuntimeClient( suite, options.owner, options.host, options.port, options.comms_timeout) pclient( 'remove_tasks', {'tasks': task_globs, 'spawn': (not options.no_spawn)} )
def main(parser, options, suite): pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout) query_kwargs = {'request_string': QUERY, 'variables': {'wFlows': [suite]}} result = pclient('graphql', query_kwargs) for workflow in result['workflows']: print(workflow['cylcVersion'])
def main(): parser = COP(__doc__, comms=True, argdoc=[('REG', 'Suite name')]) (options, args) = parser.parse_args() suite = args[0] pclient = SuiteRuntimeClient(suite, options.owner, options.host, options.port) print(pclient('get_cylc_version', timeout=options.comms_timeout))
def main(parser, options, suite, *task_globs): """CLI of "cylc kill".""" if task_globs: prompt('Kill task %s in %s' % (task_globs, suite), options.force) else: prompt('Kill ALL tasks in %s' % (suite), options.force) pclient = SuiteRuntimeClient(suite, options.owner, options.host, options.port) pclient('kill_tasks', {'tasks': task_globs}, timeout=options.comms_timeout)
def main(parser, options, suite): pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout) mutation_kwargs = { 'request_string': MUTATION, 'variables': { 'wflows': [suite] } } pclient('graphql', mutation_kwargs)
def main(parser, options, suite, *task_globs): if task_globs: prompt('Poll task %s in %s' % (task_globs, suite), options.force) else: prompt('Poll ALL tasks in %s' % (suite), options.force) pclient = SuiteRuntimeClient(suite, options.owner, options.host, options.port, options.comms_timeout) pclient('poll_tasks', { 'tasks': task_globs, 'poll_succeeded': options.poll_succ })
def main(parser, options, workflow): workflow = os.path.normpath(workflow) pclient = SuiteRuntimeClient(workflow, timeout=options.comms_timeout) mutation_kwargs = { 'request_string': MUTATION, 'variables': { 'wFlows': [workflow], } } pclient('graphql', mutation_kwargs)
def main(parser, options, suite, *task_globs): pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout) mutation_kwargs = { 'request_string': MUTATION, 'variables': { 'wFlows': [suite], 'tasks': list(task_globs), } } pclient('graphql', mutation_kwargs)
def main(_, options, suite, name): pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout) mutation_kwargs = { 'request_string': MUTATION, 'variables': { 'wFlows': [suite], 'cName': name, } } pclient('graphql', mutation_kwargs)
def main(parser, options, suite, shutdown_arg=None): if shutdown_arg is not None and options.kill: parser.error("ERROR: --kill is not compatible with [STOP]") if options.kill and options.now: parser.error("ERROR: --kill is not compatible with --now") if options.flow_label and int(options.max_polls) > 0: parser.error("ERROR: --flow is not compatible with --max-polls") pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout) if int(options.max_polls) > 0: # (test to avoid the "nothing to do" warning for # --max-polls=0) spoller = StopPoller(pclient, "suite stopped", options.interval, options.max_polls) # mode defaults to 'Clean' mode = None task = None cycle_point = None if shutdown_arg is not None and TaskID.is_valid_id(shutdown_arg): # STOP argument detected task = shutdown_arg elif shutdown_arg is not None: # not a task ID, may be a cycle point cycle_point = shutdown_arg elif options.kill: mode = 'Kill' elif options.now > 1: mode = 'NowNow' elif options.now: mode = 'Now' mutation_kwargs = { 'request_string': MUTATION, 'variables': { 'wFlows': [suite], 'stopMode': mode, 'cyclePoint': cycle_point, 'clockTime': options.wall_clock, 'task': task, 'flowLabel': options.flow_label, } } pclient('graphql', mutation_kwargs) if int(options.max_polls) > 0: # (test to avoid the "nothing to do" warning for # --max-polls=0) if not spoller.poll(): sys.exit(1)
def main(parser, options, suite, severity_str): try: severity = LOGGING_LVL_OF[severity_str] except KeyError: parser.error("Illegal logging level, %s" % severity_str) prompt("Set logging level to %s in %s" % (severity_str, suite), options.force) pclient = SuiteRuntimeClient( suite, options.owner, options.host, options.port, options.comms_timeout) pclient('set_verbosity', {'level': severity})
def setUp(self) -> None: super(TestSuiteRuntimeClient, self).setUp() self.scheduler.data_store_mgr = DataStoreMgr(self.scheduler) for name in self.scheduler.config.taskdefs: task_proxy = create_task_proxy( task_name=name, suite_config=self.suite_config, is_startup=True ) warnings = self.task_pool.insert_tasks( items=[task_proxy.identity], stopcp=None, check_point=True ) assert warnings == 0 self.task_pool.release_runahead_tasks() self.scheduler.data_store_mgr.initiate_data_model() self.workflow_id = self.scheduler.data_store_mgr.workflow_id create_auth_files(self.suite_name) # auth keys are required for comms barrier = Barrier(2, timeout=20) self.server = SuiteRuntimeServer( self.scheduler, context=SERVER_CONTEXT, threaded=True, barrier=barrier, daemon=True) port_range = glbl_cfg().get(['suite servers', 'run ports']) self.server.start(port_range[0], port_range[-1]) # barrier.wait() doesn't seem to work properly here # so this workaround will do while barrier.n_waiting < 1: sleep(0.2) barrier.wait() sleep(0.5) self.client = SuiteRuntimeClient( self.scheduler.suite, host=self.scheduler.host, port=self.server.port) sleep(0.5)
def main(_, options, suite): pclient = SuiteRuntimeClient(suite, options.owner, options.host, options.port, options.comms_timeout) summary = pclient('get_suite_state_summary') if options.disp_form == "raw": print(summary) else: if options.disp_form != "tasks": for key, value in sorted(summary[0].items()): print("%s=%s" % (key, value)) if options.disp_form != "global": dump_to_stdout(summary[1], options.sort_by_cycle)
async def scan_one(reg, host, port, pub_port, api, timeout=None, methods=None): """Connect to and identify workflow server if possible. Args: reg (str): Registered name of workflow. host (str): Workflow host. port (int): Workflow server port. pub_port (int): Workflow publisher port. api (str): Workflow API version. timeout (float, optional): Client socket receiver timeout. methods (list): List of methods/endpoints to request. Returns: tuple: (reg, host, port, pub_port, result) """ if not methods: methods = ['identify'] if is_remote_host(host): try: host = get_host_ip_by_name(host) # IP reduces DNS traffic except socket.error as exc: if cylc.flow.flags.debug: raise sys.stderr.write("ERROR: %s: %s\n" % (exc, host)) return (reg, host, port, pub_port, api, None) # NOTE: Connect to the suite by host:port, this was the # SuiteRuntimeClient will not attempt to check the contact file # which would be unnecessary as we have already done so. # NOTE: This part of the scan *is* IO blocking. client = SuiteRuntimeClient(reg, host=host, port=port, timeout=timeout) result = {} for method in methods: # work our way up the chain of identity methods, extract as much # information as we can before the suite rejects us try: msg = await client.async_request(method) except ClientTimeout as exc: LOG.exception( "Timeout: name:%s, host:%s, port:%s", reg, host, port) return (reg, host, port, pub_port, api, MSG_TIMEOUT) except ClientError as exc: LOG.exception("ClientError") return (reg, host, port, pub_port, api, result or None) else: result.update(msg) return (reg, host, port, pub_port, api, result)
def record_messages(suite, task_job, messages): """Record task job messages. Print the messages according to their severity. Write the messages in the job status file. Send the messages to the suite, if possible. Arguments: suite (str): Suite name. task_job (str): Task job identifier "CYCLE/TASK_NAME/SUBMIT_NUM". messages (list): List of messages "[[severity, message], ...]". """ # Record the event time, in case the message is delayed in some way. event_time = get_current_time_string( override_use_utc=(os.getenv('CYLC_UTC') == 'True')) # Print to stdout/stderr for severity, message in messages: if severity in STDERR_LEVELS: handle = sys.stderr else: handle = sys.stdout handle.write('%s %s - %s\n' % (event_time, severity, message)) handle.flush() # Write to job.status _append_job_status_file(suite, task_job, event_time, messages) # Send messages try: pclient = SuiteRuntimeClient(suite) except SuiteStopped: # on a remote host this means the contact file is not present # either the suite is stopped or the contact file is not present # on the job host (i.e. comms method is polling) # eitherway don't try messaging pass except Exception: # Backward communication not possible if cylc.flow.flags.debug: import traceback traceback.print_exc() else: mutation_kwargs = { 'request_string': MUTATION, 'variables': { 'wFlows': [suite], 'taskJob': task_job, 'eventTime': event_time, 'messages': messages, } } pclient('graphql', mutation_kwargs)
def main(parser, options, suite, *items): for i, item in enumerate(items): if not TaskID.is_valid_id_2(item): raise UserInputError( '"%s": invalid task ID (argument %d)' % (item, i + 1)) prompt('Insert %s in %s' % (items, suite), options.force) pclient = SuiteRuntimeClient( suite, options.owner, options.host, options.port) pclient( 'insert_tasks', {'items': items, 'no_check': options.no_check, 'stop_point_string': options.stop_point_string}, timeout=options.comms_timeout )
def main(parser, options, suite, severity_str): try: severity = LOG_LEVELS[severity_str] except KeyError: parser.error("Illegal logging level, %s" % severity_str) pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout) mutation_kwargs = { 'request_string': MUTATION, 'variables': { 'wFlows': [suite], 'level': severity, } } pclient('graphql', mutation_kwargs)
def main(parser, options, suite, shutdown_arg=None): if shutdown_arg is not None and options.kill: parser.error("ERROR: --kill is not compatible with [STOP]") if options.kill and options.now: parser.error("ERROR: --kill is not compatible with --now") pclient = SuiteRuntimeClient(suite, options.owner, options.host, options.port, options.comms_timeout) if int(options.max_polls) > 0: # (test to avoid the "nothing to do" warning for # --max-polls=0) spoller = StopPoller(pclient, "suite stopped", options.interval, options.max_polls) if options.wall_clock: prompt( 'Set shutdown at wall clock %s for %s' % (options.wall_clock, suite), options.force) pclient('set_stop_after_clock_time', {'datetime_string': options.wall_clock}) elif shutdown_arg is not None and TaskID.is_valid_id(shutdown_arg): # STOP argument detected prompt('Set shutdown after task %s for %s' % (shutdown_arg, suite), options.force) pclient('set_stop_after_task', {'task_id': shutdown_arg}) elif shutdown_arg is not None: # not a task ID, may be a cycle point prompt('Set shutdown at cycle point %s for %s' % (shutdown_arg, suite), options.force) pclient('set_stop_after_point', {'point_string': shutdown_arg}) elif options.now > 1: prompt('Shut down and terminate %s now' % suite, options.force) pclient('stop_now', {'terminate': True}) elif options.now: prompt('Shut down %s now' % suite, options.force) pclient('stop_now') else: prompt('Shut down %s' % suite, options.force) pclient('set_stop_cleanly', {'kill_active_tasks': options.kill}) if int(options.max_polls) > 0: # (test to avoid the "nothing to do" warning for # --max-polls=0) if not spoller.poll(): sys.exit(1)
async def est_workflow(reg, host, port, pub_port, context=None, timeout=None): """Establish communication with workflow, instantiating REQ client.""" if is_remote_host(host): try: host = get_host_ip_by_name(host) # IP reduces DNS traffic except socket.error as exc: if flags.debug: raise logger.error("ERROR: %s: %s\n", exc, host) return (reg, host, port, pub_port, None) # NOTE: Connect to the suite by host:port. This way the # SuiteRuntimeClient will not attempt to check the contact file # which would be unnecessary as we have already done so. # NOTE: This part of the scan *is* IO blocking. client = SuiteRuntimeClient(reg, context=context, timeout=timeout) _, result = await workflow_request(client, 'identify') return (reg, host, port, pub_port, client, result)
def main(_, options, suite, func): pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout) if options.no_input: kwargs = {} else: kwargs = json.load(sys.stdin) sys.stdin.close() res = pclient(func, kwargs) if func in PB_METHOD_MAP: if 'element_type' in kwargs: pb_msg = PB_METHOD_MAP[func][kwargs['element_type']]() else: pb_msg = PB_METHOD_MAP[func]() pb_msg.ParseFromString(res) res_msg = MessageToDict(pb_msg) else: res_msg = res sys.stdout.write(json.dumps(res_msg, indent=4) + '\n')
def main(parser, options, suite, *task_globs): if task_globs: prompt('Hold task(s) %s in %s' % (task_globs, suite), options.force) elif options.hold_point_string: prompt('Hold suite after %s' % options.hold_point_string, options.force) else: prompt('Hold suite %s' % suite, options.force) pclient = SuiteRuntimeClient(suite, options.owner, options.host, options.port) if task_globs: pclient('hold_tasks', {'task_globs': task_globs}, timeout=options.comms_timeout) elif options.hold_point_string: pclient('hold_after_point_string', {'point_string': options.hold_point_string}, timeout=options.comms_timeout) else: pclient('hold_suite', timeout=options.comms_timeout)
def main(parser, options, suite, task_id=None): pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout) if task_id and not TaskID.is_valid_id(task_id): raise UserInputError("Invalid task ID: %s" % task_id) flow_kwargs = { 'request_string': FLOW_QUERY, 'variables': { 'wFlows': [suite] } } task_kwargs = { 'request_string': TASK_QUERY, } # cylc ping SUITE result = pclient('graphql', flow_kwargs) msg = "" for flow in result['workflows']: w_name = flow['name'] w_port = flow['port'] w_pub_port = flow['pubPort'] if cylc.flow.flags.verbose: sys.stdout.write(f'{w_name} running on ' f'{pclient.host}:{w_port} {w_pub_port}\n') # cylc ping SUITE TASKID if task_id: task, point = TaskID.split(task_id) w_id = flow['id'] task_kwargs['variables'] = { 'tProxy': f'{w_id}{ID_DELIM}{point}{ID_DELIM}{task}' } task_result = pclient('graphql', task_kwargs) if not task_result.get('taskProxy'): msg = "task not found" elif task_result['taskProxy']['state'] != TASK_STATUS_RUNNING: msg = f"task not {TASK_STATUS_RUNNING}" if msg: print(cparse(f'<red>{msg}</red>')) sys.exit(1)
def record_messages(suite, task_job, messages): """Record task job messages. Print the messages according to their severity. Write the messages in the job status file. Send the messages to the suite, if possible. Arguments: suite (str): Suite name. task_job (str): Task job identifier "CYCLE/TASK_NAME/SUBMIT_NUM". messages (list): List of messages "[[severity, message], ...]". """ # Record the event time, in case the message is delayed in some way. event_time = get_current_time_string( override_use_utc=(os.getenv('CYLC_UTC') == 'True')) # Print to stdout/stderr for severity, message in messages: if severity in STDERR_LEVELS: handle = sys.stderr else: handle = sys.stdout handle.write('%s %s - %s\n' % (event_time, severity, message)) handle.flush() # Write to job.status _append_job_status_file(suite, task_job, event_time, messages) # Send messages try: pclient = SuiteRuntimeClient(suite) except Exception: # Backward communication not possible if cylc.flow.flags.debug: import traceback traceback.print_exc() else: pclient('put_messages', { 'task_job': task_job, 'event_time': event_time, 'messages': messages })
class TestSuiteRuntimeClient(CylcWorkflowTestCase): """Test the workflow runtime client.""" suite_name = "five" suiterc = """ [meta] title = "Inter-cycle dependence + a cold-start task" [cylc] UTC mode = True [scheduling] #runahead limit = 120 initial cycle point = 20130808T00 final cycle point = 20130812T00 [[graph]] R1 = "prep => foo" PT12H = "foo[-PT12H] => foo => bar" [visualization] initial cycle point = 20130808T00 final cycle point = 20130808T12 [[node attributes]] foo = "color=red" bar = "color=blue" """ def setUp(self) -> None: super(TestSuiteRuntimeClient, self).setUp() self.scheduler.data_store_mgr = DataStoreMgr(self.scheduler) for name in self.scheduler.config.taskdefs: task_proxy = create_task_proxy( task_name=name, suite_config=self.suite_config, is_startup=True ) warnings = self.task_pool.insert_tasks( items=[task_proxy.identity], stopcp=None, check_point=True ) assert warnings == 0 self.task_pool.release_runahead_tasks() self.scheduler.data_store_mgr.initiate_data_model() self.workflow_id = self.scheduler.data_store_mgr.workflow_id create_auth_files(self.suite_name) # auth keys are required for comms barrier = Barrier(2, timeout=20) self.server = SuiteRuntimeServer( self.scheduler, context=SERVER_CONTEXT, threaded=True, barrier=barrier, daemon=True) port_range = glbl_cfg().get(['suite servers', 'run ports']) self.server.start(port_range[0], port_range[-1]) # barrier.wait() doesn't seem to work properly here # so this workaround will do while barrier.n_waiting < 1: sleep(0.2) barrier.wait() sleep(0.5) self.client = SuiteRuntimeClient( self.scheduler.suite, host=self.scheduler.host, port=self.server.port) sleep(0.5) def tearDown(self): self.server.stop() self.client.stop() def test_constructor(self): self.assertFalse(self.client.socket.closed) def test_serial_request(self): """Test GraphQL endpoint method.""" request_string = f''' query {{ workflows(ids: ["{self.workflow_id}"]) {{ id }} }} ''' data = self.client.serial_request( 'graphql', args={'request_string': request_string}) self.assertEqual(data['workflows'][0]['id'], self.workflow_id) pb_msg = self.client.serial_request('pb_entire_workflow') pb_data = PB_METHOD_MAP['pb_entire_workflow']() pb_data.ParseFromString(pb_msg) self.assertEqual(pb_data.workflow.id, self.workflow_id)
def main(_, options, suite, *task_args): """Implement "cylc show" CLI.""" pclient = SuiteRuntimeClient(suite, timeout=options.comms_timeout) json_filter = {} if not task_args: query = WORKFLOW_META_QUERY query_kwargs = { 'request_string': query, 'variables': { 'wFlows': [suite] } } # Print suite info. results = pclient('graphql', query_kwargs) for workflow in results['workflows']: flat_data = flatten_data(workflow) if options.json: json_filter.update(flat_data) else: for key, value in sorted(flat_data.items(), reverse=True): ansiprint( f'<bold>{key}:</bold> {value or "<m>(not given)</m>"}') task_names = [arg for arg in task_args if TaskID.is_valid_name(arg)] task_ids = [arg for arg in task_args if TaskID.is_valid_id_2(arg)] if task_names: tasks_query = TASK_META_QUERY tasks_kwargs = { 'request_string': tasks_query, 'variables': { 'wFlows': [suite], 'taskIds': task_names } } # Print suite info. results = pclient('graphql', tasks_kwargs) multi = len(results['tasks']) > 1 for task in results['tasks']: flat_data = flatten_data(task['meta']) if options.json: json_filter.update({task['name']: flat_data}) else: if multi: print(f'----\nTASK NAME: {task["name"]}') for key, value in sorted(flat_data.items(), reverse=True): ansiprint( f'<bold>{key}:</bold> {value or "<m>(not given)</m>"}') if task_ids: tp_query = TASK_PREREQS_QUERY tp_kwargs = { 'request_string': tp_query, 'variables': { 'wFlows': [suite], 'taskIds': [ f'{c}{ID_DELIM}{n}' for n, c in [ TaskID.split(t_id) for t_id in task_ids if TaskID.is_valid_id(t_id) ] ] + [ f'{c}{ID_DELIM}{n}' for c, n in [ t_id.rsplit(TaskID.DELIM2, 1) for t_id in task_ids if not TaskID.is_valid_id(t_id) ] ] } } results = pclient('graphql', tp_kwargs) multi = len(results['taskProxies']) > 1 for t_proxy in results['taskProxies']: task_id = TaskID.get(t_proxy['name'], t_proxy['cyclePoint']) if options.json: json_filter.update({task_id: t_proxy}) else: if multi: print(f'----\nTASK ID: {task_id}') prereqs = [] for item in t_proxy['prerequisites']: prefix = '' multi_cond = len(item['conditions']) > 1 if multi_cond: prereqs.append([ True, '', item['expression'].replace('c', ''), item['satisfied'] ]) for cond in item['conditions']: if multi_cond and not options.list_prereqs: prefix = f'\t{cond["exprAlias"].strip("c")} = ' _, _, point, name = cond['taskId'].split(ID_DELIM) cond_id = TaskID.get(name, point) prereqs.append([ False, prefix, f'{cond_id} {cond["reqState"]}', cond['satisfied'] ]) if options.list_prereqs: for composite, _, msg, _ in prereqs: if not composite: print(msg) else: flat_meta = flatten_data(t_proxy['task']['meta']) for key, value in sorted(flat_meta.items(), reverse=True): ansiprint(f'<bold>{key}:</bold>' f' {value or "<m>(not given)</m>"}') ansiprint('\n<bold>prerequisites</bold>' ' (<red>- => not satisfied</red>):') if not prereqs: print(' (None)') for _, prefix, msg, state in prereqs: print_msg_state(f'{prefix}{msg}', state) ansiprint('\n<bold>outputs</bold>' ' (<red>- => not completed</red>):') if not t_proxy['outputs']: print(' (None)') for key, val in t_proxy['outputs'].items(): print_msg_state(f'{task_id} {key}', val) if t_proxy['extras']: print('\nother:') for key, value in t_proxy['extras'].items(): print(' o %s ... %s' % (key, value)) if not results['taskProxies']: ansiprint(f"<red>No matching tasks found: {task_ids}", file=sys.stderr) sys.exit(1) if options.json: print(json.dumps(json_filter, indent=4))
async def harness(mod_flow, mod_scheduler, mod_run, mod_one_conf): reg = mod_flow(mod_one_conf) schd = mod_scheduler(reg) async with mod_run(schd): client = SuiteRuntimeClient(reg) yield schd, client