libvirt: Enable custom video RAM setting
hw_video_ram can be provided via the image properties in Glance. The value should be provided in MB. hw_video_ram will be honoured, during an instance creation, only if a coresponding hw_video:ram_max_mb value has been set in the flavor's extra_specs and it's higher than the requested amount in hw_video_ram. glance image-update \ --property hw_video_model=qxl \ --property hw_video_ram=64 \ [image] DocImpact Partially implements blueprint libvirt-video-driver-selection Change-Id: I125cdc2afa27986ead9a81d925125a6a3ecce145
This commit is contained in:
parent
17aa741aee
commit
f5a102cc90
@ -127,6 +127,7 @@ CONF.import_opt('default_ephemeral_format', 'nova.virt.driver')
|
||||
MAX_USERDATA_SIZE = 65535
|
||||
QUOTAS = quota.QUOTAS
|
||||
RO_SECURITY_GROUPS = ['default']
|
||||
VIDEO_RAM = 'hw_video:ram_max_mb'
|
||||
|
||||
|
||||
def check_instance_state(vm_state=None, task_state=(None,),
|
||||
@ -336,7 +337,8 @@ class API(base.Base):
|
||||
|
||||
# Determine requested cores and ram
|
||||
req_cores = max_count * instance_type['vcpus']
|
||||
req_ram = max_count * instance_type['memory_mb']
|
||||
vram_mb = int(instance_type.get('extra_specs', {}).get(VIDEO_RAM, 0))
|
||||
req_ram = max_count * (instance_type['memory_mb'] + vram_mb)
|
||||
|
||||
# Check the quota
|
||||
try:
|
||||
@ -355,7 +357,8 @@ class API(base.Base):
|
||||
headroom['cores'] // instance_type['vcpus'])
|
||||
if instance_type['memory_mb']:
|
||||
allowed = min(allowed,
|
||||
headroom['ram'] // instance_type['memory_mb'])
|
||||
headroom['ram'] // (instance_type['memory_mb'] +
|
||||
vram_mb))
|
||||
|
||||
# Convert to the appropriate exception message
|
||||
if allowed <= 0:
|
||||
@ -1567,7 +1570,9 @@ class API(base.Base):
|
||||
pass
|
||||
else:
|
||||
instance_vcpus = old_inst_type['vcpus']
|
||||
instance_memory_mb = old_inst_type['memory_mb']
|
||||
vram_mb = int(old_inst_type['extra_specs']
|
||||
.get(VIDEO_RAM, 0))
|
||||
instance_memory_mb = (old_inst_type['memory_mb'] + vram_mb)
|
||||
LOG.debug(_("going to delete a resizing instance"))
|
||||
|
||||
reservations = QUOTAS.reserve(context,
|
||||
|
@ -1511,3 +1511,8 @@ class InvalidVideoMode(Invalid):
|
||||
class RngDeviceNotExist(Invalid):
|
||||
msg_fmt = _("The provided RNG device path: (%(path)s) is not "
|
||||
"present on the host.")
|
||||
|
||||
|
||||
class RequestedVRamTooHigh(NovaException):
|
||||
msg_fmt = _("The requested amount of video memory %(req_vram)d is higher"
|
||||
"than the maximum allowed by flavor %(max_vram)d.")
|
||||
|
@ -1323,6 +1323,90 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
self.assertEqual(cfg.devices[7].type, "unix")
|
||||
self.assertEqual(cfg.devices[7].target_name, "org.qemu.guest_agent.0")
|
||||
|
||||
def test_get_guest_config_with_video_driver_vram(self):
|
||||
self.flags(vnc_enabled=False)
|
||||
self.flags(virt_type='kvm', group='libvirt')
|
||||
self.flags(enabled=True,
|
||||
agent_enabled=True,
|
||||
group='spice')
|
||||
|
||||
instance_type = flavor_obj.Flavor.get_by_id(self.context, 5)
|
||||
instance_type.extra_specs = {'hw_video:ram_max_mb': "100"}
|
||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
instance_ref = db.instance_create(self.context, self.test_instance)
|
||||
|
||||
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
||||
instance_ref)
|
||||
image_meta = {"properties": {"hw_video_model": "qxl",
|
||||
"hw_video_ram": "64"}}
|
||||
with mock.patch.object(flavor_obj.Flavor, 'get_by_id',
|
||||
return_value=instance_type):
|
||||
cfg = conn.get_guest_config(instance_ref, [],
|
||||
image_meta, disk_info)
|
||||
self.assertEqual(len(cfg.devices), 7)
|
||||
self.assertIsInstance(cfg.devices[0],
|
||||
vconfig.LibvirtConfigGuestDisk)
|
||||
self.assertIsInstance(cfg.devices[1],
|
||||
vconfig.LibvirtConfigGuestDisk)
|
||||
self.assertIsInstance(cfg.devices[2],
|
||||
vconfig.LibvirtConfigGuestSerial)
|
||||
self.assertIsInstance(cfg.devices[3],
|
||||
vconfig.LibvirtConfigGuestSerial)
|
||||
self.assertIsInstance(cfg.devices[4],
|
||||
vconfig.LibvirtConfigGuestChannel)
|
||||
self.assertIsInstance(cfg.devices[5],
|
||||
vconfig.LibvirtConfigGuestGraphics)
|
||||
self.assertIsInstance(cfg.devices[6],
|
||||
vconfig.LibvirtConfigGuestVideo)
|
||||
|
||||
self.assertEqual(cfg.devices[5].type, "spice")
|
||||
self.assertEqual(cfg.devices[6].type, "qxl")
|
||||
self.assertEqual(cfg.devices[6].vram, 64)
|
||||
|
||||
def test_video_driver_flavor_limit_not_set(self):
|
||||
self.flags(virt_type='kvm', group='libvirt')
|
||||
self.flags(enabled=True,
|
||||
agent_enabled=True,
|
||||
group='spice')
|
||||
|
||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
instance_ref = db.instance_create(self.context, self.test_instance)
|
||||
|
||||
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
||||
instance_ref)
|
||||
image_meta = {"properties": {"hw_video_model": "qxl",
|
||||
"hw_video_ram": "64"}}
|
||||
self.assertRaises(exception.RequestedVRamTooHigh,
|
||||
conn.get_guest_config,
|
||||
instance_ref,
|
||||
[],
|
||||
image_meta,
|
||||
disk_info)
|
||||
|
||||
def test_video_driver_ram_above_flavor_limit(self):
|
||||
self.flags(virt_type='kvm', group='libvirt')
|
||||
self.flags(enabled=True,
|
||||
agent_enabled=True,
|
||||
group='spice')
|
||||
|
||||
instance_type = flavor_obj.Flavor.get_by_id(self.context, 5)
|
||||
instance_type.extra_specs = {'hw_video:ram_max_mb': "50"}
|
||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
instance_ref = db.instance_create(self.context, self.test_instance)
|
||||
|
||||
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
||||
instance_ref)
|
||||
image_meta = {"properties": {"hw_video_model": "qxl",
|
||||
"hw_video_ram": "64"}}
|
||||
with mock.patch.object(flavor_obj.Flavor, 'get_by_id',
|
||||
return_value=instance_type):
|
||||
self.assertRaises(exception.RequestedVRamTooHigh,
|
||||
conn.get_guest_config,
|
||||
instance_ref,
|
||||
[],
|
||||
image_meta,
|
||||
disk_info)
|
||||
|
||||
def test_get_guest_config_without_qga_through_image_meta(self):
|
||||
self.flags(virt_type='kvm', group='libvirt')
|
||||
|
||||
|
@ -3277,6 +3277,15 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
if (video.type not in VALID_VIDEO_DEVICES):
|
||||
raise exception.InvalidVideoMode(model=video.type)
|
||||
|
||||
# Set video memory, only if the flavor's limit is set
|
||||
video_ram = int(img_meta_prop.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 max_vram and video_ram:
|
||||
video.vram = video_ram
|
||||
guest.add_device(video)
|
||||
|
||||
# Qemu guest agent only support 'qemu' and 'kvm' hypervisor
|
||||
|
Loading…
x
Reference in New Issue
Block a user