vmware:add support for the hw_video_ram image property
Added create of a video card config spec and validation check if the image meta video ram("hw_video_ram") is bigger than the maximum allowed "hw_video:ram_max_mb" from the flavor. Change-Id: I944d7e9235790cb2a4a21318c029d51012d157b0
This commit is contained in:
parent
3b77a1825c
commit
38aa83b7fc
@ -300,11 +300,15 @@ Hardware video RAM
|
|||||||
image. Used in conjunction with the ``hw_video_ram`` image property.
|
image. Used in conjunction with the ``hw_video_ram`` image property.
|
||||||
``hw_video_ram`` must be less than or equal to ``hw_video:ram_max_mb``.
|
``hw_video_ram`` must be less than or equal to ``hw_video:ram_max_mb``.
|
||||||
|
|
||||||
This is currently only supported by the libvirt driver.
|
This is currently supported by the libvirt and the vmware drivers.
|
||||||
|
|
||||||
See https://libvirt.org/formatdomain.html#elementsVideo for more information
|
See https://libvirt.org/formatdomain.html#elementsVideo for more information
|
||||||
on how this is used to set the ``vram`` attribute with the libvirt driver.
|
on how this is used to set the ``vram`` attribute with the libvirt driver.
|
||||||
|
|
||||||
|
See https://pubs.vmware.com/vi-sdk/visdk250/ReferenceGuide/vim.vm.device.VirtualVideoCard.html
|
||||||
|
for more information on how this is used to set the ``videoRamSizeInKB`` attribute with
|
||||||
|
the vmware driver.
|
||||||
|
|
||||||
Watchdog behavior
|
Watchdog behavior
|
||||||
For the libvirt driver, you can enable and set the behavior of a virtual
|
For the libvirt driver, you can enable and set the behavior of a virtual
|
||||||
hardware watchdog device for each flavor. Watchdog devices keep an eye on the
|
hardware watchdog device for each flavor. Watchdog devices keep an eye on the
|
||||||
|
@ -2192,6 +2192,104 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
|||||||
flavor_extra_specs = self._vmops._get_extra_specs(flavor, None)
|
flavor_extra_specs = self._vmops._get_extra_specs(flavor, None)
|
||||||
self._validate_extra_specs(expected, flavor_extra_specs)
|
self._validate_extra_specs(expected, flavor_extra_specs)
|
||||||
|
|
||||||
|
"""
|
||||||
|
The test covers the negative failure scenario, where `hw_video_ram`,
|
||||||
|
coming from the image is bigger than the maximum allowed video ram from
|
||||||
|
the flavor.
|
||||||
|
"""
|
||||||
|
def test_video_ram(self):
|
||||||
|
meta_dict = {'id': self._image_id, 'properties': {'hw_video_ram': 120}}
|
||||||
|
image_meta, flavor = self._get_image_and_flavor_for_test_video(
|
||||||
|
meta_dict)
|
||||||
|
|
||||||
|
self.assertRaises(exception.RequestedVRamTooHigh,
|
||||||
|
self._vmops._get_extra_specs,
|
||||||
|
flavor,
|
||||||
|
image_meta)
|
||||||
|
|
||||||
|
"""
|
||||||
|
Testing VM provisioning result in the case where `hw_video_ram`,
|
||||||
|
coming from the image is not specified. This is a success scenario,
|
||||||
|
in the case where `hw_video_ram` property is not set.
|
||||||
|
"""
|
||||||
|
def test_video_ram_if_none(self):
|
||||||
|
meta_dict = {'id': self._image_id, 'properties': {}}
|
||||||
|
image_meta, flavor = self._get_image_and_flavor_for_test_video(
|
||||||
|
meta_dict)
|
||||||
|
|
||||||
|
extra_specs = self._vmops._get_extra_specs(flavor, image_meta)
|
||||||
|
self.assertIsNone(extra_specs.hw_video_ram)
|
||||||
|
|
||||||
|
"""
|
||||||
|
Testing VM provisioning result in the case where `hw_video:ram_max_mb`,
|
||||||
|
coming from the flavor is not specified. This is a success scenario,
|
||||||
|
in the case where `hw_video_ram` property is not set.
|
||||||
|
"""
|
||||||
|
def test_max_video_ram_none(self):
|
||||||
|
meta_dict = {'id': self._image_id, 'properties': {'hw_video_ram': 120}}
|
||||||
|
image_meta = objects.ImageMeta.from_dict(meta_dict)
|
||||||
|
flavor_extra_specs = {'quota:cpu_limit': 7,
|
||||||
|
'quota:cpu_reservation': 6}
|
||||||
|
flavor = objects.Flavor(name='my-flavor',
|
||||||
|
memory_mb=6,
|
||||||
|
vcpus=28,
|
||||||
|
root_gb=496,
|
||||||
|
ephemeral_gb=8128,
|
||||||
|
swap=33550336,
|
||||||
|
extra_specs=flavor_extra_specs)
|
||||||
|
|
||||||
|
self.assertRaises(exception.RequestedVRamTooHigh,
|
||||||
|
self._vmops._get_extra_specs,
|
||||||
|
flavor,
|
||||||
|
image_meta)
|
||||||
|
|
||||||
|
"""
|
||||||
|
Testing VM provisioning result in the case where `hw_video_ram`,
|
||||||
|
coming from the image is less than the maximum allowed video ram from
|
||||||
|
the flavor. This is a success scenario, in the case where `hw_video_ram`
|
||||||
|
property is set in the extra spec.
|
||||||
|
"""
|
||||||
|
def test_success_video_ram(self):
|
||||||
|
expected_video_ram = 90
|
||||||
|
meta_dict = {'id': self._image_id, 'properties': {
|
||||||
|
'hw_video_ram': expected_video_ram}}
|
||||||
|
image_meta, flavor = self._get_image_and_flavor_for_test_video(
|
||||||
|
meta_dict)
|
||||||
|
|
||||||
|
extra_specs = self._vmops._get_extra_specs(flavor, image_meta)
|
||||||
|
self.assertEqual(self._calculate_expected_fake_video_ram(
|
||||||
|
expected_video_ram), extra_specs.hw_video_ram)
|
||||||
|
|
||||||
|
"""
|
||||||
|
Testing VM provisioning result in the case where `hw_video_ram`,
|
||||||
|
coming from the image is equal to 0. This is a success scenario, in the
|
||||||
|
case where `hw_video_ram` property is not set in the extra spec.
|
||||||
|
"""
|
||||||
|
def test_zero_video_ram(self):
|
||||||
|
meta_dict = {'id': self._image_id, 'properties': {'hw_video_ram': 0}}
|
||||||
|
image_meta, flavor = self._get_image_and_flavor_for_test_video(
|
||||||
|
meta_dict)
|
||||||
|
|
||||||
|
extra_specs = self._vmops._get_extra_specs(flavor, image_meta)
|
||||||
|
self.assertIsNone(extra_specs.hw_video_ram)
|
||||||
|
|
||||||
|
def _calculate_expected_fake_video_ram(self, amount):
|
||||||
|
return amount * units.Mi / units.Ki
|
||||||
|
|
||||||
|
def _get_image_and_flavor_for_test_video(self, meta_dict):
|
||||||
|
image_meta = objects.ImageMeta.from_dict(meta_dict)
|
||||||
|
flavor_extra_specs = {'quota:cpu_limit': 7,
|
||||||
|
'quota:cpu_reservation': 6,
|
||||||
|
'hw_video:ram_max_mb': 100}
|
||||||
|
flavor = objects.Flavor(name='my-flavor',
|
||||||
|
memory_mb=6,
|
||||||
|
vcpus=28,
|
||||||
|
root_gb=496,
|
||||||
|
ephemeral_gb=8128,
|
||||||
|
swap=33550336,
|
||||||
|
extra_specs=flavor_extra_specs)
|
||||||
|
return image_meta, flavor
|
||||||
|
|
||||||
def test_extra_specs_cpu_limit(self):
|
def test_extra_specs_cpu_limit(self):
|
||||||
flavor_extra_specs = {'quota:cpu_limit': 7}
|
flavor_extra_specs = {'quota:cpu_limit': 7}
|
||||||
cpu_limits = vm_util.Limits(limit=7)
|
cpu_limits = vm_util.Limits(limit=7)
|
||||||
|
@ -92,7 +92,7 @@ class ExtraSpecs(object):
|
|||||||
def __init__(self, cpu_limits=None, hw_version=None,
|
def __init__(self, cpu_limits=None, hw_version=None,
|
||||||
storage_policy=None, cores_per_socket=None,
|
storage_policy=None, cores_per_socket=None,
|
||||||
memory_limits=None, disk_io_limits=None,
|
memory_limits=None, disk_io_limits=None,
|
||||||
vif_limits=None, firmware=None):
|
vif_limits=None, firmware=None, hw_video_ram=None):
|
||||||
"""ExtraSpecs object holds extra_specs for the instance."""
|
"""ExtraSpecs object holds extra_specs for the instance."""
|
||||||
self.cpu_limits = cpu_limits or Limits()
|
self.cpu_limits = cpu_limits or Limits()
|
||||||
self.memory_limits = memory_limits or Limits()
|
self.memory_limits = memory_limits or Limits()
|
||||||
@ -102,6 +102,7 @@ class ExtraSpecs(object):
|
|||||||
self.storage_policy = storage_policy
|
self.storage_policy = storage_policy
|
||||||
self.cores_per_socket = cores_per_socket
|
self.cores_per_socket = cores_per_socket
|
||||||
self.firmware = firmware
|
self.firmware = firmware
|
||||||
|
self.hw_video_ram = hw_video_ram
|
||||||
|
|
||||||
|
|
||||||
def vm_refs_cache_reset():
|
def vm_refs_cache_reset():
|
||||||
@ -257,6 +258,11 @@ def get_vm_create_spec(client_factory, instance, data_store_name,
|
|||||||
if serial_port_spec:
|
if serial_port_spec:
|
||||||
devices.append(serial_port_spec)
|
devices.append(serial_port_spec)
|
||||||
|
|
||||||
|
virtual_device_config_spec = create_video_card_spec(client_factory,
|
||||||
|
extra_specs)
|
||||||
|
if virtual_device_config_spec:
|
||||||
|
devices.append(virtual_device_config_spec)
|
||||||
|
|
||||||
config_spec.deviceChange = devices
|
config_spec.deviceChange = devices
|
||||||
|
|
||||||
# add vm-uuid and iface-id.x values for Neutron
|
# add vm-uuid and iface-id.x values for Neutron
|
||||||
@ -298,6 +304,18 @@ def get_vm_create_spec(client_factory, instance, data_store_name,
|
|||||||
return config_spec
|
return config_spec
|
||||||
|
|
||||||
|
|
||||||
|
def create_video_card_spec(client_factory, extra_specs):
|
||||||
|
if extra_specs.hw_video_ram:
|
||||||
|
video_card = client_factory.create('ns0:VirtualMachineVideoCard')
|
||||||
|
video_card.videoRamSizeInKB = extra_specs.hw_video_ram
|
||||||
|
video_card.key = -1
|
||||||
|
virtual_device_config_spec = client_factory.create(
|
||||||
|
'ns0:VirtualDeviceConfigSpec')
|
||||||
|
virtual_device_config_spec.operation = "add"
|
||||||
|
virtual_device_config_spec.device = video_card
|
||||||
|
return virtual_device_config_spec
|
||||||
|
|
||||||
|
|
||||||
def create_serial_port_spec(client_factory):
|
def create_serial_port_spec(client_factory):
|
||||||
"""Creates config spec for serial port."""
|
"""Creates config spec for serial port."""
|
||||||
if not CONF.vmware.serial_port_service_uri:
|
if not CONF.vmware.serial_port_service_uri:
|
||||||
|
@ -327,6 +327,16 @@ class VMwareVMOps(object):
|
|||||||
extra_specs.firmware = 'bios'
|
extra_specs.firmware = 'bios'
|
||||||
hw_version = flavor.extra_specs.get('vmware:hw_version')
|
hw_version = flavor.extra_specs.get('vmware:hw_version')
|
||||||
extra_specs.hw_version = hw_version
|
extra_specs.hw_version = hw_version
|
||||||
|
|
||||||
|
video_ram = image_meta.properties.get('hw_video_ram', 0)
|
||||||
|
max_vram = int(flavor.extra_specs.get('hw_video:ram_max_mb', 0))
|
||||||
|
|
||||||
|
if video_ram > max_vram:
|
||||||
|
raise exception.RequestedVRamTooHigh(req_vram=video_ram,
|
||||||
|
max_vram=max_vram)
|
||||||
|
if video_ram and max_vram:
|
||||||
|
extra_specs.hw_video_ram = video_ram * units.Mi / units.Ki
|
||||||
|
|
||||||
if CONF.vmware.pbm_enabled:
|
if CONF.vmware.pbm_enabled:
|
||||||
storage_policy = flavor.extra_specs.get('vmware:storage_policy',
|
storage_policy = flavor.extra_specs.get('vmware:storage_policy',
|
||||||
CONF.vmware.pbm_default_policy)
|
CONF.vmware.pbm_default_policy)
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
For the VMware vCenter driver, added support for the configured video ram ``hw_video_ram`` from the image,
|
||||||
|
which will be checked against the maximum allowed video ram ``hw_video:ram_max_mb``
|
||||||
|
from the flavor.
|
||||||
|
If the selected video ram from the image is less than or equal to the maximum allowed ram,
|
||||||
|
the ``videoRamSizeInKB`` will be set.
|
||||||
|
If the selected ram is more than the maximum allowed one, then server creation will fail for the given
|
||||||
|
image and flavor.
|
||||||
|
If the maximum allowed video ram is not set in the flavor we do not set ``videoRamSizeInKB`` in the VM.
|
Loading…
Reference in New Issue
Block a user