def _update_firmware_sum_final(task, command): """Deploy/Clean step hook after SUM based firmware update operation. This method is invoked as a post deploy/clean step hook by the Ironic conductor once firmware update operaion is completed. The deploy/clean logs are collected and stored according to the configured storage backend when the node is configured to collect the logs. :param task: a TaskManager instance. :param command: A command result structure of the SUM based firmware update operation returned from agent ramdisk on query of the status of command(s). """ if not _should_collect_logs(command): return if task.node.provision_state == states.DEPLOYWAIT: log_data = command['command_result']['deploy_result']['Log Data'] label = command['command_result']['deploy_step']['step'] else: log_data = command['command_result']['clean_result']['Log Data'] label = command['command_result']['clean_step']['step'] node = task.node try: driver_utils.store_ramdisk_logs(node, log_data, label=label) except exception.SwiftOperationError as e: LOG.error( 'Failed to store the logs from the node %(node)s ' 'for "update_firmware_sum" clean step in Swift. ' 'Error: %(error)s', { 'node': node.uuid, 'error': e }) except EnvironmentError as e: LOG.exception( 'Failed to store the logs from the node %(node)s ' 'for "update_firmware_sum" clean step due to a ' 'file-system related error. Error: %(error)s', { 'node': node.uuid, 'error': e }) except Exception as e: LOG.exception( 'Unknown error when storing logs from the node ' '%(node)s for "update_firmware_sum" clean step. ' 'Error: %(error)s', { 'node': node.uuid, 'error': e })
def test_store_ramdisk_logs_local(self, mock_logs_name, mock_makedirs): file_name = 'ironic_test_file.tar.gz' b64str = 'ZW5jb2RlZHN0cmluZw==\n' log_path = '/foo/bar' cfg.CONF.set_override('deploy_logs_local_path', log_path, 'agent') mock_logs_name.return_value = file_name with mock.patch.object(driver_utils, 'open', new=mock.mock_open(), create=True) as mock_open: driver_utils.store_ramdisk_logs(self.node, b64str) expected_path = os.path.join(log_path, file_name) mock_open.assert_called_once_with(expected_path, 'wb') mock_makedirs.assert_called_once_with(log_path) mock_logs_name.assert_called_once_with(self.node, label=None)
def test_store_ramdisk_logs_swift(self, mock_logs_name, mock_swift): container_name = 'ironic_test_container' file_name = 'ironic_test_file.tar.gz' b64str = 'ZW5jb2RlZHN0cmluZw==\n' cfg.CONF.set_override('deploy_logs_storage_backend', 'swift', 'agent') cfg.CONF.set_override( 'deploy_logs_swift_container', container_name, 'agent') cfg.CONF.set_override('deploy_logs_swift_days_to_expire', 1, 'agent') mock_logs_name.return_value = file_name driver_utils.store_ramdisk_logs(self.node, b64str) mock_swift.return_value.create_object.assert_called_once_with( container_name, file_name, mock.ANY, object_headers={'X-Delete-After': '86400'}) mock_logs_name.assert_called_once_with(self.node, label=None)
def test_store_ramdisk_logs_local(self, mock_logs_name, mock_makedirs): file_name = 'ironic_test_file.tar.gz' b64str = 'ZW5jb2RlZHN0cmluZw==\n' log_path = '/foo/bar' cfg.CONF.set_override('deploy_logs_local_path', log_path, 'agent') mock_logs_name.return_value = file_name with mock.patch.object(driver_utils, 'open', new=mock.mock_open(), create=True) as mock_open: driver_utils.store_ramdisk_logs(self.node, b64str) expected_path = os.path.join(log_path, file_name) mock_open.assert_called_once_with(expected_path, 'wb') mock_makedirs.assert_called_once_with(log_path) mock_logs_name.assert_called_once_with(self.node)
def test_store_ramdisk_logs_swift(self, mock_logs_name, mock_swift): container_name = 'ironic_test_container' file_name = 'ironic_test_file.tar.gz' b64str = 'ZW5jb2RlZHN0cmluZw==\n' cfg.CONF.set_override('deploy_logs_storage_backend', 'swift', 'agent') cfg.CONF.set_override( 'deploy_logs_swift_container', container_name, 'agent') cfg.CONF.set_override('deploy_logs_swift_days_to_expire', 1, 'agent') mock_logs_name.return_value = file_name driver_utils.store_ramdisk_logs(self.node, b64str) mock_swift.return_value.create_object.assert_called_once_with( container_name, file_name, mock.ANY, object_headers={'X-Delete-After': '86400'}) mock_logs_name.assert_called_once_with(self.node)