diff --git a/doc/notification_samples/common_payloads/ImageMetaPropsPayload.json b/doc/notification_samples/common_payloads/ImageMetaPropsPayload.json index 79f2559ec538..e56e37ad72a7 100644 --- a/doc/notification_samples/common_payloads/ImageMetaPropsPayload.json +++ b/doc/notification_samples/common_payloads/ImageMetaPropsPayload.json @@ -4,5 +4,5 @@ "hw_architecture": "x86_64" }, "nova_object.name": "ImageMetaPropsPayload", - "nova_object.version": "1.16" -} + "nova_object.version": "1.17" +} \ No newline at end of file diff --git a/nova/notifications/objects/image.py b/nova/notifications/objects/image.py index 42e61530aaa5..68247b082cd6 100644 --- a/nova/notifications/objects/image.py +++ b/nova/notifications/objects/image.py @@ -134,7 +134,8 @@ class ImageMetaPropsPayload(base.NotificationPayloadBase): # Version 1.14: Added 'hw_firmware_stateless' field # Version 1.15: Added igb value to 'hw_vif_model' enum # Version 1.16: Added 'hw_sound_model' field - VERSION = '1.16' + # Version 1.17: Added 'hw_usb_model' and 'hw_redirected_usb_ports' fields + VERSION = '1.17' # NOTE(efried): This logic currently relies on all of the fields of # ImageMetaProps being initialized with no arguments. See the docstring. diff --git a/nova/objects/fields.py b/nova/objects/fields.py index 0cb7922e121f..147ef70de43e 100644 --- a/nova/objects/fields.py +++ b/nova/objects/fields.py @@ -869,6 +869,21 @@ class SoundModelType(BaseNovaEnum): ALL = (SB16, ES1370, PCSPK, AC97, ICH6, ICH9, USB, VIRTIO,) +class USBControllerModelType(BaseNovaEnum): + # NOTE(mikal): qemu itself (and therefore libvirt) supports a lot more + # USB controllers than this, but they're all very old and don't support + # USB3. So while we could turn them on, it would be like adding in IDE + # disk bus emulation -- the performance isn't great and its been a very + # long time since an operating system was released which genuinely couldn't + # use something better. + + NONE = 'none' + NEC_XHCI = 'nec-xhci' + QEMU_XHCI = 'qemu-xhci' + + ALL = (NONE, NEC_XHCI, QEMU_XHCI) + + class NotificationPriority(BaseNovaEnum): AUDIT = 'audit' CRITICAL = 'critical' @@ -1411,6 +1426,10 @@ class SoundModelField(BaseEnumField): AUTO_TYPE = SoundModelType() +class USBControllerModelField(BaseEnumField): + AUTO_TYPE = USBControllerModelType() + + class NotificationPriorityField(BaseEnumField): AUTO_TYPE = NotificationPriority() diff --git a/nova/objects/image_meta.py b/nova/objects/image_meta.py index b6f0ba544391..3ccb267cb7d2 100644 --- a/nova/objects/image_meta.py +++ b/nova/objects/image_meta.py @@ -199,15 +199,19 @@ class ImageMetaProps(base.NovaObject): # Version 1.38: Added 'hw_firmware_stateless' field # Version 1.39: Added igb value to 'hw_vif_model' enum # Version 1.40: Added 'hw_sound_model' field + # Version 1.41: Added 'hw_usb_model' and 'hw_redirected_usb_ports' fields # NOTE(efried): When bumping this version, the version of # ImageMetaPropsPayload must also be bumped. See its docstring for details. - VERSION = '1.40' + VERSION = '1.41' 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, 41): + primitive.pop('hw_usb_model', None) + primitive.pop('hw_redirected_usb_ports', None) if target_version < (1, 40): primitive.pop('hw_sound_model', None) if target_version < (1, 39): @@ -501,6 +505,12 @@ class ImageMetaProps(base.NovaObject): # Name of sound device model to use. 'hw_sound_model': fields.SoundModelField(), + # Name of the USB Controller model to use. + 'hw_usb_model': fields.USBControllerModelField(), + + # Number of USB redirection ports to add to the guest. + 'hw_redirected_usb_ports': fields.IntegerField(), + # if true download using bittorrent 'img_bittorrent': fields.FlexibleBooleanField(), diff --git a/nova/tests/functional/notification_sample_tests/test_instance.py b/nova/tests/functional/notification_sample_tests/test_instance.py index 471fb9295edf..1f96029d607f 100644 --- a/nova/tests/functional/notification_sample_tests/test_instance.py +++ b/nova/tests/functional/notification_sample_tests/test_instance.py @@ -1244,7 +1244,7 @@ class TestInstanceNotificationSample( 'nova_object.data': {}, 'nova_object.name': 'ImageMetaPropsPayload', 'nova_object.namespace': 'nova', - 'nova_object.version': '1.16', + 'nova_object.version': '1.17', }, 'image.size': 58145823, 'image.tags': [], @@ -1340,7 +1340,7 @@ class TestInstanceNotificationSample( 'nova_object.data': {}, 'nova_object.name': 'ImageMetaPropsPayload', 'nova_object.namespace': 'nova', - 'nova_object.version': '1.16', + 'nova_object.version': '1.17', }, 'image.size': 58145823, 'image.tags': [], diff --git a/nova/tests/unit/notifications/objects/test_notification.py b/nova/tests/unit/notifications/objects/test_notification.py index 319892aaeeed..46f68b5dfb5e 100644 --- a/nova/tests/unit/notifications/objects/test_notification.py +++ b/nova/tests/unit/notifications/objects/test_notification.py @@ -385,7 +385,7 @@ notification_object_data = { # ImageMetaProps, so when you see a fail here for that reason, you must # *also* bump the version of ImageMetaPropsPayload. See its docstring for # more information. - 'ImageMetaPropsPayload': '1.16-871cffafce16ab4b6296c1f071262aa8', + 'ImageMetaPropsPayload': '1.17-60ebfe97483b0abee1ec22220613da40', 'InstanceActionNotification': '1.0-a73147b93b520ff0061865849d3dfa56', 'InstanceActionPayload': '1.9-525dcf81b6e4592d935712a2675309dc', 'InstanceActionRebuildNotification': diff --git a/nova/tests/unit/objects/test_objects.py b/nova/tests/unit/objects/test_objects.py index b7550a01e28a..7601ffa8c15e 100644 --- a/nova/tests/unit/objects/test_objects.py +++ b/nova/tests/unit/objects/test_objects.py @@ -1105,7 +1105,7 @@ object_data = { 'HyperVLiveMigrateData': '1.5-b424b27305f259fb3c15d720856585c7', 'IDEDeviceBus': '1.0-29d4c9f27ac44197f01b6ac1b7e16502', 'ImageMeta': '1.8-642d1b2eb3e880a367f37d72dd76162d', - 'ImageMetaProps': '1.40-6cd46dc34799f30e98a3a79d72c3b6eb', + 'ImageMetaProps': '1.41-1b67f6d0ae2292c3e50b838564e329c8', 'Instance': '2.8-2727dba5e4a078e6cc848c1f94f7eb24', 'InstanceAction': '1.2-9a5abc87fdd3af46f45731960651efb5', 'InstanceActionEvent': '1.4-5b1f361bd81989f8bb2c20bb7e8a4cb4',