def _wait_for_heat_complete(self, orchestration_client, stack_id, timeout): # Wait for the stack to go to COMPLETE. timeout_t = time.time() + 60 * timeout marker = None event_log_context = heat_utils.EventLogContext() kwargs = { 'sort_dir': 'asc', 'nested_depth': '6' } while True: time.sleep(2) events = event_utils.get_events( orchestration_client, stack_id=stack_id, event_args=kwargs, marker=marker) if events: marker = getattr(events[-1], 'id', None) events_log = heat_utils.event_log_formatter( events, event_log_context) print(events_log) status = orchestration_client.stacks.get(stack_id).status if status == 'FAILED': raise Exception('Stack create failed') if status == 'COMPLETE': break if time.time() > timeout_t: msg = 'Stack creation timeout: %d minutes elapsed' % (timeout) raise Exception(msg)
def wait_for_events(ws, stack_name, out=None): """Receive events over the passed websocket and wait for final status.""" msg_template = _("\n Stack %(name)s %(status)s \n") if not out: out = sys.stdout event_log_context = utils.EventLogContext() while True: data = ws.recv()['body'] event = events_mod.Event(None, data['payload'], True) # Keep compatibility with the HTTP API event.event_time = data['timestamp'] event.resource_status = '%s_%s' % (event.resource_action, event.resource_status) events_log = utils.event_log_formatter([event], event_log_context) out.write(events_log) out.write('\n') if data['payload']['resource_name'] == stack_name: stack_status = data['payload']['resource_status'] if stack_status in ('COMPLETE', 'FAILED'): msg = msg_template % dict(name=stack_name, status=event.resource_status) return '%s_%s' % (event.resource_action, stack_status), msg
def poll_for_events(hc, stack_name, action=None, poll_period=5, marker=None, out=None, nested_depth=0): """Continuously poll events and logs for performed action on stack.""" if action: stop_status = ('%s_FAILED' % action, '%s_COMPLETE' % action) stop_check = lambda a: a in stop_status # noqa: E731 else: stop_check = lambda a: a.endswith('_COMPLETE') or a.endswith( '_FAILED') # noqa E731 no_event_polls = 0 msg_template = _("\n Stack %(name)s %(status)s \n") if not out: out = sys.stdout event_log_context = utils.EventLogContext() def is_stack_event(event): if getattr(event, 'resource_name', '') != stack_name: return False phys_id = getattr(event, 'physical_resource_id', '') links = dict( (l.get('rel'), l.get('href')) for l in getattr(event, 'links', [])) stack_id = links.get('stack', phys_id).rsplit('/', 1)[-1] return stack_id == phys_id while True: events = get_events(hc, stack_id=stack_name, nested_depth=nested_depth, event_args={ 'sort_dir': 'asc', 'marker': marker }) if len(events) == 0: no_event_polls += 1 else: no_event_polls = 0 # set marker to last event that was received. marker = getattr(events[-1], 'id', None) events_log = utils.event_log_formatter(events, event_log_context) out.write(events_log) out.write('\n') for event in events: # check if stack event was also received if is_stack_event(event): stack_status = getattr(event, 'resource_status', '') msg = msg_template % dict(name=stack_name, status=stack_status) if stop_check(stack_status): return stack_status, msg if no_event_polls >= 2: # after 2 polls with no events, fall back to a stack get stack = hc.stacks.get(stack_name, resolve_outputs=False) stack_status = stack.stack_status msg = msg_template % dict(name=stack_name, status=stack_status) if stop_check(stack_status): return stack_status, msg # go back to event polling again no_event_polls = 0 time.sleep(poll_period)
def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) client = self.app.client_manager.orchestration columns = ['id', 'resource_status', 'resource_status_reason', 'event_time', 'physical_resource_id'] kwargs = { 'resource_name': parsed_args.resource, 'filters': heat_utils.format_parameters(parsed_args.filter), 'sort_dir': 'asc' } if parsed_args.resource and parsed_args.nested_depth: msg = _('--nested-depth cannot be specified with --resource') raise exc.CommandError(msg) if parsed_args.nested_depth: columns.append('stack_name') nested_depth = parsed_args.nested_depth else: nested_depth = 0 if parsed_args.sort: sorts = [] sort_keys = [] for sort in parsed_args.sort: if sort.startswith(":"): sorts.append(":".join(["event_time", sort.lstrip(":")])) else: sorts.append(sort) sort_keys.append(sort.split(":")[0]) kwargs['sort_keys'] = sort_keys if ":" in parsed_args.sort[0]: kwargs['sort_dir'] = parsed_args.sort[0].split(":")[1] if parsed_args.follow: if parsed_args.formatter != 'log': msg = _('--follow can only be specified with --format log') raise exc.CommandError(msg) marker = parsed_args.marker try: event_log_context = heat_utils.EventLogContext() while True: events = event_utils.get_events( client, stack_id=parsed_args.stack, event_args=kwargs, nested_depth=nested_depth, marker=marker) if events: marker = getattr(events[-1], 'id', None) events_log = heat_utils.event_log_formatter( events, event_log_context) self.app.stdout.write(events_log) self.app.stdout.write('\n') time.sleep(5) # this loop never exits except (KeyboardInterrupt, EOFError): # ctrl-c, ctrl-d return [], [] events = event_utils.get_events( client, stack_id=parsed_args.stack, event_args=kwargs, nested_depth=nested_depth, marker=parsed_args.marker, limit=parsed_args.limit) if parsed_args.sort: events = utils.sort_items(events, ','.join(sorts)) if parsed_args.formatter == 'log': return [], events if len(events): if hasattr(events[0], 'resource_name'): columns.insert(0, 'resource_name') columns.append('logical_resource_id') else: columns.insert(0, 'logical_resource_id') return ( columns, (utils.get_item_properties(s, columns) for s in events) )