def __str__(self): return ("Command name: %(name)s, " "params: %(params)s, status: %(status)s, result: " "%(result)s." % { "name": self.command_name, "params": utils.remove_large_keys(self.command_params), "status": self.command_status, "result": utils.remove_large_keys(self.command_result) })
def test_remove_keys(self): value = {'system_logs': 'abcd', 'key': 'value', 'other': [{'configdrive': 'foo'}, 'string', 0]} expected = {'system_logs': '<...>', 'key': 'value', 'other': [{'configdrive': '<...>'}, 'string', 0]} self.assertEqual(expected, utils.remove_large_keys(value))
def execute_command(self, command_name, **kwargs): """Execute an agent command.""" with self.command_lock: LOG.debug('Executing command: %(name)s with args: %(args)s', { 'name': command_name, 'args': utils.remove_large_keys(kwargs) }) extension_part, command_part = self.split_command(command_name) if len(self.command_results) > 0: last_command = list(self.command_results.values())[-1] if not last_command.is_done(): LOG.error( 'Tried to execute %(command)s, agent is still ' 'executing %(last)s', { 'command': command_name, 'last': last_command }) raise errors.CommandExecutionError('agent is busy') try: ext = self.get_extension(extension_part) result = ext.execute(command_part, **kwargs) except KeyError: # Extension Not found LOG.exception('Extension %s not found', extension_part) raise errors.RequestedObjectNotFoundError( 'Extension', extension_part) except errors.InvalidContentError as e: # Any command may raise a InvalidContentError which will be # returned to the caller directly. LOG.exception('Invalid content error: %s', e) raise e except Exception as e: # Other errors are considered command execution errors, and are # recorded as a failed SyncCommandResult with an error message LOG.exception('Command execution error: %s', e) result = SyncCommandResult(command_name, kwargs, False, e) LOG.info('Command %(name)s completed: %(result)s', { 'name': command_name, 'result': utils.remove_large_keys(result) }) self.command_results[result.id] = result return result
def wrapper(self, **command_params): # Run a validator before invoking the function. # validators should raise exceptions or return silently. if validator: validator(self, **command_params) result = func(self, **command_params) LOG.info('Synchronous command %(name)s completed: %(result)s', { 'name': command_name, 'result': utils.remove_large_keys(result) }) return SyncCommandResult(command_name, command_params, True, result)
def run(self): """Run a command.""" try: result = self.execute_method(**self.command_params) if isinstance(result, (bytes, str)): result = {'result': '{}: {}'.format(self.command_name, result)} LOG.info( 'Command: %(name)s, result: %(result)s', { 'name': self.command_name, 'result': utils.remove_large_keys(result) }) with self.command_state_lock: self.command_result = result self.command_status = AgentCommandStatus.SUCCEEDED except errors.VersionMismatch as e: with self.command_state_lock: self.command_error = e self.command_status = AgentCommandStatus.VERSION_MISMATCH self.command_result = None LOG.error('Clean version mismatch for command %s', self.command_name) except Exception as e: LOG.exception('Command failed: %(name)s, error: %(err)s', { 'name': self.command_name, 'err': e }) if not isinstance(e, errors.RESTError): e = errors.CommandExecutionError(str(e)) with self.command_state_lock: self.command_error = e self.command_status = AgentCommandStatus.FAILED finally: if self.agent: self.agent.force_heartbeat()