libvirt: enhance method to return pointer_model from image prop
Gives the opportunity to set the pointer type from image properties. Implements: blueprint virt-configure-usb-tablet-from-image Change-Id: I11d3e031c202c39258263212401a0f035ec67d88
This commit is contained in:
committed by
Matt Riedemann
parent
5b92ae8d92
commit
ed6a82ee22
@@ -333,6 +333,9 @@ pointer_model = cfg.StrOpt(
|
||||
Input devices allow interaction with a graphical framebuffer. For
|
||||
example to provide a graphic tablet for absolute cursor movement.
|
||||
|
||||
If set, the 'hw_pointer_model' image property takes precedence over
|
||||
this configuration option.
|
||||
|
||||
Possible values:
|
||||
|
||||
* None: Uses relative movement. Mouse connected by PS2
|
||||
|
||||
@@ -2153,3 +2153,8 @@ class InvalidReservedMemoryPagesOption(Invalid):
|
||||
class ConcurrentUpdateDetected(NovaException):
|
||||
msg_fmt = _("Another thread concurrently updated the data. "
|
||||
"Please retry your update")
|
||||
|
||||
|
||||
class UnsupportedPointerModelRequested(Invalid):
|
||||
msg_fmt = _("Pointer model '%(model)s' requested is not supported by "
|
||||
"host.")
|
||||
|
||||
@@ -567,6 +567,17 @@ class DiskFormat(Enum):
|
||||
valid_values=DiskFormat.ALL)
|
||||
|
||||
|
||||
class PointerModelType(Enum):
|
||||
|
||||
USBTABLET = "usbtablet"
|
||||
|
||||
ALL = (USBTABLET)
|
||||
|
||||
def __init__(self):
|
||||
super(PointerModelType, self).__init__(
|
||||
valid_values=PointerModelType.ALL)
|
||||
|
||||
|
||||
class NotificationPriority(Enum):
|
||||
AUDIT = 'audit'
|
||||
CRITICAL = 'critical'
|
||||
@@ -836,6 +847,10 @@ class DiskFormatField(BaseEnumField):
|
||||
AUTO_TYPE = DiskFormat()
|
||||
|
||||
|
||||
class PointerModelField(BaseEnumField):
|
||||
AUTO_TYPE = PointerModelType()
|
||||
|
||||
|
||||
class NotificationPriorityField(BaseEnumField):
|
||||
AUTO_TYPE = NotificationPriority()
|
||||
|
||||
|
||||
@@ -162,12 +162,15 @@ class ImageMetaProps(base.NovaObject):
|
||||
# Version 1.11: Added hw_firmware_type field
|
||||
# Version 1.12: Added properties for image signature verification
|
||||
# Version 1.13: added os_secure_boot field
|
||||
VERSION = '1.13'
|
||||
# Version 1.14: Added 'hw_pointer_model' field
|
||||
VERSION = '1.14'
|
||||
|
||||
def obj_make_compatible(self, primitive, target_version):
|
||||
super(ImageMetaProps, self).obj_make_compatible(primitive,
|
||||
target_version)
|
||||
target_version = versionutils.convert_version_to_tuple(target_version)
|
||||
if target_version < (1, 14):
|
||||
primitive.pop('hw_pointer_model', None)
|
||||
if target_version < (1, 13):
|
||||
primitive.pop('os_secure_boot', None)
|
||||
if target_version < (1, 11):
|
||||
@@ -287,6 +290,9 @@ class ImageMetaProps(base.NovaObject):
|
||||
# list value indicates the memory size of that node.
|
||||
'hw_numa_mem': fields.ListOfIntegersField(),
|
||||
|
||||
# Generic property to specify the pointer model type.
|
||||
'hw_pointer_model': fields.PointerModelField(),
|
||||
|
||||
# boolean 'yes' or 'no' to enable QEMU guest agent
|
||||
'hw_qemu_guest_agent': fields.FlexibleBooleanField(),
|
||||
|
||||
|
||||
@@ -1132,7 +1132,7 @@ object_data = {
|
||||
'HVSpec': '1.2-db672e73304da86139086d003f3977e7',
|
||||
'IDEDeviceBus': '1.0-29d4c9f27ac44197f01b6ac1b7e16502',
|
||||
'ImageMeta': '1.8-642d1b2eb3e880a367f37d72dd76162d',
|
||||
'ImageMetaProps': '1.13-8bc4e3cac2a941991e9adbc54e915698',
|
||||
'ImageMetaProps': '1.14-cc8f96454cdb0feadcb2fc9e63974016',
|
||||
'Instance': '2.2-ab450ec9c1f4d429755c48d492b823f0',
|
||||
'InstanceAction': '1.1-f9f293e526b66fca0d05c3b3a2d13914',
|
||||
'InstanceActionEvent': '1.1-e56a64fa4710e43ef7af2ad9d6028b33',
|
||||
|
||||
@@ -3866,12 +3866,13 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
||||
self.assertEqual("none", cfg.devices[7].action)
|
||||
|
||||
def _test_get_guest_usb_tablet(self, vnc_enabled, spice_enabled, os_type,
|
||||
agent_enabled=False):
|
||||
agent_enabled=False, image_meta=None):
|
||||
self.flags(enabled=vnc_enabled, group='vnc')
|
||||
self.flags(enabled=spice_enabled,
|
||||
agent_enabled=agent_enabled, group='spice')
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
return drvr._get_guest_pointer_model(os_type)
|
||||
image_meta = objects.ImageMeta.from_dict(image_meta)
|
||||
return drvr._get_guest_pointer_model(os_type, image_meta)
|
||||
|
||||
def test_get_guest_usb_tablet_wipe(self):
|
||||
self.flags(use_usb_tablet=True, group='libvirt')
|
||||
@@ -3895,6 +3896,44 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
||||
False, True, vm_mode.HVM, True)
|
||||
self.assertIsNone(tablet)
|
||||
|
||||
def test_get_guest_usb_tablet_image_meta(self):
|
||||
self.flags(use_usb_tablet=True, group='libvirt')
|
||||
image_meta = {"properties": {"hw_pointer_model": "usbtablet"}}
|
||||
|
||||
tablet = self._test_get_guest_usb_tablet(
|
||||
True, True, vm_mode.HVM, image_meta=image_meta)
|
||||
self.assertIsNotNone(tablet)
|
||||
|
||||
tablet = self._test_get_guest_usb_tablet(
|
||||
True, False, vm_mode.HVM, image_meta=image_meta)
|
||||
self.assertIsNotNone(tablet)
|
||||
|
||||
tablet = self._test_get_guest_usb_tablet(
|
||||
False, True, vm_mode.HVM, image_meta=image_meta)
|
||||
self.assertIsNotNone(tablet)
|
||||
|
||||
tablet = self._test_get_guest_usb_tablet(
|
||||
False, False, vm_mode.HVM, image_meta=image_meta)
|
||||
self.assertIsNone(tablet)
|
||||
|
||||
tablet = self._test_get_guest_usb_tablet(
|
||||
True, True, "foo", image_meta=image_meta)
|
||||
self.assertIsNone(tablet)
|
||||
|
||||
tablet = self._test_get_guest_usb_tablet(
|
||||
False, True, vm_mode.HVM, True, image_meta=image_meta)
|
||||
self.assertIsNone(tablet)
|
||||
|
||||
def test_get_guest_usb_tablet_image_meta_no_vnc(self):
|
||||
self.flags(use_usb_tablet=False, group='libvirt')
|
||||
self.flags(pointer_model=None)
|
||||
|
||||
image_meta = {"properties": {"hw_pointer_model": "usbtablet"}}
|
||||
self.assertRaises(
|
||||
exception.UnsupportedPointerModelRequested,
|
||||
self._test_get_guest_usb_tablet,
|
||||
False, False, vm_mode.HVM, True, image_meta=image_meta)
|
||||
|
||||
def test_get_guest_no_pointer_model_usb_tablet_set(self):
|
||||
self.flags(use_usb_tablet=True, group='libvirt')
|
||||
|
||||
@@ -3913,6 +3952,21 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
||||
tablet = self._test_get_guest_usb_tablet(True, True, vm_mode.HVM)
|
||||
self.assertIsNotNone(tablet)
|
||||
|
||||
def test_get_guest_pointer_model_usb_tablet_image(self):
|
||||
image_meta = {"properties": {"hw_pointer_model": "usbtablet"}}
|
||||
tablet = self._test_get_guest_usb_tablet(
|
||||
True, True, vm_mode.HVM, image_meta=image_meta)
|
||||
self.assertIsNotNone(tablet)
|
||||
|
||||
def test_get_guest_pointer_model_usb_tablet_image_no_HVM(self):
|
||||
self.flags(pointer_model=None)
|
||||
self.flags(use_usb_tablet=False, group='libvirt')
|
||||
image_meta = {"properties": {"hw_pointer_model": "usbtablet"}}
|
||||
self.assertRaises(
|
||||
exception.UnsupportedPointerModelRequested,
|
||||
self._test_get_guest_usb_tablet,
|
||||
True, True, vm_mode.XEN, image_meta=image_meta)
|
||||
|
||||
def _test_get_guest_config_with_watchdog_action_flavor(self,
|
||||
hw_watchdog_action="hw:watchdog_action"):
|
||||
self.flags(virt_type='kvm', group='libvirt')
|
||||
|
||||
+27
-17
@@ -4374,7 +4374,7 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
consolepty.type = "pty"
|
||||
guest.add_device(consolepty)
|
||||
|
||||
pointer = self._get_guest_pointer_model(guest.os_type)
|
||||
pointer = self._get_guest_pointer_model(guest.os_type, image_meta)
|
||||
if pointer:
|
||||
guest.add_device(pointer)
|
||||
|
||||
@@ -4457,8 +4457,9 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
|
||||
return guest
|
||||
|
||||
def _get_guest_pointer_model(self, os_type):
|
||||
pointer_model = CONF.pointer_model
|
||||
def _get_guest_pointer_model(self, os_type, image_meta):
|
||||
pointer_model = image_meta.properties.get(
|
||||
'hw_pointer_model', CONF.pointer_model)
|
||||
if pointer_model is None and CONF.libvirt.use_usb_tablet:
|
||||
# TODO(sahid): We set pointer_model to keep compatibility
|
||||
# until the next release O*. It means operators can continue
|
||||
@@ -4479,14 +4480,18 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
CONF.spice.enabled and not CONF.spice.agent_enabled):
|
||||
return self._get_guest_usb_tablet(os_type)
|
||||
else:
|
||||
# For backward compatibility We don't want to break
|
||||
# process of booting an instance if host is configured
|
||||
# to use USB tablet without VNC or SPICE and SPICE
|
||||
# agent disable.
|
||||
LOG.warning(_LW('USB tablet requested for guests by host '
|
||||
'configuration. In order to accept this '
|
||||
'request VNC should be enabled or SPICE '
|
||||
'and SPICE agent disabled on host.'))
|
||||
if CONF.pointer_model or CONF.libvirt.use_usb_tablet:
|
||||
# For backward compatibility We don't want to break
|
||||
# process of booting an instance if host is configured
|
||||
# to use USB tablet without VNC or SPICE and SPICE
|
||||
# agent disable.
|
||||
LOG.warning(_LW('USB tablet requested for guests by host '
|
||||
'configuration. In order to accept this '
|
||||
'request VNC should be enabled or SPICE '
|
||||
'and SPICE agent disabled on host.'))
|
||||
else:
|
||||
raise exception.UnsupportedPointerModelRequested(
|
||||
model="usbtablet")
|
||||
|
||||
def _get_guest_usb_tablet(self, os_type):
|
||||
tablet = None
|
||||
@@ -4495,12 +4500,17 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
tablet.type = "tablet"
|
||||
tablet.bus = "usb"
|
||||
else:
|
||||
# For backward compatibility We don't want to break
|
||||
# process of booting an instance if virtual machine mode
|
||||
# is not configured as HVM.
|
||||
LOG.warning(_LW('USB tablet requested for guests by host '
|
||||
'configuration. In order to accept this request '
|
||||
'the machine mode should be configured as HVM.'))
|
||||
if CONF.pointer_model or CONF.libvirt.use_usb_tablet:
|
||||
# For backward compatibility We don't want to break
|
||||
# process of booting an instance if virtual machine mode
|
||||
# is not configured as HVM.
|
||||
LOG.warning(_LW('USB tablet requested for guests by host '
|
||||
'configuration. In order to accept this '
|
||||
'request the machine mode should be '
|
||||
'configured as HVM.'))
|
||||
else:
|
||||
raise exception.UnsupportedPointerModelRequested(
|
||||
model="usbtablet")
|
||||
return tablet
|
||||
|
||||
def _get_guest_xml(self, context, instance, network_info, disk_info,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
---
|
||||
features:
|
||||
- The pointer_model configuration option was added to specify
|
||||
different pointer models for input devices. This replaces
|
||||
the now deprecated use_usb_tablet option.
|
||||
- The pointer_model configuration option and hw_pointer_model image
|
||||
property was added to specify different pointer models for input
|
||||
devices. This replaces the now deprecated use_usb_tablet
|
||||
option.
|
||||
deprecations:
|
||||
- Nova option 'use_usb_tablet' will be deprecated in favor of
|
||||
the global 'pointer_model'.
|
||||
Reference in New Issue
Block a user