Merge "Add more flavor metadata to libvirt guest XML"

This commit is contained in:
Zuul
2025-08-09 08:31:50 +00:00
committed by Gerrit Code Review
7 changed files with 197 additions and 18 deletions

View File

@@ -31,6 +31,7 @@ TEST_IMAGE_UUID = "cccccccc-cccc-cccc-cccc-cccccccccccc"
TEST_IMAGE_NAME = "test-image"
TEST_FLAVOR_ID = 1
TEST_FLAVOR_NAME = "fake.flavor"
TEST_FLAVOR_FLAVORID = "iiiiiiii-iiii-iiii-iiii-iiiiiiiiiiii"
TEST_FLAVOR_EXTRA_SPECS = {
'baremetal:deploy_kernel_id': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
'baremetal:deploy_ramdisk_id': 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'}
@@ -226,6 +227,8 @@ def get_test_instance_driver_metadata(**kw):
properties={})
default_flavor_meta = driver.FlavorMeta(
name=kw.get('flavor_name', TEST_FLAVOR_NAME),
flavorid=kw.get('flavor_flavorid',
TEST_FLAVOR_FLAVORID),
memory_mb=kw.get('flavor_memorymb',
TEST_FLAVOR_MEMORYMB),
vcpus=kw.get('flavor_vcpus', TEST_FLAVOR_VCPUS),

View File

@@ -4117,6 +4117,7 @@ class LibvirtConfigGuestMetadataNovaTest(LibvirtConfigBaseTest):
flavor = config.LibvirtConfigGuestMetaNovaFlavor()
flavor.name = "m1.lowgravity"
flavor.id = "f719a0dd-4b43-4efe-8336-48ef74099ad4"
flavor.vcpus = 8
flavor.memory = 2048
flavor.swap = 10
@@ -4152,12 +4153,102 @@ class LibvirtConfigGuestMetadataNovaTest(LibvirtConfigBaseTest):
<nova:package version="2014.2.3"/>
<nova:name>moonbuggy</nova:name>
<nova:creationTime>2009-02-13 23:31:30</nova:creationTime>
<nova:flavor name="m1.lowgravity">
<nova:flavor name="m1.lowgravity"
id="f719a0dd-4b43-4efe-8336-48ef74099ad4">
<nova:memory>2048</nova:memory>
<nova:disk>50</nova:disk>
<nova:swap>10</nova:swap>
<nova:ephemeral>10</nova:ephemeral>
<nova:vcpus>8</nova:vcpus>
<nova:extraSpecs></nova:extraSpecs>
</nova:flavor>
<nova:owner>
<nova:user
uuid="3472c2a6-de91-4fb5-b618-42bc781ef670">buzz</nova:user>
<nova:project
uuid="f241e906-010e-4917-ae81-53f4fb8aa021">moonshot</nova:project>
</nova:owner>
<nova:root type="image" uuid="fe55c69a-8b2e-4bbc-811a-9ad2023a0426"/>
<nova:ports>
<nova:port uuid="567a4527-b0e4-4d0a-bcc2-71fda37897f7">
<nova:ip type="fixed" address="192.168.1.1" ipVersion="4"/>
<nova:ip type="fixed" address="fe80::f95c:b030:7094" ipVersion="6"/>
<nova:ip type="floating" address="11.22.33.44" ipVersion="4"/>
</nova:port>
<nova:port uuid="a3ca97e2-0cf9-4159-9bfc-afd55bc13ead">
<nova:ip type="fixed" address="10.0.0.1" ipVersion="4"/>
<nova:ip type="fixed" address="fdf8:f53b:82e4::52" ipVersion="6"/>
<nova:ip type="floating" address="1.2.3.4" ipVersion="4"/>
</nova:port>
</nova:ports>
</nova:instance>
""")
def test_config_metadata_flavor_extra_specs(self):
meta = config.LibvirtConfigGuestMetaNovaInstance()
meta.package = "2014.2.3"
meta.name = "moonbuggy"
meta.creationTime = 1234567890
meta.roottype = "image"
meta.rootid = "fe55c69a-8b2e-4bbc-811a-9ad2023a0426"
owner = config.LibvirtConfigGuestMetaNovaOwner()
owner.userid = "3472c2a6-de91-4fb5-b618-42bc781ef670"
owner.username = "buzz"
owner.projectid = "f241e906-010e-4917-ae81-53f4fb8aa021"
owner.projectname = "moonshot"
meta.owner = owner
flavor = config.LibvirtConfigGuestMetaNovaFlavor()
flavor.name = "m1.lowgravity"
flavor.id = "f719a0dd-4b43-4efe-8336-48ef74099ad4"
flavor.vcpus = 8
flavor.memory = 2048
flavor.swap = 10
flavor.disk = 50
flavor.ephemeral = 10
flavor.extra_specs = {"hw_rng:allowed": "true"}
meta.flavor = flavor
meta.ports = config.LibvirtConfigGuestMetaNovaPorts(
ports=[
config.LibvirtConfigGuestMetaNovaPort(
'567a4527-b0e4-4d0a-bcc2-71fda37897f7',
ips=[
config.LibvirtConfigGuestMetaNovaIp(
'fixed', '192.168.1.1', '4'),
config.LibvirtConfigGuestMetaNovaIp(
'fixed', 'fe80::f95c:b030:7094', '6'),
config.LibvirtConfigGuestMetaNovaIp(
'floating', '11.22.33.44', '4')]),
config.LibvirtConfigGuestMetaNovaPort(
'a3ca97e2-0cf9-4159-9bfc-afd55bc13ead',
ips=[
config.LibvirtConfigGuestMetaNovaIp(
'fixed', '10.0.0.1', '4'),
config.LibvirtConfigGuestMetaNovaIp(
'fixed', 'fdf8:f53b:82e4::52', '6'),
config.LibvirtConfigGuestMetaNovaIp(
'floating', '1.2.3.4', '4')])])
xml = meta.to_xml()
self.assertXmlEqual(xml, """
<nova:instance xmlns:nova='http://openstack.org/xmlns/libvirt/nova/1.1'>
<nova:package version="2014.2.3"/>
<nova:name>moonbuggy</nova:name>
<nova:creationTime>2009-02-13 23:31:30</nova:creationTime>
<nova:flavor name="m1.lowgravity"
id="f719a0dd-4b43-4efe-8336-48ef74099ad4">
<nova:memory>2048</nova:memory>
<nova:disk>50</nova:disk>
<nova:swap>10</nova:swap>
<nova:ephemeral>10</nova:ephemeral>
<nova:vcpus>8</nova:vcpus>
<nova:extraSpecs>
<nova:extraSpec name="hw_rng:allowed">true</nova:extraSpec>
</nova:extraSpecs>
</nova:flavor>
<nova:owner>
<nova:user

View File

@@ -2969,6 +2969,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
flavor = objects.Flavor(
id=1,
name='m1.small',
flavorid='6a523f6f-5ede-4a3a-938b-1c3a5d665771',
memory_mb=6,
vcpus=28,
root_gb=496,
@@ -3045,11 +3046,14 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertIsInstance(
cfg.metadata[0].flavor, vconfig.LibvirtConfigGuestMetaNovaFlavor)
self.assertEqual("m1.small", cfg.metadata[0].flavor.name)
self.assertEqual("6a523f6f-5ede-4a3a-938b-1c3a5d665771",
cfg.metadata[0].flavor.id)
self.assertEqual(6, cfg.metadata[0].flavor.memory)
self.assertEqual(28, cfg.metadata[0].flavor.vcpus)
self.assertEqual(496, cfg.metadata[0].flavor.disk)
self.assertEqual(8128, cfg.metadata[0].flavor.ephemeral)
self.assertEqual(33550336, cfg.metadata[0].flavor.swap)
self.assertEqual({}, cfg.metadata[0].flavor.extra_specs)
num_ports = 0
for device in cfg.devices:
@@ -3094,7 +3098,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
ephemeral_gb=8128,
swap=33550336,
extra_specs={},
id=42
id=42,
flavorid='someflavor',
)
instance_ref = objects.Instance(**test_instance)
instance_ref.flavor = flavor
@@ -3250,7 +3255,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
flavor = objects.Flavor(
id=42, name='m1.small', memory_mb=6,
vcpus=28, root_gb=496, ephemeral_gb=8128,
swap=33550336, extra_specs={})
swap=33550336, extra_specs={}, flavorid='someflavor')
instance_ref = objects.Instance(**test_instance)
instance_ref.flavor = flavor
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
@@ -3423,7 +3428,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=1, vcpus=2, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}, id=42)
extra_specs={}, id=42, flavorid='someflavor')
instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps()
@@ -3460,7 +3465,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
flavor = objects.Flavor(
id=42, memory_mb=4096, vcpus=4, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={})
extra_specs={}, flavorid='someflavor')
instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps()
@@ -3488,6 +3493,42 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertIsNone(cfg.cputune)
self.assertIsNone(cfg.cpu.numa)
def test_get_guest_config_flavor_extra_specs(self):
flavor = objects.Flavor(name='m1.small',
flavorid=(
'6a523f6f-5ede-4a3a-938b-1c3a5d665771'),
memory_mb=6,
vcpus=28,
root_gb=496,
ephemeral_gb=8128,
swap=33550336,
extra_specs={"hw_rng:allowed": "true"})
instance_ref = objects.Instance(**self.test_instance)
instance_ref.flavor = flavor
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
cfg = drvr._get_guest_config(instance_ref,
_fake_network_info(self, 1),
image_meta, {'mapping': {}})
self.assertIsInstance(cfg.metadata[0].flavor,
vconfig.LibvirtConfigGuestMetaNovaFlavor)
self.assertEqual("m1.small",
cfg.metadata[0].flavor.name)
self.assertEqual("6a523f6f-5ede-4a3a-938b-1c3a5d665771",
cfg.metadata[0].flavor.id)
self.assertEqual(6,
cfg.metadata[0].flavor.memory)
self.assertEqual(28,
cfg.metadata[0].flavor.vcpus)
self.assertEqual(496,
cfg.metadata[0].flavor.disk)
self.assertEqual(8128,
cfg.metadata[0].flavor.ephemeral)
self.assertEqual(33550336,
cfg.metadata[0].flavor.swap)
self.assertEqual({"hw_rng:allowed": "true"},
cfg.metadata[0].flavor.extra_specs)
def _test_get_guest_memory_backing_config(
self, host_topology, inst_topology, numatune):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
@@ -3796,7 +3837,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
flavor = objects.Flavor(
id=42, name='m1.small', memory_mb=6,
vcpus=28, root_gb=496, ephemeral_gb=8128,
swap=33550336, extra_specs=extra_specs)
swap=33550336, extra_specs=extra_specs, flavorid='someflavor')
instance_ref = objects.Instance(**self.test_instance)
instance_ref.flavor = flavor
@@ -3898,7 +3939,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=1, vcpus=2, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}, id=42)
extra_specs={}, id=42, flavorid='someflavor')
instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps()
@@ -3951,7 +3992,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=4096, vcpus=4, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}, id=42)
extra_specs={}, id=42, flavorid='someflavor')
instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps()
@@ -4069,7 +4110,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=1024, vcpus=2, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}, id=42)
extra_specs={}, id=42, flavorid='someflavor')
instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps()
@@ -4112,7 +4153,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=2048, vcpus=2, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}, id=42)
extra_specs={}, id=42, flavorid='someflavor')
instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps()
@@ -4165,7 +4206,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=2048, vcpus=4, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}, id=42)
extra_specs={}, id=42, flavorid='someflavor')
instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps()
@@ -4242,7 +4283,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=2048, vcpus=4, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}, id=42)
extra_specs={}, id=42, flavorid='someflavor')
instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps()
@@ -4320,7 +4361,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=2048, vcpus=2, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}, id=42)
extra_specs={}, id=42, flavorid='someflavor')
instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps()
@@ -4409,7 +4450,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=2048, vcpus=8, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}, id=42)
extra_specs={}, id=42, flavorid='someflavor')
instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps()
@@ -4523,7 +4564,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=2048, vcpus=8, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}, id=42)
extra_specs={}, id=42, flavorid='someflavor')
instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps()
@@ -4626,7 +4667,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
"hw:cpu_realtime": "yes",
"hw:cpu_policy": "mixed",
"hw:cpu_realtime_mask": "^2-3"
}, id=42)
}, id=42, flavorid='someflavor')
instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps()
@@ -4735,7 +4776,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
flavor = objects.Flavor(memory_mb=2048, vcpus=4, root_gb=496,
ephemeral_gb=8128, swap=33550336, name='fake',
extra_specs={}, id=42)
extra_specs={}, id=42, flavorid='someflavor')
instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps()
@@ -4819,7 +4860,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
"hw:cpu_realtime": "yes",
"hw:cpu_policy": "dedicated",
"hw:cpu_realtime_mask": "^0-1"
}, id=42)
}, id=42, flavorid='someflavor')
instance_ref.flavor = flavor
caps = vconfig.LibvirtConfigCaps()

View File

@@ -49,6 +49,7 @@ LOG = logging.getLogger(__name__)
@dataclasses.dataclass
class FlavorMeta:
name: str
flavorid: str
memory_mb: int
vcpus: int
root_gb: int
@@ -376,6 +377,7 @@ class ComputeDriver(object):
)
flavor = FlavorMeta(
name=instance.flavor.name,
flavorid=instance.flavor.flavorid,
memory_mb=instance.flavor.memory_mb,
vcpus=instance.flavor.vcpus,
ephemeral_gb=instance.flavor.ephemeral_gb,

View File

@@ -3804,15 +3804,18 @@ class LibvirtConfigGuestMetaNovaFlavor(LibvirtConfigObject):
ns_uri=NOVA_NS)
self.name = None
self.id = None
self.memory = None
self.disk = None
self.swap = None
self.ephemeral = None
self.vcpus = None
self.extra_specs = None
def format_dom(self):
meta = super(LibvirtConfigGuestMetaNovaFlavor, self).format_dom()
meta.set("name", self.name)
meta.set("id", self.id)
if self.memory is not None:
meta.append(self._text_node("memory", str(self.memory)))
if self.disk is not None:
@@ -3823,6 +3826,28 @@ class LibvirtConfigGuestMetaNovaFlavor(LibvirtConfigObject):
meta.append(self._text_node("ephemeral", str(self.ephemeral)))
if self.vcpus is not None:
meta.append(self._text_node("vcpus", str(self.vcpus)))
extra_specs_meta = LibvirtConfigGuestMetaNovaFlavorExtraSpecs()
if self.extra_specs is not None:
extra_specs_meta.extra_specs = self.extra_specs
meta.append(extra_specs_meta.format_dom())
return meta
class LibvirtConfigGuestMetaNovaFlavorExtraSpecs(LibvirtConfigObject):
def __init__(self):
super().__init__(root_name="extraSpecs",
ns_prefix="nova",
ns_uri=NOVA_NS)
self.extra_specs = None
def format_dom(self):
meta = super().format_dom()
if self.extra_specs is not None:
for key, value in self.extra_specs.items():
node = self._text_node("extraSpec", value)
node.set("name", key)
meta.append(node)
return meta

View File

@@ -6250,11 +6250,13 @@ class LibvirtDriver(driver.ComputeDriver):
fmeta = vconfig.LibvirtConfigGuestMetaNovaFlavor()
fmeta.name = dmeta.flavor.name
fmeta.id = dmeta.flavor.flavorid
fmeta.memory = dmeta.flavor.memory_mb
fmeta.vcpus = dmeta.flavor.vcpus
fmeta.ephemeral = dmeta.flavor.ephemeral_gb
fmeta.disk = dmeta.flavor.root_gb
fmeta.swap = dmeta.flavor.swap
fmeta.extra_specs = dmeta.flavor.extra_specs
meta.flavor = fmeta

View File

@@ -0,0 +1,15 @@
---
features:
- |
Additional information regarding an instance's flavor (the ID
and the defined extra specs at the time the instance was launched)
has been added to the libvirt domain metadata for instances.
This allows downstream clients that queries libvirt domain metadata,
such as Ceilometer, to avoid performing additional Nova API queries
to get this information.
upgrades:
- |
To expose the newly added attributes in the libvirt domain metadata
in an upgraded environment, already running instances will need to
be shutdown, restarted, cold migrated or shelved and unshelved.