def execute_command(self, command_name, **kwargs): """Execute an agent command.""" with self.command_lock: 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(): raise errors.CommandExecutionError('agent is busy') try: ext = self.get_extension(extension_part) result = ext.execute(command_part, **kwargs) except KeyError: # Extension Not found 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. raise e except Exception as e: # Other errors are considered command execution errors, and are # recorded as an result = SyncCommandResult(command_name, kwargs, False, six.text_type(e)) self.command_results[result.id] = result return result
def _validate_exts(ext, flow=None): for task in flow: for method in task: ext_name, cmd = ext.split_command(method) if ext_name not in ext.ext_mgr.names(): raise errors.RequestedObjectNotFoundError( 'Extension', ext_name) ext_obj = ext.ext_mgr[ext_name].obj ext.check_cmd_presence(ext_obj, ext_name, cmd)
def get_command_result(self, result_id): """Get a specific command result by ID. :returns: a :class:`ironic_python_agent.extensions.base. BaseCommandResult` object. :raises: RequestedObjectNotFoundError if command with the given ID is not found. """ try: return self.command_results[result_id] except KeyError: raise errors.RequestedObjectNotFoundError('Command Result', result_id)
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 test_error_classes(self): cases = [ (errors.InvalidContentError(DETAILS), SAME_DETAILS), (errors.NotFound(), SAME_CL_DETAILS), (errors.CommandExecutionError(DETAILS), SAME_DETAILS), (errors.InvalidCommandError(DETAILS), SAME_DETAILS), (errors.InvalidCommandParamsError(DETAILS), SAME_DETAILS), (errors.RequestedObjectNotFoundError('type_descr', 'obj_id'), DIFF_CL_DETAILS), (errors.IronicAPIError(DETAILS), SAME_DETAILS), (errors.HeartbeatError(DETAILS), SAME_DETAILS), (errors.LookupNodeError(DETAILS), SAME_DETAILS), (errors.LookupAgentIPError(DETAILS), SAME_DETAILS), (errors.LookupAgentInterfaceError(DETAILS), SAME_DETAILS), (errors.ImageDownloadError('image_id', DETAILS), DIFF_CL_DETAILS), (errors.ImageChecksumError('image_id', '/foo/image_id', 'incorrect', 'correct'), DIFF_CL_DETAILS), (errors.ImageWriteError('device', 'exit_code', 'stdout', 'stderr'), DIFF_CL_DETAILS), (errors.ConfigDriveTooLargeError('filename', 'filesize'), DIFF_CL_DETAILS), (errors.ConfigDriveWriteError('device', 'exit_code', 'stdout', 'stderr'), DIFF_CL_DETAILS), (errors.SystemRebootError('exit_code', 'stdout', 'stderr'), DIFF_CL_DETAILS), (errors.BlockDeviceEraseError(DETAILS), SAME_DETAILS), (errors.BlockDeviceError(DETAILS), SAME_DETAILS), (errors.VirtualMediaBootError(DETAILS), SAME_DETAILS), (errors.UnknownNodeError(), DEFAULT_DETAILS), (errors.UnknownNodeError(DETAILS), SAME_DETAILS), (errors.HardwareManagerNotFound(), DEFAULT_DETAILS), (errors.HardwareManagerNotFound(DETAILS), SAME_DETAILS), (errors.HardwareManagerMethodNotFound('method'), DIFF_CL_DETAILS), (errors.IncompatibleHardwareMethodError(), DEFAULT_DETAILS), (errors.IncompatibleHardwareMethodError(DETAILS), SAME_DETAILS), ] for (obj, check_details) in cases: self._test_class(obj, check_details)
def get_command_result(self, result_id): try: return self.command_results[result_id] except KeyError: raise errors.RequestedObjectNotFoundError('Command Result', result_id)