diff --git a/nova/tests/unit/virt/ironic/test_driver.py b/nova/tests/unit/virt/ironic/test_driver.py index e573a76065a6..a95deef58b38 100644 --- a/nova/tests/unit/virt/ironic/test_driver.py +++ b/nova/tests/unit/virt/ironic/test_driver.py @@ -1060,6 +1060,40 @@ class IronicDriverTestCase(test.NoDBTestCase): mock_cleanup_deploy.assert_called_with(self.ctx, node, instance, None, flavor=flavor) + @mock.patch.object(configdrive, 'required_by') + @mock.patch.object(objects.Instance, 'save') + @mock.patch.object(FAKE_CLIENT, 'node') + @mock.patch.object(ironic_driver.IronicDriver, '_generate_configdrive') + @mock.patch.object(ironic_driver.IronicDriver, '_start_firewall') + @mock.patch.object(ironic_driver.IronicDriver, '_plug_vifs') + @mock.patch.object(ironic_driver.IronicDriver, '_cleanup_deploy') + def test_spawn_node_configdrive_fail(self, mock_cleanup_deploy, + mock_pvifs, mock_sf, mock_configdrive, + mock_node, mock_save, + mock_required_by): + mock_required_by.return_value = True + node_uuid = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' + node = ironic_utils.get_test_node(driver='fake', uuid=node_uuid) + flavor = ironic_utils.get_test_flavor() + instance = fake_instance.fake_instance_obj(self.ctx, node=node_uuid) + instance.flavor = flavor + mock_node.get.return_value = node + mock_node.validate.return_value = ironic_utils.get_test_validation() + image_meta = ironic_utils.get_test_image_meta() + + class TestException(Exception): + pass + + mock_configdrive.side_effect = TestException() + self.assertRaises(TestException, self.driver.spawn, + self.ctx, instance, image_meta, [], None) + + mock_node.get.assert_called_once_with( + node_uuid, fields=ironic_driver._NODE_FIELDS) + mock_node.validate.assert_called_once_with(node_uuid) + mock_cleanup_deploy.assert_called_with(self.ctx, node, instance, None, + flavor=flavor) + @mock.patch.object(configdrive, 'required_by') @mock.patch.object(FAKE_CLIENT, 'node') @mock.patch.object(ironic_driver.IronicDriver, '_start_firewall') diff --git a/nova/virt/ironic/driver.py b/nova/virt/ironic/driver.py index ae47c59d547b..d223e53e1505 100644 --- a/nova/virt/ironic/driver.py +++ b/nova/virt/ironic/driver.py @@ -678,13 +678,8 @@ class IronicDriver(virt_driver.ComputeDriver): content=files, extra_md=extra_md, network_info=network_info) with tempfile.NamedTemporaryFile() as uncompressed: - try: - with configdrive.ConfigDriveBuilder(instance_md=i_meta) as cdb: - cdb.make_drive(uncompressed.name) - except Exception as e: - with excutils.save_and_reraise_exception(): - LOG.error(_LE("Creating config drive failed with " - "error: %s"), e, instance=instance) + with configdrive.ConfigDriveBuilder(instance_md=i_meta) as cdb: + cdb.make_drive(uncompressed.name) with tempfile.NamedTemporaryFile() as compressed: # compress config drive @@ -766,9 +761,17 @@ class IronicDriver(virt_driver.ComputeDriver): if admin_password: extra_md['admin_pass'] = admin_password - configdrive_value = self._generate_configdrive( - instance, node, network_info, extra_md=extra_md, - files=injected_files) + try: + configdrive_value = self._generate_configdrive( + instance, node, network_info, extra_md=extra_md, + files=injected_files) + except Exception as e: + with excutils.save_and_reraise_exception(): + msg = (_LE("Failed to build configdrive: %s") % + six.text_type(e)) + LOG.error(msg, instance=instance) + self._cleanup_deploy(context, node, instance, network_info, + flavor=flavor) LOG.info(_LI("Config drive for instance %(instance)s on " "baremetal node %(node)s created."),