Merge "[ironic] Factor out metadata and send to ironic"

This commit is contained in:
Zuul
2024-08-31 04:42:22 +00:00
committed by Gerrit Code Review
8 changed files with 387 additions and 115 deletions
+96 -17
View File
@@ -1263,6 +1263,8 @@ class IronicDriverTestCase(test.NoDBTestCase):
instance_id=instance.uuid, instance_id=instance.uuid,
fields=ironic_driver._NODE_FIELDS)]) fields=ironic_driver._NODE_FIELDS)])
@mock.patch.object(ironic_driver.IronicDriver,
'get_instance_driver_metadata')
@mock.patch.object(objects.Instance, 'save') @mock.patch.object(objects.Instance, 'save')
@mock.patch.object(loopingcall, 'FixedIntervalLoopingCall') @mock.patch.object(loopingcall, 'FixedIntervalLoopingCall')
@mock.patch.object(ironic_driver.IronicDriver, '_add_volume_target_info') @mock.patch.object(ironic_driver.IronicDriver, '_add_volume_target_info')
@@ -1271,11 +1273,15 @@ class IronicDriverTestCase(test.NoDBTestCase):
'_add_instance_info_to_node') '_add_instance_info_to_node')
def _test_spawn(self, mock_aiitn, mock_wait_active, def _test_spawn(self, mock_aiitn, mock_wait_active,
mock_avti, mock_looping, mock_save, mock_avti, mock_looping, mock_save,
config_drive_value=None): mock_metadata, config_drive_value=None):
node_id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' node_id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
node = _get_cached_node(driver='fake', id=node_id) node = _get_cached_node(driver='fake', id=node_id)
instance = fake_instance.fake_instance_obj(self.ctx, node=node_id) instance = fake_instance.fake_instance_obj(self.ctx, node=node_id)
fake_flavor = objects.Flavor(ephemeral_gb=0) fake_flavor = objects.Flavor(ephemeral_gb=0)
mock_metadata.return_value = (
ironic_utils.get_test_instance_driver_metadata(
flavor_ephemeralgb=0)
)
instance.flavor = fake_flavor instance.flavor = fake_flavor
self.mock_conn.get_node.return_value = node self.mock_conn.get_node.return_value = node
@@ -1295,9 +1301,10 @@ class IronicDriverTestCase(test.NoDBTestCase):
self.mock_conn.validate_node.assert_called_once_with( self.mock_conn.validate_node.assert_called_once_with(
node_id, required=None, node_id, required=None,
) )
mock_aiitn.assert_called_once_with(node, instance, mock_aiitn.assert_called_once_with(
test.MatchType(objects.ImageMeta), node, instance, test.MatchType(objects.ImageMeta),
fake_flavor, block_device_info=None) fake_flavor, test.MatchType(driver.InstanceDriverMetadata),
block_device_info=None)
mock_avti.assert_called_once_with(self.ctx, instance, None) mock_avti.assert_called_once_with(self.ctx, instance, None)
self.mock_conn.set_node_provision_state.assert_called_once_with( self.mock_conn.set_node_provision_state.assert_called_once_with(
node_id, 'active', config_drive=config_drive_value, node_id, 'active', config_drive=config_drive_value,
@@ -1331,6 +1338,8 @@ class IronicDriverTestCase(test.NoDBTestCase):
mock.ANY, extra_md={}, mock.ANY, extra_md={},
files=[]) files=[])
@mock.patch.object(ironic_driver.IronicDriver,
'get_instance_driver_metadata')
@mock.patch.object(configdrive, 'required_by') @mock.patch.object(configdrive, 'required_by')
@mock.patch.object(loopingcall, 'FixedIntervalLoopingCall') @mock.patch.object(loopingcall, 'FixedIntervalLoopingCall')
@mock.patch.object(ironic_driver.IronicDriver, 'destroy') @mock.patch.object(ironic_driver.IronicDriver, 'destroy')
@@ -1341,13 +1350,18 @@ class IronicDriverTestCase(test.NoDBTestCase):
def test_spawn_destroyed_after_failure(self, mock_aiitn, def test_spawn_destroyed_after_failure(self, mock_aiitn,
mock_wait_active, mock_avti, mock_wait_active, mock_avti,
mock_destroy, mock_destroy,
mock_looping, mock_required_by): mock_looping, mock_required_by,
mock_metadata):
mock_required_by.return_value = False mock_required_by.return_value = False
node_uuid = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' node_uuid = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
node = _get_cached_node(driver='fake', id=node_uuid) node = _get_cached_node(driver='fake', id=node_uuid)
fake_flavor = objects.Flavor(ephemeral_gb=0) fake_flavor = objects.Flavor(ephemeral_gb=0)
instance = fake_instance.fake_instance_obj(self.ctx, node=node_uuid) instance = fake_instance.fake_instance_obj(self.ctx, node=node_uuid)
instance.flavor = fake_flavor instance.flavor = fake_flavor
mock_metadata.return_value = (
ironic_utils.get_test_instance_driver_metadata(
flavor_ephemeralgb=0
))
self.mock_conn.get_node.return_value = node self.mock_conn.get_node.return_value = node
self.mock_conn.validate_node.return_value = \ self.mock_conn.validate_node.return_value = \
@@ -1368,6 +1382,7 @@ class IronicDriverTestCase(test.NoDBTestCase):
instance = fake_instance.fake_instance_obj(self.ctx, node=node.id) instance = fake_instance.fake_instance_obj(self.ctx, node=node.id)
image_meta = ironic_utils.get_test_image_meta() image_meta = ironic_utils.get_test_image_meta()
flavor = ironic_utils.get_test_flavor() flavor = ironic_utils.get_test_flavor()
metadata = ironic_utils.get_test_instance_driver_metadata()
instance.flavor = flavor instance.flavor = flavor
expected_patch = [{'path': '/instance_info/image_source', 'op': 'add', expected_patch = [{'path': '/instance_info/image_source', 'op': 'add',
'value': image_meta.id}, 'value': image_meta.id},
@@ -1384,10 +1399,25 @@ class IronicDriverTestCase(test.NoDBTestCase):
{'path': '/instance_info/memory_mb', 'op': 'add', {'path': '/instance_info/memory_mb', 'op': 'add',
'value': str(instance.flavor.memory_mb)}, 'value': str(instance.flavor.memory_mb)},
{'path': '/instance_info/local_gb', 'op': 'add', {'path': '/instance_info/local_gb', 'op': 'add',
'value': str(node.properties.get('local_gb', 0))}] 'value': str(node.properties.get('local_gb', 0))},
{'path': '/instance_info/project_id', 'op': 'add',
'value': 'ppppppp-pppp-pppp-pppp-pppppppppppp'},
{'path': '/instance_info/project_name', 'op': 'add',
'value': 'testproject'},
{'path': '/instance_info/user_id', 'op': 'add',
'value': 'uuuuuuu-uuuu-uuuu-uuuu-uuuuuuuuuuuu'},
{'op': 'add', 'path': '/instance_info/user_name',
'value': 'testuser'},
{'path': '/instance_info/flavor_name',
'op': 'add', 'value': 'fake.flavor'},
{'path': '/instance_info/fixed_ips',
'op': 'add', 'value': '[]'},
{'path': '/instance_info/floating_ips',
'op': 'add', 'value': '[]'},
]
self.driver._add_instance_info_to_node(node, instance, self.driver._add_instance_info_to_node(node, instance,
image_meta, flavor) image_meta, flavor, metadata)
# TODO(dustinc): Add check for call to patcher.create # TODO(dustinc): Add check for call to patcher.create
self.mock_conn.patch_node.assert_called_once_with(node, expected_patch) self.mock_conn.patch_node.assert_called_once_with(node, expected_patch)
@@ -1533,16 +1563,22 @@ class IronicDriverTestCase(test.NoDBTestCase):
] ]
) )
@mock.patch.object(ironic_driver.IronicDriver,
'get_instance_driver_metadata')
@mock.patch.object(configdrive, 'required_by') @mock.patch.object(configdrive, 'required_by')
@mock.patch.object(ironic_driver.IronicDriver, '_add_volume_target_info') @mock.patch.object(ironic_driver.IronicDriver, '_add_volume_target_info')
def test_spawn_node_driver_validation_fail(self, mock_avti, def test_spawn_node_driver_validation_fail(self, mock_avti,
mock_required_by): mock_required_by,
mock_metadata):
mock_required_by.return_value = False mock_required_by.return_value = False
node_id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' node_id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
node = _get_cached_node(driver='fake', id=node_id) node = _get_cached_node(driver='fake', id=node_id)
flavor = ironic_utils.get_test_flavor() flavor = ironic_utils.get_test_flavor()
instance = fake_instance.fake_instance_obj(self.ctx, node=node_id) instance = fake_instance.fake_instance_obj(self.ctx, node=node_id)
instance.flavor = flavor instance.flavor = flavor
mock_metadata.return_value = (
ironic_utils.get_test_instance_driver_metadata()
)
self.mock_conn.validate_node.return_value = \ self.mock_conn.validate_node.return_value = \
ironic_utils.get_test_validation( ironic_utils.get_test_validation(
@@ -1562,20 +1598,23 @@ class IronicDriverTestCase(test.NoDBTestCase):
node_id, required=None, node_id, required=None,
) )
@mock.patch.object(ironic_driver.IronicDriver,
'get_instance_driver_metadata')
@mock.patch.object(configdrive, 'required_by') @mock.patch.object(configdrive, 'required_by')
@mock.patch.object(objects.Instance, 'save') @mock.patch.object(objects.Instance, 'save')
@mock.patch.object(ironic_driver.IronicDriver, '_add_volume_target_info') @mock.patch.object(ironic_driver.IronicDriver, '_add_volume_target_info')
@mock.patch.object(ironic_driver.IronicDriver, '_generate_configdrive') @mock.patch.object(ironic_driver.IronicDriver, '_generate_configdrive')
def test_spawn_node_configdrive_fail(self, def test_spawn_node_configdrive_fail(self, mock_configdrive, mock_avti,
mock_configdrive, mock_save, mock_required_by,
mock_avti, mock_save, mock_metadata):
mock_required_by):
mock_required_by.return_value = True mock_required_by.return_value = True
node_id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' node_id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
node = _get_cached_node(driver='fake', id=node_id) node = _get_cached_node(driver='fake', id=node_id)
flavor = ironic_utils.get_test_flavor() flavor = ironic_utils.get_test_flavor()
instance = fake_instance.fake_instance_obj(self.ctx, node=node_id) instance = fake_instance.fake_instance_obj(self.ctx, node=node_id)
instance.flavor = flavor instance.flavor = flavor
mock_metadata.return_value = (
ironic_utils.get_test_instance_driver_metadata())
self.mock_conn.get_node.return_value = node self.mock_conn.get_node.return_value = node
self.mock_conn.validate_node.return_value = \ self.mock_conn.validate_node.return_value = \
ironic_utils.get_test_validation() ironic_utils.get_test_validation()
@@ -1594,12 +1633,14 @@ class IronicDriverTestCase(test.NoDBTestCase):
) )
mock_cleanup_deploy.assert_called_with(node, instance, None) mock_cleanup_deploy.assert_called_with(node, instance, None)
@mock.patch.object(ironic_driver.IronicDriver,
'get_instance_driver_metadata')
@mock.patch.object(configdrive, 'required_by') @mock.patch.object(configdrive, 'required_by')
@mock.patch.object(ironic_driver.IronicDriver, '_add_volume_target_info') @mock.patch.object(ironic_driver.IronicDriver, '_add_volume_target_info')
@mock.patch.object(ironic_driver.IronicDriver, '_cleanup_deploy') @mock.patch.object(ironic_driver.IronicDriver, '_cleanup_deploy')
def test_spawn_node_trigger_deploy_fail(self, mock_cleanup_deploy, def test_spawn_node_trigger_deploy_fail(self, mock_cleanup_deploy,
mock_avti, mock_avti,
mock_required_by): mock_required_by, mock_metadata):
mock_required_by.return_value = False mock_required_by.return_value = False
node_id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' node_id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
node = _get_cached_node(driver='fake', id=node_id) node = _get_cached_node(driver='fake', id=node_id)
@@ -1607,6 +1648,9 @@ class IronicDriverTestCase(test.NoDBTestCase):
instance = fake_instance.fake_instance_obj(self.ctx, node=node_id) instance = fake_instance.fake_instance_obj(self.ctx, node=node_id)
instance.flavor = flavor instance.flavor = flavor
image_meta = ironic_utils.get_test_image_meta() image_meta = ironic_utils.get_test_image_meta()
mock_metadata.return_value = (
ironic_utils.get_test_instance_driver_metadata()
)
self.mock_conn.get_node.return_value = node self.mock_conn.get_node.return_value = node
self.mock_conn.validate_node.return_value = \ self.mock_conn.validate_node.return_value = \
@@ -1627,6 +1671,8 @@ class IronicDriverTestCase(test.NoDBTestCase):
) )
mock_cleanup_deploy.assert_called_once_with(node, instance, None) mock_cleanup_deploy.assert_called_once_with(node, instance, None)
@mock.patch.object(ironic_driver.IronicDriver,
'get_instance_driver_metadata')
@mock.patch.object(configdrive, 'required_by') @mock.patch.object(configdrive, 'required_by')
@mock.patch.object(loopingcall, 'FixedIntervalLoopingCall') @mock.patch.object(loopingcall, 'FixedIntervalLoopingCall')
@mock.patch.object(objects.Instance, 'save') @mock.patch.object(objects.Instance, 'save')
@@ -1636,12 +1682,18 @@ class IronicDriverTestCase(test.NoDBTestCase):
mock_wait, mock_avti, mock_wait, mock_avti,
mock_save, mock_save,
mock_looping, mock_looping,
mock_required_by): mock_required_by,
mock_metadata):
mock_required_by.return_value = False mock_required_by.return_value = False
node_uuid = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' node_uuid = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
flavor = ironic_utils.get_test_flavor(ephemeral_gb=1) flavor = ironic_utils.get_test_flavor(ephemeral_gb=1)
instance = fake_instance.fake_instance_obj(self.ctx, node=node_uuid) instance = fake_instance.fake_instance_obj(self.ctx, node=node_uuid)
instance.flavor = flavor instance.flavor = flavor
mock_metadata.return_value = (
ironic_utils.get_test_instance_driver_metadata(
flavor_ephemeralgb=1)
)
image_meta = ironic_utils.get_test_image_meta() image_meta = ironic_utils.get_test_image_meta()
self.driver.spawn(self.ctx, instance, image_meta, [], None, {}) self.driver.spawn(self.ctx, instance, image_meta, [], None, {})
@@ -2148,13 +2200,16 @@ class IronicDriverTestCase(test.NoDBTestCase):
'fake_vif') 'fake_vif')
mock_uv.assert_called_once_with('fake_instance', ['fake_vif']) mock_uv.assert_called_once_with('fake_instance', ['fake_vif'])
@mock.patch.object(ironic_driver.IronicDriver,
'get_instance_driver_metadata')
@mock.patch.object(ironic_driver.IronicDriver, '_wait_for_active') @mock.patch.object(ironic_driver.IronicDriver, '_wait_for_active')
@mock.patch.object(loopingcall, 'FixedIntervalLoopingCall') @mock.patch.object(loopingcall, 'FixedIntervalLoopingCall')
@mock.patch.object(ironic_driver.IronicDriver, @mock.patch.object(ironic_driver.IronicDriver,
'_add_instance_info_to_node') '_add_instance_info_to_node')
@mock.patch.object(objects.Instance, 'save') @mock.patch.object(objects.Instance, 'save')
def _test_rebuild(self, mock_save, mock_add_instance_info, def _test_rebuild(self, mock_save, mock_add_instance_info,
mock_looping, mock_wait_active, preserve=False): mock_looping, mock_wait_active, mock_metadata,
preserve=False):
node_uuid = uuidutils.generate_uuid() node_uuid = uuidutils.generate_uuid()
node = _get_cached_node(id=node_uuid, instance_id=self.instance_id) node = _get_cached_node(id=node_uuid, instance_id=self.instance_id)
self.mock_conn.get_node.return_value = node self.mock_conn.get_node.return_value = node
@@ -2165,6 +2220,13 @@ class IronicDriverTestCase(test.NoDBTestCase):
instance = fake_instance.fake_instance_obj( instance = fake_instance.fake_instance_obj(
self.ctx, uuid=self.instance_uuid, node=node_uuid, flavor=flavor) self.ctx, uuid=self.instance_uuid, node=node_uuid, flavor=flavor)
mock_metadata.return_value = (
ironic_utils.get_test_instance_driver_metadata(
flavor_id=5,
flavor_name='baremetal',
instance_uuid=self.instance_uuid,
))
fake_looping_call = FakeLoopingCall() fake_looping_call = FakeLoopingCall()
mock_looping.return_value = fake_looping_call mock_looping.return_value = fake_looping_call
@@ -2179,6 +2241,7 @@ class IronicDriverTestCase(test.NoDBTestCase):
mock_add_instance_info.assert_called_once_with( mock_add_instance_info.assert_called_once_with(
node, instance, node, instance,
test.MatchType(objects.ImageMeta), test.MatchType(objects.ImageMeta),
test.MatchType(driver.InstanceDriverMetadata),
flavor, preserve) flavor, preserve)
self.mock_conn.set_node_provision_state.assert_called_once_with( self.mock_conn.set_node_provision_state.assert_called_once_with(
node_uuid, ironic_states.REBUILD, config_drive=mock.ANY, node_uuid, ironic_states.REBUILD, config_drive=mock.ANY,
@@ -2214,6 +2277,8 @@ class IronicDriverTestCase(test.NoDBTestCase):
mock_configdrive.assert_called_once_with( mock_configdrive.assert_called_once_with(
self.ctx, mock.ANY, mock.ANY, mock.ANY, extra_md={}, files=None) self.ctx, mock.ANY, mock.ANY, mock.ANY, extra_md={}, files=None)
@mock.patch.object(ironic_driver.IronicDriver,
'get_instance_driver_metadata')
@mock.patch.object(ironic_driver.IronicDriver, '_generate_configdrive') @mock.patch.object(ironic_driver.IronicDriver, '_generate_configdrive')
@mock.patch.object(configdrive, 'required_by') @mock.patch.object(configdrive, 'required_by')
@mock.patch.object(ironic_driver.IronicDriver, @mock.patch.object(ironic_driver.IronicDriver,
@@ -2222,13 +2287,18 @@ class IronicDriverTestCase(test.NoDBTestCase):
def test_rebuild_with_configdrive_failure(self, mock_save, def test_rebuild_with_configdrive_failure(self, mock_save,
mock_add_instance_info, mock_add_instance_info,
mock_required_by, mock_required_by,
mock_configdrive): mock_configdrive,
mock_metadata):
node_uuid = uuidutils.generate_uuid() node_uuid = uuidutils.generate_uuid()
node = _get_cached_node( node = _get_cached_node(
id=node_uuid, instance_id=self.instance_uuid) id=node_uuid, instance_id=self.instance_uuid)
self.mock_conn.get_node.return_value = node self.mock_conn.get_node.return_value = node
mock_required_by.return_value = True mock_required_by.return_value = True
mock_configdrive.side_effect = exception.NovaException() mock_configdrive.side_effect = exception.NovaException()
mock_metadata.return_value = (
ironic_utils.get_test_instance_driver_metadata(
flavor_id=5, flavor_name='baremetal')
)
image_meta = ironic_utils.get_test_image_meta() image_meta = ironic_utils.get_test_image_meta()
flavor = objects.Flavor(flavor_id=5, name='baremetal') flavor = objects.Flavor(flavor_id=5, name='baremetal')
@@ -2243,6 +2313,8 @@ class IronicDriverTestCase(test.NoDBTestCase):
bdms=None, detach_block_devices=None, bdms=None, detach_block_devices=None,
attach_block_devices=None) attach_block_devices=None)
@mock.patch.object(ironic_driver.IronicDriver,
'get_instance_driver_metadata')
@mock.patch.object(ironic_driver.IronicDriver, '_generate_configdrive') @mock.patch.object(ironic_driver.IronicDriver, '_generate_configdrive')
@mock.patch.object(configdrive, 'required_by') @mock.patch.object(configdrive, 'required_by')
@mock.patch.object(ironic_driver.IronicDriver, @mock.patch.object(ironic_driver.IronicDriver,
@@ -2250,7 +2322,8 @@ class IronicDriverTestCase(test.NoDBTestCase):
@mock.patch.object(objects.Instance, 'save') @mock.patch.object(objects.Instance, 'save')
def test_rebuild_failures(self, mock_save, def test_rebuild_failures(self, mock_save,
mock_add_instance_info, mock_add_instance_info,
mock_required_by, mock_configdrive): mock_required_by, mock_configdrive,
mock_metadata):
node_uuid = uuidutils.generate_uuid() node_uuid = uuidutils.generate_uuid()
node = _get_cached_node( node = _get_cached_node(
id=node_uuid, instance_id=self.instance_uuid) id=node_uuid, instance_id=self.instance_uuid)
@@ -2259,6 +2332,12 @@ class IronicDriverTestCase(test.NoDBTestCase):
image_meta = ironic_utils.get_test_image_meta() image_meta = ironic_utils.get_test_image_meta()
flavor = objects.Flavor(flavor_id=5, name='baremetal') flavor = objects.Flavor(flavor_id=5, name='baremetal')
mock_metadata.return_value = (
ironic_utils.get_test_instance_driver_metadata(
flavor_id=5,
flavor_name='baremetal',
instance_uuid=self.instance_uuid,
))
instance = fake_instance.fake_instance_obj( instance = fake_instance.fake_instance_obj(
self.ctx, uuid=self.instance_uuid, node=node_uuid, flavor=flavor) self.ctx, uuid=self.instance_uuid, node=node_uuid, flavor=flavor)
+33 -17
View File
@@ -37,6 +37,7 @@ class IronicDriverFieldsTestCase(test.NoDBTestCase):
self.instance = fake_instance.fake_instance_obj(self.ctx) self.instance = fake_instance.fake_instance_obj(self.ctx)
self.instance.flavor = self.flavor self.instance.flavor = self.flavor
self.node = ironic_utils.get_test_node(driver='fake') self.node = ironic_utils.get_test_node(driver='fake')
self.metadata = ironic_utils.get_test_instance_driver_metadata()
# Generic expected patches # Generic expected patches
self._expected_deploy_patch = [ self._expected_deploy_patch = [
{'path': '/instance_info/image_source', {'path': '/instance_info/image_source',
@@ -60,9 +61,24 @@ class IronicDriverFieldsTestCase(test.NoDBTestCase):
{'path': '/instance_info/local_gb', {'path': '/instance_info/local_gb',
'value': str(self.node.properties.get('local_gb', 0)), 'value': str(self.node.properties.get('local_gb', 0)),
'op': 'add'}, 'op': 'add'},
{'path': '/instance_info/nova_host_id', {'op': 'add', 'path': '/instance_info/fixed_ips',
'value': u'fake-host', 'value': '[]'},
'op': 'add'}, {'op': 'add', 'path': '/instance_info/floating_ips',
'value': '[]'},
{'op': 'add', 'path': '/instance_info/flavor_name',
'value': str(self.flavor.name)},
{'op': 'add', 'path': '/instance_info/nova_host_id',
'value': 'fake-host'},
{'op': 'add',
'path': '/instance_info/project_id',
'value': 'ppppppp-pppp-pppp-pppp-pppppppppppp'},
{'op': 'add', 'path': '/instance_info/project_name',
'value': 'testproject'},
{'op': 'add', 'path': '/instance_info/user_name',
'value': 'testuser'},
{'op': 'add',
'path': '/instance_info/user_id',
'value': 'uuuuuuu-uuuu-uuuu-uuuu-uuuuuuuuuuuu'},
] ]
def assertPatchEqual(self, expected, observed): def assertPatchEqual(self, expected, observed):
@@ -79,7 +95,7 @@ class IronicDriverFieldsTestCase(test.NoDBTestCase):
def test_generic_get_deploy_patch(self): def test_generic_get_deploy_patch(self):
node = ironic_utils.get_test_node(driver='fake') node = ironic_utils.get_test_node(driver='fake')
patch = patcher.create(node).get_deploy_patch( patch = patcher.create(node).get_deploy_patch(
self.instance, self.image_meta, self.flavor) self.instance, self.image_meta, self.flavor, self.metadata)
self.assertPatchEqual(self._expected_deploy_patch, patch) self.assertPatchEqual(self._expected_deploy_patch, patch)
def test_generic_get_deploy_patch_capabilities(self): def test_generic_get_deploy_patch_capabilities(self):
@@ -90,7 +106,7 @@ class IronicDriverFieldsTestCase(test.NoDBTestCase):
'op': 'add'}] 'op': 'add'}]
expected += self._expected_deploy_patch expected += self._expected_deploy_patch
patch = patcher.create(node).get_deploy_patch( patch = patcher.create(node).get_deploy_patch(
self.instance, self.image_meta, self.flavor) self.instance, self.image_meta, self.flavor, self.metadata)
self.assertPatchEqual(expected, patch) self.assertPatchEqual(expected, patch)
def test_generic_get_deploy_patch_capabilities_op(self): def test_generic_get_deploy_patch_capabilities_op(self):
@@ -101,7 +117,7 @@ class IronicDriverFieldsTestCase(test.NoDBTestCase):
'op': 'add'}] 'op': 'add'}]
expected += self._expected_deploy_patch expected += self._expected_deploy_patch
patch = patcher.create(node).get_deploy_patch( patch = patcher.create(node).get_deploy_patch(
self.instance, self.image_meta, self.flavor) self.instance, self.image_meta, self.flavor, self.metadata)
self.assertPatchEqual(expected, patch) self.assertPatchEqual(expected, patch)
def test_generic_get_deploy_patch_capabilities_nested_key(self): def test_generic_get_deploy_patch_capabilities_nested_key(self):
@@ -112,7 +128,7 @@ class IronicDriverFieldsTestCase(test.NoDBTestCase):
'op': 'add'}] 'op': 'add'}]
expected += self._expected_deploy_patch expected += self._expected_deploy_patch
patch = patcher.create(node).get_deploy_patch( patch = patcher.create(node).get_deploy_patch(
self.instance, self.image_meta, self.flavor) self.instance, self.image_meta, self.flavor, self.metadata)
self.assertPatchEqual(expected, patch) self.assertPatchEqual(expected, patch)
def test_generic_get_deploy_patch_traits(self): def test_generic_get_deploy_patch_traits(self):
@@ -123,7 +139,7 @@ class IronicDriverFieldsTestCase(test.NoDBTestCase):
'op': 'add'}] 'op': 'add'}]
expected += self._expected_deploy_patch expected += self._expected_deploy_patch
patch = patcher.create(node).get_deploy_patch( patch = patcher.create(node).get_deploy_patch(
self.instance, self.image_meta, self.flavor) self.instance, self.image_meta, self.flavor, self.metadata)
self.assertPatchEqual(expected, patch) self.assertPatchEqual(expected, patch)
def test_generic_get_deploy_patch_traits_granular(self): def test_generic_get_deploy_patch_traits_granular(self):
@@ -134,7 +150,7 @@ class IronicDriverFieldsTestCase(test.NoDBTestCase):
'op': 'add'}] 'op': 'add'}]
expected += self._expected_deploy_patch expected += self._expected_deploy_patch
patch = patcher.create(node).get_deploy_patch( patch = patcher.create(node).get_deploy_patch(
self.instance, self.image_meta, self.flavor) self.instance, self.image_meta, self.flavor, self.metadata)
self.assertPatchEqual(expected, patch) self.assertPatchEqual(expected, patch)
def test_generic_get_deploy_patch_traits_ignores_not_required(self): def test_generic_get_deploy_patch_traits_ignores_not_required(self):
@@ -142,7 +158,7 @@ class IronicDriverFieldsTestCase(test.NoDBTestCase):
self.flavor['extra_specs']['trait:CUSTOM_FOO'] = 'invalid' self.flavor['extra_specs']['trait:CUSTOM_FOO'] = 'invalid'
expected = self._expected_deploy_patch expected = self._expected_deploy_patch
patch = patcher.create(node).get_deploy_patch( patch = patcher.create(node).get_deploy_patch(
self.instance, self.image_meta, self.flavor) self.instance, self.image_meta, self.flavor, self.metadata)
self.assertPatchEqual(expected, patch) self.assertPatchEqual(expected, patch)
def test_generic_get_deploy_patch_image_traits_required(self): def test_generic_get_deploy_patch_image_traits_required(self):
@@ -154,7 +170,7 @@ class IronicDriverFieldsTestCase(test.NoDBTestCase):
'op': 'add'}] 'op': 'add'}]
expected += self._expected_deploy_patch expected += self._expected_deploy_patch
patch = patcher.create(node).get_deploy_patch( patch = patcher.create(node).get_deploy_patch(
self.instance, self.image_meta, self.flavor) self.instance, self.image_meta, self.flavor, self.metadata)
self.assertPatchEqual(expected, patch) self.assertPatchEqual(expected, patch)
def test_generic_get_deploy_patch_image_flavor_traits_required(self): def test_generic_get_deploy_patch_image_flavor_traits_required(self):
@@ -167,7 +183,7 @@ class IronicDriverFieldsTestCase(test.NoDBTestCase):
'op': 'add'}] 'op': 'add'}]
expected += self._expected_deploy_patch expected += self._expected_deploy_patch
patch = patcher.create(node).get_deploy_patch( patch = patcher.create(node).get_deploy_patch(
self.instance, self.image_meta, self.flavor) self.instance, self.image_meta, self.flavor, self.metadata)
self.assertPatchEqual(expected, patch) self.assertPatchEqual(expected, patch)
def test_generic_get_deploy_patch_image_flavor_traits_none(self): def test_generic_get_deploy_patch_image_flavor_traits_none(self):
@@ -175,7 +191,7 @@ class IronicDriverFieldsTestCase(test.NoDBTestCase):
self.image_meta.properties = objects.ImageMetaProps() self.image_meta.properties = objects.ImageMetaProps()
expected = self._expected_deploy_patch expected = self._expected_deploy_patch
patch = patcher.create(node).get_deploy_patch( patch = patcher.create(node).get_deploy_patch(
self.instance, self.image_meta, self.flavor) self.instance, self.image_meta, self.flavor, self.metadata)
self.assertPatchEqual(expected, patch) self.assertPatchEqual(expected, patch)
def test_generic_get_deploy_patch_boot_from_volume_image_traits_required( def test_generic_get_deploy_patch_boot_from_volume_image_traits_required(
@@ -192,7 +208,7 @@ class IronicDriverFieldsTestCase(test.NoDBTestCase):
'op': 'add'}] 'op': 'add'}]
expected += expected_deploy_patch_volume expected += expected_deploy_patch_volume
patch = patcher.create(node).get_deploy_patch( patch = patcher.create(node).get_deploy_patch(
self.instance, self.image_meta, self.flavor, self.instance, self.image_meta, self.flavor, self.metadata,
boot_from_volume=True) boot_from_volume=True)
self.assertPatchEqual(expected, patch) self.assertPatchEqual(expected, patch)
@@ -204,7 +220,7 @@ class IronicDriverFieldsTestCase(test.NoDBTestCase):
flavor=objects.Flavor(root_gb=1, vcpus=1, flavor=objects.Flavor(root_gb=1, vcpus=1,
memory_mb=1, ephemeral_gb=10)) memory_mb=1, ephemeral_gb=10))
patch = patcher.create(node).get_deploy_patch( patch = patcher.create(node).get_deploy_patch(
instance, self.image_meta, self.flavor) instance, self.image_meta, self.flavor, self.metadata)
expected = [{'path': '/instance_info/ephemeral_gb', expected = [{'path': '/instance_info/ephemeral_gb',
'value': str(instance.flavor.ephemeral_gb), 'value': str(instance.flavor.ephemeral_gb),
'op': 'add'}, 'op': 'add'},
@@ -218,7 +234,7 @@ class IronicDriverFieldsTestCase(test.NoDBTestCase):
node = ironic_utils.get_test_node(driver='fake') node = ironic_utils.get_test_node(driver='fake')
for preserve in [True, False]: for preserve in [True, False]:
patch = patcher.create(node).get_deploy_patch( patch = patcher.create(node).get_deploy_patch(
self.instance, self.image_meta, self.flavor, self.instance, self.image_meta, self.flavor, self.metadata,
preserve_ephemeral=preserve) preserve_ephemeral=preserve)
expected = [{'path': '/instance_info/preserve_ephemeral', expected = [{'path': '/instance_info/preserve_ephemeral',
'value': str(preserve), 'op': 'add', }] 'value': str(preserve), 'op': 'add', }]
@@ -230,6 +246,6 @@ class IronicDriverFieldsTestCase(test.NoDBTestCase):
expected = [patch for patch in self._expected_deploy_patch expected = [patch for patch in self._expected_deploy_patch
if patch['path'] != '/instance_info/image_source'] if patch['path'] != '/instance_info/image_source']
patch = patcher.create(node).get_deploy_patch( patch = patcher.create(node).get_deploy_patch(
self.instance, self.image_meta, self.flavor, self.instance, self.image_meta, self.flavor, self.metadata,
boot_from_volume=True) boot_from_volume=True)
self.assertPatchEqual(expected, patch) self.assertPatchEqual(expected, patch)
+63 -12
View File
@@ -19,9 +19,27 @@ from openstack.baremetal.v1 import port_group as _port_group
from openstack.baremetal.v1 import volume_connector as _volume_connector from openstack.baremetal.v1 import volume_connector as _volume_connector
from openstack.baremetal.v1 import volume_target as _volume_target from openstack.baremetal.v1 import volume_target as _volume_target
from nova.network import model as network_model
from nova import objects from nova import objects
from nova.virt import driver
from nova.virt.ironic import ironic_states from nova.virt.ironic import ironic_states
# NOTE(JayF): These exist to make it trivial to unify test data
# between both the driver_metadata generators and the generated
# objects.
TEST_IMAGE_UUID = "cccccccc-cccc-cccc-cccc-cccccccccccc"
TEST_IMAGE_NAME = "test-image"
TEST_FLAVOR_ID = "1"
TEST_FLAVOR_NAME = "fake.flavor"
TEST_FLAVOR_EXTRA_SPECS = {
'baremetal:deploy_kernel_id': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
'baremetal:deploy_ramdisk_id': 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'}
TEST_FLAVOR_SWAP = 1
TEST_FLAVOR_ROOTGB = 1
TEST_FLAVOR_MEMORYMB = 1
TEST_FLAVOR_VCPUS = 1
TEST_FLAVOR_EPHEMERALGB = 0
def get_test_validation(**kw): def get_test_validation(**kw):
result = { result = {
@@ -174,18 +192,15 @@ def get_test_volume_target(**kw):
def get_test_flavor(**kw): def get_test_flavor(**kw):
default_extra_specs = {
'baremetal:deploy_kernel_id': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
'baremetal:deploy_ramdisk_id': 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb',
}
flavor = { flavor = {
'name': kw.get('name', 'fake.flavor'), 'id': kw.get('id', TEST_FLAVOR_ID),
'extra_specs': kw.get('extra_specs', default_extra_specs), 'name': kw.get('name', TEST_FLAVOR_NAME),
'swap': kw.get('swap', 0), 'extra_specs': kw.get('extra_specs', TEST_FLAVOR_EXTRA_SPECS),
'root_gb': 1, 'swap': kw.get('swap', TEST_FLAVOR_SWAP),
'memory_mb': 1, 'root_gb': TEST_FLAVOR_ROOTGB,
'vcpus': 1, 'memory_mb': TEST_FLAVOR_MEMORYMB,
'ephemeral_gb': kw.get('ephemeral_gb', 0), 'vcpus': TEST_FLAVOR_VCPUS,
'ephemeral_gb': kw.get('ephemeral_gb', TEST_FLAVOR_EPHEMERALGB),
} }
return objects.Flavor(**flavor) return objects.Flavor(**flavor)
@@ -193,5 +208,41 @@ def get_test_flavor(**kw):
def get_test_image_meta(**kw): def get_test_image_meta(**kw):
return objects.ImageMeta.from_dict( return objects.ImageMeta.from_dict(
{'id': kw.get('id', 'cccccccc-cccc-cccc-cccc-cccccccccccc')}, {'id': kw.get('id', TEST_IMAGE_UUID)},
)
def get_test_instance_driver_metadata(**kw):
default_instance_meta = driver.NovaInstanceMeta(
name=kw.get('instance_name', 'testinstance'),
uuid=kw.get('instance_uuid', 'iiiiiii-iiii-iiii-iiii-iiiiiiiiiiii'))
default_owner_meta = driver.OwnerMeta(
userid='uuuuuuu-uuuu-uuuu-uuuu-uuuuuuuuuuuu',
username='testuser',
projectid='ppppppp-pppp-pppp-pppp-pppppppppppp',
projectname='testproject')
default_image_meta = driver.ImageMeta(id=TEST_IMAGE_UUID,
name=TEST_IMAGE_NAME,
properties={})
default_flavor_meta = driver.FlavorMeta(
name=kw.get('flavor_name', TEST_FLAVOR_NAME),
memory_mb=kw.get('flavor_memorymb',
TEST_FLAVOR_MEMORYMB),
vcpus=kw.get('flavor_vcpus', TEST_FLAVOR_VCPUS),
root_gb=kw.get('flavor_rootgb',
TEST_FLAVOR_ROOTGB),
ephemeral_gb=kw.get('flavor_ephemeralgb',
TEST_FLAVOR_EPHEMERALGB),
extra_specs=kw.get('flavor_extra_specs',
TEST_FLAVOR_EXTRA_SPECS),
swap=kw.get('flavor_swap', TEST_FLAVOR_SWAP))
return driver.InstanceDriverMetadata(
root_type=kw.get('root_type', 'roottype'),
root_id=kw.get('root_id', 'rootid'),
instance_meta=kw.get('instance_meta', default_instance_meta),
owner=kw.get('owner_meta', default_owner_meta),
image=kw.get('image_meta', default_image_meta),
flavor=kw.get('flavor_meta', default_flavor_meta),
network_info=kw.get('network_info', network_model.NetworkInfo())
) )
+43 -39
View File
@@ -2677,17 +2677,19 @@ class LibvirtConnTestCase(test.NoDBTestCase,
def test_get_guest_config_meta_with_no_port(self): def test_get_guest_config_meta_with_no_port(self):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
meta = drvr._get_guest_config_meta( idm = drvr.get_instance_driver_metadata(
objects.Instance(**self.test_instance), objects.Instance(**self.test_instance),
_fake_network_info(self, num_networks=0)) _fake_network_info(self, num_networks=0))
meta = drvr._get_guest_config_meta(idm)
self.assertEqual(len(meta.ports.ports), 0) self.assertEqual(len(meta.ports.ports), 0)
def test_get_guest_config_meta_with_multiple_ports(self): def test_get_guest_config_meta_with_multiple_ports(self):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
meta = drvr._get_guest_config_meta( idm = drvr.get_instance_driver_metadata(
objects.Instance(**self.test_instance), objects.Instance(**self.test_instance),
_fake_network_info(self, num_networks=2)) _fake_network_info(self, num_networks=2))
meta = drvr._get_guest_config_meta(idm)
self.assertEqual(len(meta.ports.ports), 2) self.assertEqual(len(meta.ports.ports), 2)
@@ -2735,6 +2737,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
user_name="pie", user_name="pie",
) )
flavor = objects.Flavor( flavor = objects.Flavor(
id=1,
name='m1.small', name='m1.small',
memory_mb=6, memory_mb=6,
vcpus=28, vcpus=28,
@@ -2861,6 +2864,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
ephemeral_gb=8128, ephemeral_gb=8128,
swap=33550336, swap=33550336,
extra_specs={}, extra_specs={},
id=42
) )
instance_ref = objects.Instance(**test_instance) instance_ref = objects.Instance(**test_instance)
instance_ref.flavor = flavor instance_ref.flavor = flavor
@@ -3013,13 +3017,10 @@ class LibvirtConnTestCase(test.NoDBTestCase,
user_id=456, user_id=456,
user_name="pie") user_name="pie")
flavor = objects.Flavor(name='m1.small', flavor = objects.Flavor(
memory_mb=6, id=42, name='m1.small', memory_mb=6,
vcpus=28, vcpus=28, root_gb=496, ephemeral_gb=8128,
root_gb=496, swap=33550336, extra_specs={})
ephemeral_gb=8128,
swap=33550336,
extra_specs={})
instance_ref = objects.Instance(**test_instance) instance_ref = objects.Instance(**test_instance)
instance_ref.flavor = flavor instance_ref.flavor = flavor
image_meta = objects.ImageMeta.from_dict(self.test_image_meta) image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
@@ -3192,7 +3193,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta) image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=1, vcpus=2, root_gb=496, flavor = objects.Flavor(memory_mb=1, vcpus=2, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake', ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}) extra_specs={}, id=42)
instance_ref.flavor = flavor instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps() caps = vconfig.LibvirtConfigCaps()
@@ -3226,9 +3227,10 @@ class LibvirtConnTestCase(test.NoDBTestCase,
def test_get_guest_config_numa_host_instance_no_fit(self): def test_get_guest_config_numa_host_instance_no_fit(self):
instance_ref = objects.Instance(**self.test_instance) instance_ref = objects.Instance(**self.test_instance)
image_meta = objects.ImageMeta.from_dict(self.test_image_meta) image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=4096, vcpus=4, root_gb=496, flavor = objects.Flavor(
ephemeral_gb=8128, swap=33550336, name='fake', id=42, memory_mb=4096, vcpus=4, root_gb=496,
extra_specs={}) ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={})
instance_ref.flavor = flavor instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps() caps = vconfig.LibvirtConfigCaps()
@@ -3561,13 +3563,10 @@ class LibvirtConnTestCase(test.NoDBTestCase,
extra_specs = { extra_specs = {
"hw:mem_encryption": True, "hw:mem_encryption": True,
} }
flavor = objects.Flavor(name='m1.small', flavor = objects.Flavor(
memory_mb=6, id=42, name='m1.small', memory_mb=6,
vcpus=28, vcpus=28, root_gb=496, ephemeral_gb=8128,
root_gb=496, swap=33550336, extra_specs=extra_specs)
ephemeral_gb=8128,
swap=33550336,
extra_specs=extra_specs)
instance_ref = objects.Instance(**self.test_instance) instance_ref = objects.Instance(**self.test_instance)
instance_ref.flavor = flavor instance_ref.flavor = flavor
@@ -3659,7 +3658,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta) image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=1, vcpus=2, root_gb=496, flavor = objects.Flavor(memory_mb=1, vcpus=2, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake', ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}) extra_specs={}, id=42)
instance_ref.flavor = flavor instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps() caps = vconfig.LibvirtConfigCaps()
@@ -3712,7 +3711,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta) image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=4096, vcpus=4, root_gb=496, flavor = objects.Flavor(memory_mb=4096, vcpus=4, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake', ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}) extra_specs={}, id=42)
instance_ref.flavor = flavor instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps() caps = vconfig.LibvirtConfigCaps()
@@ -3830,7 +3829,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta) image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=1024, vcpus=2, root_gb=496, flavor = objects.Flavor(memory_mb=1024, vcpus=2, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake', ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}) extra_specs={}, id=42)
instance_ref.flavor = flavor instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps() caps = vconfig.LibvirtConfigCaps()
@@ -3873,7 +3872,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta) image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=2048, vcpus=2, root_gb=496, flavor = objects.Flavor(memory_mb=2048, vcpus=2, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake', ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}) extra_specs={}, id=42)
instance_ref.flavor = flavor instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps() caps = vconfig.LibvirtConfigCaps()
@@ -3926,7 +3925,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta) image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=2048, vcpus=4, root_gb=496, flavor = objects.Flavor(memory_mb=2048, vcpus=4, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake', ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}) extra_specs={}, id=42)
instance_ref.flavor = flavor instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps() caps = vconfig.LibvirtConfigCaps()
@@ -4003,7 +4002,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta) image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=2048, vcpus=4, root_gb=496, flavor = objects.Flavor(memory_mb=2048, vcpus=4, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake', ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}) extra_specs={}, id=42)
instance_ref.flavor = flavor instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps() caps = vconfig.LibvirtConfigCaps()
@@ -4081,7 +4080,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta) image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=2048, vcpus=2, root_gb=496, flavor = objects.Flavor(memory_mb=2048, vcpus=2, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake', ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}) extra_specs={}, id=42)
instance_ref.flavor = flavor instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps() caps = vconfig.LibvirtConfigCaps()
@@ -4170,7 +4169,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta) image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=2048, vcpus=8, root_gb=496, flavor = objects.Flavor(memory_mb=2048, vcpus=8, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake', ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}) extra_specs={}, id=42)
instance_ref.flavor = flavor instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps() caps = vconfig.LibvirtConfigCaps()
@@ -4284,7 +4283,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta) image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=2048, vcpus=8, root_gb=496, flavor = objects.Flavor(memory_mb=2048, vcpus=8, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake', ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}) extra_specs={}, id=42)
instance_ref.flavor = flavor instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps() caps = vconfig.LibvirtConfigCaps()
@@ -4387,7 +4386,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
"hw:cpu_realtime": "yes", "hw:cpu_realtime": "yes",
"hw:cpu_policy": "mixed", "hw:cpu_policy": "mixed",
"hw:cpu_realtime_mask": "^2-3" "hw:cpu_realtime_mask": "^2-3"
}) }, id=42)
instance_ref.flavor = flavor instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps() caps = vconfig.LibvirtConfigCaps()
@@ -4496,7 +4495,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta) image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=2048, vcpus=4, root_gb=496, flavor = objects.Flavor(memory_mb=2048, vcpus=4, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake', ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}) extra_specs={}, id=42)
instance_ref.flavor = flavor instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps() caps = vconfig.LibvirtConfigCaps()
@@ -4580,7 +4579,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
"hw:cpu_realtime": "yes", "hw:cpu_realtime": "yes",
"hw:cpu_policy": "dedicated", "hw:cpu_policy": "dedicated",
"hw:cpu_realtime_mask": "^0-1" "hw:cpu_realtime_mask": "^0-1"
}) }, id=42)
instance_ref.flavor = flavor instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps() caps = vconfig.LibvirtConfigCaps()
@@ -23094,6 +23093,7 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin):
inst = {} inst = {}
inst['id'] = 1 inst['id'] = 1
inst['uuid'] = uuids.fake_instance_id inst['uuid'] = uuids.fake_instance_id
inst['display_name'] = 'fake-instance'
inst['os_type'] = 'linux' inst['os_type'] = 'linux'
inst['image_ref'] = uuids.fake_image_ref inst['image_ref'] = uuids.fake_image_ref
inst['reservation_id'] = 'r-fakeres' inst['reservation_id'] = 'r-fakeres'
@@ -25163,13 +25163,16 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin):
instance, 'get_network_info', return_value=network_info), instance, 'get_network_info', return_value=network_info),
mock.patch.object( mock.patch.object(
self.drvr, '_detach_with_retry'), self.drvr, '_detach_with_retry'),
mock.patch.object(
self.drvr, 'get_instance_driver_metadata'
),
mock.patch.object( mock.patch.object(
self.drvr, '_get_guest_config_meta', return_value=config_meta), self.drvr, '_get_guest_config_meta', return_value=config_meta),
mock.patch.object(guest, 'set_metadata') mock.patch.object(guest, 'set_metadata')
) as ( ) as (
mock_get_guest, mock_get_config, mock_get_network_info, mock_get_guest, mock_get_config, mock_get_network_info,
mock_detach_with_retry, mock_get_guest_config_meta, mock_detach_with_retry, mock_get_instance_driver_metadata,
mock_set_metadata mock_get_guest_config_meta, mock_set_metadata
): ):
self.drvr.detach_interface(self.context, instance, vif) self.drvr.detach_interface(self.context, instance, vif)
mock_get_guest.assert_called_once_with(instance) mock_get_guest.assert_called_once_with(instance)
@@ -25179,8 +25182,9 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin):
mock_detach_with_retry.assert_called_once_with( mock_detach_with_retry.assert_called_once_with(
guest, instance.uuid, mock.ANY, device_name=None) guest, instance.uuid, mock.ANY, device_name=None)
mock_get_network_info.assert_called_once_with() mock_get_network_info.assert_called_once_with()
mock_get_guest_config_meta.assert_called_once_with( mock_get_instance_driver_metadata.assert_called_once_with(
instance, network_info[1:]) instance, network_info[1:])
mock_get_guest_config_meta.assert_called_once()
mock_set_metadata.assert_called_once_with(config_meta) mock_set_metadata.assert_called_once_with(config_meta)
def test__detach_with_retry_persistent_success(self): def test__detach_with_retry_persistent_success(self):
+102 -1
View File
@@ -20,26 +20,78 @@ Driver base-classes:
types that support that contract types that support that contract
""" """
import dataclasses
import itertools import itertools
import sys import sys
import time
import typing as ty import typing as ty
import os_resource_classes as orc import os_resource_classes as orc
import os_traits import os_traits
from oslo_log import log as logging from oslo_log import log as logging
from oslo_utils import importutils from oslo_utils import importutils
import nova.conf import nova.conf
import nova.virt.node
from nova import context as nova_context from nova import context as nova_context
from nova.i18n import _ from nova.i18n import _
from nova.network import model as network_model
from nova import objects from nova import objects
from nova import version
from nova.virt import event as virtevent from nova.virt import event as virtevent
import nova.virt.node
CONF = nova.conf.CONF CONF = nova.conf.CONF
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@dataclasses.dataclass
class FlavorMeta:
name: str
memory_mb: int
vcpus: int
root_gb: int
ephemeral_gb: int
extra_specs: dict
swap: int
@dataclasses.dataclass
class ImageMeta:
id: str
name: str
properties: dict
@dataclasses.dataclass
class NovaInstanceMeta:
name: str
uuid: str
@dataclasses.dataclass
class OwnerMeta:
userid: str
username: str
projectid: str
projectname: str
@dataclasses.dataclass
class InstanceDriverMetadata:
root_type: str
root_id: str
instance_meta: NovaInstanceMeta
owner: OwnerMeta
image: ImageMeta
flavor: FlavorMeta
network_info: network_model.NetworkInfo
nova_package: str = dataclasses.field(
default_factory=version.version_string_with_package)
creation_time: float = dataclasses.field(default_factory=time.time)
def get_block_device_info(instance, block_device_mapping): def get_block_device_info(instance, block_device_mapping):
"""Converts block device mappings for an instance to driver format. """Converts block device mappings for an instance to driver format.
@@ -296,6 +348,55 @@ class ComputeDriver(object):
# TODO(Vek): Need to pass context in for access to auth_token # TODO(Vek): Need to pass context in for access to auth_token
raise NotImplementedError() raise NotImplementedError()
@classmethod
def get_instance_driver_metadata(
cls, instance: 'nova.objects.instance.Instance',
network_info: network_model.NetworkInfo
) -> InstanceDriverMetadata:
"""Get driver metadata from instance and network info
:param instance: nova.objects.instance.Instance
:param network_info: instance network information
:returns: InstanceDriverMetadata
"""
instance_name = instance.display_name or instance.uuid
system_meta = instance.system_metadata
instance_meta = NovaInstanceMeta(
str(instance_name), str(instance.uuid))
owner = OwnerMeta(
userid=instance.user_id,
username=system_meta.get('owner_user_name', 'N/A'),
projectid=instance.project_id,
projectname=system_meta.get('owner_project_name', 'N/A')
)
flavor = FlavorMeta(
name=instance.flavor.name,
memory_mb=instance.flavor.memory_mb,
vcpus=instance.flavor.vcpus,
ephemeral_gb=instance.flavor.ephemeral_gb,
root_gb=instance.flavor.root_gb,
swap=instance.flavor.swap,
extra_specs=instance.flavor.extra_specs,
)
image = ImageMeta(
id=instance.image_ref,
name=system_meta.get('image_name'),
properties=instance.image_meta.properties
)
meta = InstanceDriverMetadata(
instance_meta=instance_meta,
owner=owner,
flavor=flavor,
image=image,
root_type = 'image' if instance.image_ref else 'volume',
root_id = instance.image_ref,
creation_time = time.time(),
network_info=network_info
)
LOG.debug('InstanceDriverMetadata: %s', meta)
return meta
def get_num_instances(self): def get_num_instances(self):
"""Return the total number of virtual machines. """Return the total number of virtual machines.
+7 -3
View File
@@ -405,7 +405,7 @@ class IronicDriver(virt_driver.ComputeDriver):
self._cleanup_deploy(node, instance) self._cleanup_deploy(node, instance)
def _add_instance_info_to_node(self, node, instance, image_meta, flavor, def _add_instance_info_to_node(self, node, instance, image_meta, flavor,
preserve_ephemeral=None, metadata, preserve_ephemeral=None,
block_device_info=None): block_device_info=None):
root_bdm = block_device.get_root_bdm( root_bdm = block_device.get_root_bdm(
@@ -414,6 +414,7 @@ class IronicDriver(virt_driver.ComputeDriver):
patch = patcher.create(node).get_deploy_patch(instance, patch = patcher.create(node).get_deploy_patch(instance,
image_meta, image_meta,
flavor, flavor,
metadata,
preserve_ephemeral, preserve_ephemeral,
boot_from_volume) boot_from_volume)
@@ -1158,7 +1159,7 @@ class IronicDriver(virt_driver.ComputeDriver):
:param network_info: Instance network information. :param network_info: Instance network information.
:param block_device_info: Instance block device :param block_device_info: Instance block device
information. information.
:param arqs: Accelerator requests for this instance. :param accel_info: Accelerator requests for this instance.
:param power_on: True if the instance should be powered on, False :param power_on: True if the instance should be powered on, False
otherwise otherwise
""" """
@@ -1176,7 +1177,9 @@ class IronicDriver(virt_driver.ComputeDriver):
node = self._get_node(node_id) node = self._get_node(node_id)
flavor = instance.flavor flavor = instance.flavor
metadata = self.get_instance_driver_metadata(instance, network_info)
self._add_instance_info_to_node(node, instance, image_meta, flavor, self._add_instance_info_to_node(node, instance, image_meta, flavor,
metadata,
block_device_info=block_device_info) block_device_info=block_device_info)
try: try:
@@ -1740,7 +1743,8 @@ class IronicDriver(virt_driver.ComputeDriver):
node_id = instance.node node_id = instance.node
node = self._get_node(node_id) node = self._get_node(node_id)
self._add_instance_info_to_node(node, instance, image_meta, metadata = self.get_instance_driver_metadata(instance, network_info)
self._add_instance_info_to_node(node, instance, image_meta, metadata,
instance.flavor, preserve_ephemeral) instance.flavor, preserve_ephemeral)
# Config drive # Config drive
+17 -1
View File
@@ -40,13 +40,14 @@ class GenericDriverFields(object):
def __init__(self, node): def __init__(self, node):
self.node = node self.node = node
def get_deploy_patch(self, instance, image_meta, flavor, def get_deploy_patch(self, instance, image_meta, flavor, metadata,
preserve_ephemeral=None, boot_from_volume=False): preserve_ephemeral=None, boot_from_volume=False):
"""Build a patch to add the required fields to deploy a node. """Build a patch to add the required fields to deploy a node.
:param instance: the instance object. :param instance: the instance object.
:param image_meta: the nova.objects.ImageMeta object instance :param image_meta: the nova.objects.ImageMeta object instance
:param flavor: the flavor object. :param flavor: the flavor object.
:param metadata: nova.virt.driver.InstanceDriverMetadata dataclass
:param preserve_ephemeral: preserve_ephemeral status (bool) to be :param preserve_ephemeral: preserve_ephemeral status (bool) to be
specified during rebuild. specified during rebuild.
:param boot_from_volume: True if node boots from volume. Then, :param boot_from_volume: True if node boots from volume. Then,
@@ -73,6 +74,21 @@ class GenericDriverFields(object):
patch.append({'path': '/instance_info/local_gb', 'op': 'add', patch.append({'path': '/instance_info/local_gb', 'op': 'add',
'value': str(self.node.properties.get('local_gb', 0))}) 'value': str(self.node.properties.get('local_gb', 0))})
patch.append({'path': '/instance_info/project_id', 'op': 'add',
'value': str(metadata.owner.projectid)})
patch.append({'path': '/instance_info/project_name', 'op': 'add',
'value': str(metadata.owner.projectname)})
patch.append({'path': '/instance_info/user_id', 'op': 'add',
'value': str(metadata.owner.userid)})
patch.append({'path': '/instance_info/user_name', 'op': 'add',
'value': str(metadata.owner.username)})
patch.append({'path': '/instance_info/flavor_name', 'op': 'add',
'value': str(metadata.flavor.name)})
patch.append({'path': '/instance_info/fixed_ips', 'op': 'add',
'value': str(metadata.network_info.fixed_ips())})
patch.append({'path': '/instance_info/floating_ips', 'op': 'add',
'value': str(metadata.network_info.floating_ips())})
if instance.flavor.ephemeral_gb: if instance.flavor.ephemeral_gb:
patch.append({'path': '/instance_info/ephemeral_gb', patch.append({'path': '/instance_info/ephemeral_gb',
'op': 'add', 'op': 'add',
+26 -25
View File
@@ -3083,7 +3083,8 @@ class LibvirtDriver(driver.ComputeDriver):
try: try:
guest.set_metadata( guest.set_metadata(
self._get_guest_config_meta( self._get_guest_config_meta(
instance, instance.get_network_info())) self.get_instance_driver_metadata(
instance, instance.get_network_info())))
except libvirt.libvirtError: except libvirt.libvirtError:
LOG.warning('updating libvirt metadata failed.', instance=instance) LOG.warning('updating libvirt metadata failed.', instance=instance)
@@ -3122,7 +3123,9 @@ class LibvirtDriver(driver.ComputeDriver):
network_info = list(filter(lambda info: info['id'] != vif['id'], network_info = list(filter(lambda info: info['id'] != vif['id'],
instance.get_network_info())) instance.get_network_info()))
guest.set_metadata( guest.set_metadata(
self._get_guest_config_meta(instance, network_info)) self._get_guest_config_meta(
self.get_instance_driver_metadata(
instance, network_info)))
except libvirt.libvirtError: except libvirt.libvirtError:
LOG.warning('updating libvirt metadata failed.', instance=instance) LOG.warning('updating libvirt metadata failed.', instance=instance)
@@ -6104,39 +6107,35 @@ class LibvirtDriver(driver.ComputeDriver):
return dev return dev
def _get_guest_config_meta(self, instance, network_info): def _get_guest_config_meta(self, dmeta: driver.InstanceDriverMetadata):
"""Get metadata config for guest.""" """Get metadata config for guest."""
meta = vconfig.LibvirtConfigGuestMetaNovaInstance() meta = vconfig.LibvirtConfigGuestMetaNovaInstance()
meta.package = version.version_string_with_package() meta.package = dmeta.nova_package
meta.name = instance.display_name meta.name = dmeta.instance_meta.name
meta.creationTime = time.time() meta.creationTime = dmeta.creation_time
meta.roottype = dmeta.root_type
meta.rootid = dmeta.root_id
if instance.image_ref not in ("", None):
meta.roottype = "image"
meta.rootid = instance.image_ref
system_meta = instance.system_metadata
ometa = vconfig.LibvirtConfigGuestMetaNovaOwner() ometa = vconfig.LibvirtConfigGuestMetaNovaOwner()
ometa.userid = instance.user_id ometa.userid = dmeta.owner.userid
ometa.username = system_meta.get('owner_user_name', 'N/A') ometa.username = dmeta.owner.username
ometa.projectid = instance.project_id ometa.projectid = dmeta.owner.projectid
ometa.projectname = system_meta.get('owner_project_name', 'N/A') ometa.projectname = dmeta.owner.projectname
meta.owner = ometa meta.owner = ometa
fmeta = vconfig.LibvirtConfigGuestMetaNovaFlavor() fmeta = vconfig.LibvirtConfigGuestMetaNovaFlavor()
flavor = instance.flavor fmeta.name = dmeta.flavor.name
fmeta.name = flavor.name fmeta.memory = dmeta.flavor.memory_mb
fmeta.memory = flavor.memory_mb fmeta.vcpus = dmeta.flavor.vcpus
fmeta.vcpus = flavor.vcpus fmeta.ephemeral = dmeta.flavor.ephemeral_gb
fmeta.ephemeral = flavor.ephemeral_gb fmeta.disk = dmeta.flavor.root_gb
fmeta.disk = flavor.root_gb fmeta.swap = dmeta.flavor.swap
fmeta.swap = flavor.swap
meta.flavor = fmeta meta.flavor = fmeta
ports = [] ports = []
for vif in network_info: for vif in dmeta.network_info:
ips = [] ips = []
for subnet in vif.get('network', {}).get('subnets', []): for subnet in vif.get('network', {}).get('subnets', []):
for ip in subnet.get('ips', []): for ip in subnet.get('ips', []):
@@ -7384,8 +7383,10 @@ class LibvirtDriver(driver.ComputeDriver):
guest_numa_config.numatune, guest_numa_config.numatune,
flavor, image_meta) flavor, image_meta)
guest.metadata.append(self._get_guest_config_meta( guest.metadata.append(
instance, network_info)) self._get_guest_config_meta(
self.get_instance_driver_metadata(
instance, network_info)))
guest.idmaps = self._get_guest_idmaps() guest.idmaps = self._get_guest_idmaps()
for event in self._supported_perf_events: for event in self._supported_perf_events: