diff options
author | Alex Szarka <szarka@inf.u-szeged.hu> | 2017-07-11 18:32:24 +0200 |
---|---|---|
committer | Takashi NATSUME <natsume.takashi@lab.ntt.co.jp> | 2018-11-21 16:23:28 +0900 |
commit | fe4e47d9899b730abf06a120ba113f5f4a567d1e (patch) | |
tree | c9887de9d262b6915203972ff39b595b218c6988 /nova/notifications | |
parent | 7217e38bafb75e8a613763835b64e48e6b2c8ece (diff) | |
download | nova-fe4e47d9899b730abf06a120ba113f5f4a567d1e.tar.gz |
Transform compute_task notifications
The following notifications have been transformed to
the versioned notification framework.
* compute_task.build_instances
* compute_task.migrate_server
* compute_task.rebuild_server
Co-Authored-By: Takashi Natsume <natsume.takashi@lab.ntt.co.jp>
Change-Id: Ibfb0a6db5920d921c4fc7cabf3f4d2838ea7f421
Implements: bp versioned-notification-transformation-stein
Diffstat (limited to 'nova/notifications')
-rw-r--r-- | nova/notifications/objects/base.py | 23 | ||||
-rw-r--r-- | nova/notifications/objects/compute_task.py | 54 | ||||
-rw-r--r-- | nova/notifications/objects/image.py | 261 | ||||
-rw-r--r-- | nova/notifications/objects/request_spec.py | 226 |
4 files changed, 554 insertions, 10 deletions
diff --git a/nova/notifications/objects/base.py b/nova/notifications/objects/base.py index 26012dfbc8..70ce3391c9 100644 --- a/nova/notifications/objects/base.py +++ b/nova/notifications/objects/base.py @@ -67,7 +67,9 @@ class EventType(NotificationObject): # NotificationActionField enum # Version 1.16: CONNECT is added to NotificationActionField enum # Version 1.17: USAGE is added to NotificationActionField enum - VERSION = '1.17' + # Version 1.18: ComputeTask related values have been added to + # NotificationActionField enum + VERSION = '1.18' fields = { 'object': fields.StringField(nullable=False), @@ -119,7 +121,7 @@ class NotificationPayloadBase(NotificationObject): self.populated = not self.SCHEMA @rpc.if_notifications_enabled - def populate_schema(self, **kwargs): + def populate_schema(self, set_none=True, **kwargs): """Populate the object based on the SCHEMA and the source objects :param kwargs: A dict contains the source object at the key defined in @@ -137,14 +139,15 @@ class NotificationPayloadBase(NotificationObject): NotImplementedError, exception.OrphanedObjectError, ovo_exception.OrphanedObjectError): - # If it is unset or non lazy loadable in the source object - # then we cannot do anything else but try to default it in the - # payload object we are generating here. - # NOTE(gibi): This will fail if the payload field is not - # nullable, but that means that either the source object is not - # properly initialized or the payload field needs to be defined - # as nullable - setattr(self, key, None) + if set_none: + # If it is unset or non lazy loadable in the source object + # then we cannot do anything else but try to default it + # in the payload object we are generating here. + # NOTE(gibi): This will fail if the payload field is not + # nullable, but that means that either the source object + # is not properly initialized or the payload field needs + # to be defined as nullable + setattr(self, key, None) except Exception: with excutils.save_and_reraise_exception(): LOG.error('Failed trying to populate attribute "%s" ' diff --git a/nova/notifications/objects/compute_task.py b/nova/notifications/objects/compute_task.py new file mode 100644 index 0000000000..fe087dbb93 --- /dev/null +++ b/nova/notifications/objects/compute_task.py @@ -0,0 +1,54 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from nova.notifications.objects import base +from nova.notifications.objects import request_spec as reqspec_payload +from nova.objects import base as nova_base +from nova.objects import fields + + +@nova_base.NovaObjectRegistry.register_notification +class ComputeTaskPayload(base.NotificationPayloadBase): + # Version 1.0: Initial version + VERSION = '1.0' + + fields = { + 'instance_uuid': fields.UUIDField(), + # There are some cases that request_spec is None. + # e.g. Old instances can still have no RequestSpec object + # attached to them. + 'request_spec': fields.ObjectField('RequestSpecPayload', + nullable=True), + 'state': fields.InstanceStateField(nullable=True), + 'reason': fields.ObjectField('ExceptionPayload') + } + + def __init__(self, instance_uuid, request_spec, state, reason): + super(ComputeTaskPayload, self).__init__() + self.instance_uuid = instance_uuid + self.request_spec = reqspec_payload.RequestSpecPayload( + request_spec) if request_spec is not None else None + self.state = state + self.reason = reason + + +@base.notification_sample('compute_task-build_instances-error.json') +@base.notification_sample('compute_task-migrate_server-error.json') +@base.notification_sample('compute_task-rebuild_server-error.json') +@nova_base.NovaObjectRegistry.register_notification +class ComputeTaskNotification(base.NotificationBase): + # Version 1.0: Initial version + VERSION = '1.0' + + fields = { + 'payload': fields.ObjectField('ComputeTaskPayload') + } diff --git a/nova/notifications/objects/image.py b/nova/notifications/objects/image.py new file mode 100644 index 0000000000..d68259731c --- /dev/null +++ b/nova/notifications/objects/image.py @@ -0,0 +1,261 @@ +# Copyright 2018 NTT Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from nova.notifications.objects import base +from nova.objects import base as nova_base +from nova.objects import fields + + +@nova_base.NovaObjectRegistry.register_notification +class ImageMetaPayload(base.NotificationPayloadBase): + # Version 1.0: Initial version + VERSION = '1.0' + + SCHEMA = { + 'id': ('image_meta', 'id'), + 'name': ('image_meta', 'name'), + 'status': ('image_meta', 'status'), + 'visibility': ('image_meta', 'visibility'), + 'protected': ('image_meta', 'protected'), + 'checksum': ('image_meta', 'checksum'), + 'owner': ('image_meta', 'owner'), + 'size': ('image_meta', 'size'), + 'virtual_size': ('image_meta', 'virtual_size'), + 'container_format': ('image_meta', 'container_format'), + 'disk_format': ('image_meta', 'disk_format'), + 'created_at': ('image_meta', 'created_at'), + 'updated_at': ('image_meta', 'updated_at'), + 'tags': ('image_meta', 'tags'), + 'direct_url': ('image_meta', 'direct_url'), + 'min_ram': ('image_meta', 'min_ram'), + 'min_disk': ('image_meta', 'min_disk') + } + + # NOTE(takashin): The reason that each field is nullable is as follows. + # + # a. It is defined as "The value might be null (JSON null data type)." + # in the "Show image" API (GET /v2/images/{image_id}) + # in the glance API v2 Reference. + # (https://developer.openstack.org/api-ref/image/v2/index.html) + # + # * checksum + # * container_format + # * disk_format + # * min_disk + # * min_ram + # * name + # * owner + # * size + # * updated_at + # * virtual_size + # + # b. It is optional in the response from glance. + # * direct_url + # + # a. It is defined as nullable in the ImageMeta object. + # * created_at + # + # c. It cannot be got in the boot from volume case. + # See VIM_IMAGE_ATTRIBUTES in nova/utils.py. + # + # * id (not 'image_id') + # * visibility + # * protected + # * status + # * tags + fields = { + 'id': fields.UUIDField(nullable=True), + 'name': fields.StringField(nullable=True), + 'status': fields.StringField(nullable=True), + 'visibility': fields.StringField(nullable=True), + 'protected': fields.FlexibleBooleanField(nullable=True), + 'checksum': fields.StringField(nullable=True), + 'owner': fields.StringField(nullable=True), + 'size': fields.IntegerField(nullable=True), + 'virtual_size': fields.IntegerField(nullable=True), + 'container_format': fields.StringField(nullable=True), + 'disk_format': fields.StringField(nullable=True), + 'created_at': fields.DateTimeField(nullable=True), + 'updated_at': fields.DateTimeField(nullable=True), + 'tags': fields.ListOfStringsField(nullable=True), + 'direct_url': fields.StringField(nullable=True), + 'min_ram': fields.IntegerField(nullable=True), + 'min_disk': fields.IntegerField(nullable=True), + 'properties': fields.ObjectField('ImageMetaPropsPayload') + } + + def __init__(self, image_meta): + super(ImageMetaPayload, self).__init__() + self.properties = ImageMetaPropsPayload( + image_meta_props=image_meta.properties) + self.populate_schema(image_meta=image_meta) + + +@nova_base.NovaObjectRegistry.register_notification +class ImageMetaPropsPayload(base.NotificationPayloadBase): + # Version 1.0: Initial version + VERSION = '1.0' + + SCHEMA = { + 'hw_architecture': ('image_meta_props', 'hw_architecture'), + 'hw_auto_disk_config': ('image_meta_props', 'hw_auto_disk_config'), + 'hw_boot_menu': ('image_meta_props', 'hw_boot_menu'), + 'hw_cdrom_bus': ('image_meta_props', 'hw_cdrom_bus'), + 'hw_cpu_cores': ('image_meta_props', 'hw_cpu_cores'), + 'hw_cpu_sockets': ('image_meta_props', 'hw_cpu_sockets'), + 'hw_cpu_max_cores': ('image_meta_props', 'hw_cpu_max_cores'), + 'hw_cpu_max_sockets': ('image_meta_props', 'hw_cpu_max_sockets'), + 'hw_cpu_max_threads': ('image_meta_props', 'hw_cpu_max_threads'), + 'hw_cpu_policy': ('image_meta_props', 'hw_cpu_policy'), + 'hw_cpu_thread_policy': ('image_meta_props', 'hw_cpu_thread_policy'), + 'hw_cpu_realtime_mask': ('image_meta_props', 'hw_cpu_realtime_mask'), + 'hw_cpu_threads': ('image_meta_props', 'hw_cpu_threads'), + 'hw_device_id': ('image_meta_props', 'hw_device_id'), + 'hw_disk_bus': ('image_meta_props', 'hw_disk_bus'), + 'hw_disk_type': ('image_meta_props', 'hw_disk_type'), + 'hw_floppy_bus': ('image_meta_props', 'hw_floppy_bus'), + 'hw_firmware_type': ('image_meta_props', 'hw_firmware_type'), + 'hw_ipxe_boot': ('image_meta_props', 'hw_ipxe_boot'), + 'hw_machine_type': ('image_meta_props', 'hw_machine_type'), + 'hw_mem_page_size': ('image_meta_props', 'hw_mem_page_size'), + 'hw_numa_nodes': ('image_meta_props', 'hw_numa_nodes'), + 'hw_numa_cpus': ('image_meta_props', 'hw_numa_cpus'), + 'hw_numa_mem': ('image_meta_props', 'hw_numa_mem'), + 'hw_pointer_model': ('image_meta_props', 'hw_pointer_model'), + 'hw_qemu_guest_agent': ('image_meta_props', 'hw_qemu_guest_agent'), + 'hw_rescue_bus': ('image_meta_props', 'hw_rescue_bus'), + 'hw_rescue_device': ('image_meta_props', 'hw_rescue_device'), + 'hw_rng_model': ('image_meta_props', 'hw_rng_model'), + 'hw_serial_port_count': ('image_meta_props', 'hw_serial_port_count'), + 'hw_scsi_model': ('image_meta_props', 'hw_scsi_model'), + 'hw_video_model': ('image_meta_props', 'hw_video_model'), + 'hw_video_ram': ('image_meta_props', 'hw_video_ram'), + 'hw_vif_model': ('image_meta_props', 'hw_vif_model'), + 'hw_vm_mode': ('image_meta_props', 'hw_vm_mode'), + 'hw_watchdog_action': ('image_meta_props', 'hw_watchdog_action'), + 'hw_vif_multiqueue_enabled': ('image_meta_props', + 'hw_vif_multiqueue_enabled'), + 'img_bittorrent': ('image_meta_props', 'img_bittorrent'), + 'img_bdm_v2': ('image_meta_props', 'img_bdm_v2'), + 'img_block_device_mapping': ('image_meta_props', + 'img_block_device_mapping'), + 'img_cache_in_nova': ('image_meta_props', 'img_cache_in_nova'), + 'img_compression_level': ('image_meta_props', 'img_compression_level'), + 'img_hv_requested_version': ('image_meta_props', + 'img_hv_requested_version'), + 'img_hv_type': ('image_meta_props', 'img_hv_type'), + 'img_config_drive': ('image_meta_props', 'img_config_drive'), + 'img_linked_clone': ('image_meta_props', 'img_linked_clone'), + 'img_mappings': ('image_meta_props', 'img_mappings'), + 'img_owner_id': ('image_meta_props', 'img_owner_id'), + 'img_root_device_name': ('image_meta_props', 'img_root_device_name'), + 'img_use_agent': ('image_meta_props', 'img_use_agent'), + 'img_version': ('image_meta_props', 'img_version'), + 'img_signature': ('image_meta_props', 'img_signature'), + 'img_signature_hash_method': ('image_meta_props', + 'img_signature_hash_method'), + 'img_signature_certificate_uuid': ('image_meta_props', + 'img_signature_certificate_uuid'), + 'img_signature_key_type': ('image_meta_props', + 'img_signature_key_type'), + 'img_hide_hypervisor_id': ('image_meta_props', + 'img_hide_hypervisor_id'), + 'os_admin_user': ('image_meta_props', 'os_admin_user'), + 'os_command_line': ('image_meta_props', 'os_command_line'), + 'os_distro': ('image_meta_props', 'os_distro'), + 'os_require_quiesce': ('image_meta_props', 'os_require_quiesce'), + 'os_secure_boot': ('image_meta_props', 'os_secure_boot'), + 'os_skip_agent_inject_files_at_boot': ( + 'image_meta_props', 'os_skip_agent_inject_files_at_boot'), + 'os_skip_agent_inject_ssh': ('image_meta_props', + 'os_skip_agent_inject_ssh'), + 'os_type': ('image_meta_props', 'os_type'), + 'traits_required': ('image_meta_props', 'traits_required') + } + + fields = { + 'hw_architecture': fields.ArchitectureField(), + 'hw_auto_disk_config': fields.StringField(), + 'hw_boot_menu': fields.FlexibleBooleanField(), + 'hw_cdrom_bus': fields.DiskBusField(), + 'hw_cpu_cores': fields.IntegerField(), + 'hw_cpu_sockets': fields.IntegerField(), + 'hw_cpu_max_cores': fields.IntegerField(), + 'hw_cpu_max_sockets': fields.IntegerField(), + 'hw_cpu_max_threads': fields.IntegerField(), + 'hw_cpu_policy': fields.CPUAllocationPolicyField(), + 'hw_cpu_thread_policy': fields.CPUThreadAllocationPolicyField(), + 'hw_cpu_realtime_mask': fields.StringField(), + 'hw_cpu_threads': fields.IntegerField(), + 'hw_device_id': fields.IntegerField(), + 'hw_disk_bus': fields.DiskBusField(), + 'hw_disk_type': fields.StringField(), + 'hw_floppy_bus': fields.DiskBusField(), + 'hw_firmware_type': fields.FirmwareTypeField(), + 'hw_ipxe_boot': fields.FlexibleBooleanField(), + 'hw_machine_type': fields.StringField(), + 'hw_mem_page_size': fields.StringField(), + 'hw_numa_nodes': fields.IntegerField(), + 'hw_numa_cpus': fields.ListOfSetsOfIntegersField(), + 'hw_numa_mem': fields.ListOfIntegersField(), + 'hw_pointer_model': fields.PointerModelField(), + 'hw_qemu_guest_agent': fields.FlexibleBooleanField(), + 'hw_rescue_bus': fields.DiskBusField(), + 'hw_rescue_device': fields.BlockDeviceTypeField(), + 'hw_rng_model': fields.RNGModelField(), + 'hw_serial_port_count': fields.IntegerField(), + 'hw_scsi_model': fields.SCSIModelField(), + 'hw_video_model': fields.VideoModelField(), + 'hw_video_ram': fields.IntegerField(), + 'hw_vif_model': fields.VIFModelField(), + 'hw_vm_mode': fields.VMModeField(), + 'hw_watchdog_action': fields.WatchdogActionField(), + 'hw_vif_multiqueue_enabled': fields.FlexibleBooleanField(), + 'img_bittorrent': fields.FlexibleBooleanField(), + 'img_bdm_v2': fields.FlexibleBooleanField(), + 'img_block_device_mapping': + fields.ListOfDictOfNullableStringsField(), + 'img_cache_in_nova': fields.FlexibleBooleanField(), + 'img_compression_level': fields.IntegerField(), + 'img_hv_requested_version': fields.VersionPredicateField(), + 'img_hv_type': fields.HVTypeField(), + 'img_config_drive': fields.ConfigDrivePolicyField(), + 'img_linked_clone': fields.FlexibleBooleanField(), + 'img_mappings': fields.ListOfDictOfNullableStringsField(), + 'img_owner_id': fields.StringField(), + 'img_root_device_name': fields.StringField(), + 'img_use_agent': fields.FlexibleBooleanField(), + 'img_version': fields.IntegerField(), + 'img_signature': fields.StringField(), + 'img_signature_hash_method': fields.ImageSignatureHashTypeField(), + 'img_signature_certificate_uuid': fields.UUIDField(), + 'img_signature_key_type': fields.ImageSignatureKeyTypeField(), + 'img_hide_hypervisor_id': fields.FlexibleBooleanField(), + 'os_admin_user': fields.StringField(), + 'os_command_line': fields.StringField(), + 'os_distro': fields.StringField(), + 'os_require_quiesce': fields.FlexibleBooleanField(), + 'os_secure_boot': fields.SecureBootField(), + 'os_skip_agent_inject_files_at_boot': fields.FlexibleBooleanField(), + 'os_skip_agent_inject_ssh': fields.FlexibleBooleanField(), + 'os_type': fields.OSTypeField(), + 'traits_required': fields.ListOfStringsField() + } + + def __init__(self, image_meta_props): + super(ImageMetaPropsPayload, self).__init__() + # NOTE(takashin): If fields are not set in the ImageMetaProps object, + # it will not set the fields in the ImageMetaPropsPayload + # in order to avoid too many fields whose values are None. + self.populate_schema(set_none=False, image_meta_props=image_meta_props) diff --git a/nova/notifications/objects/request_spec.py b/nova/notifications/objects/request_spec.py new file mode 100644 index 0000000000..f372bafcaa --- /dev/null +++ b/nova/notifications/objects/request_spec.py @@ -0,0 +1,226 @@ +# Copyright 2018 NTT Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from nova.notifications.objects import base +from nova.notifications.objects import flavor as flavor_payload +from nova.notifications.objects import image as image_payload +from nova.objects import base as nova_base +from nova.objects import fields + + +@nova_base.NovaObjectRegistry.register_notification +class RequestSpecPayload(base.NotificationPayloadBase): + # Version 1.0: Initial version + VERSION = '1.0' + + SCHEMA = { + 'instance_uuid': ('request_spec', 'instance_uuid'), + 'project_id': ('request_spec', 'project_id'), + 'user_id': ('request_spec', 'user_id'), + 'availability_zone': ('request_spec', 'availability_zone'), + 'num_instances': ('request_spec', 'num_instances') + } + + fields = { + 'instance_uuid': fields.UUIDField(), + 'project_id': fields.StringField(nullable=True), + 'user_id': fields.StringField(nullable=True), + 'availability_zone': fields.StringField(nullable=True), + 'flavor': fields.ObjectField('FlavorPayload', nullable=True), + 'image': fields.ObjectField('ImageMetaPayload', nullable=True), + 'numa_topology': fields.ObjectField('InstanceNUMATopologyPayload', + nullable=True), + 'pci_requests': fields.ObjectField('InstancePCIRequestsPayload', + nullable=True), + 'num_instances': fields.IntegerField(default=1) + } + + def __init__(self, request_spec): + super(RequestSpecPayload, self).__init__() + self.flavor = flavor_payload.FlavorPayload( + request_spec.flavor) if request_spec.obj_attr_is_set( + 'flavor') else None + self.image = image_payload.ImageMetaPayload( + request_spec.image) if request_spec.image else None + if request_spec.numa_topology is not None: + if not request_spec.numa_topology.obj_attr_is_set('instance_uuid'): + request_spec.numa_topology.instance_uuid = ( + request_spec.instance_uuid) + self.numa_topology = InstanceNUMATopologyPayload( + request_spec.numa_topology) + else: + self.numa_topology = None + if request_spec.pci_requests is not None: + if not request_spec.pci_requests.obj_attr_is_set('instance_uuid'): + request_spec.pci_requests.instance_uuid = ( + request_spec.instance_uuid) + self.pci_requests = InstancePCIRequestsPayload( + request_spec.pci_requests) + else: + self.pci_requests = None + self.populate_schema(request_spec=request_spec) + + +@nova_base.NovaObjectRegistry.register_notification +class InstanceNUMATopologyPayload(base.NotificationPayloadBase): + # Version 1.0: Initial version + VERSION = '1.0' + + SCHEMA = { + 'instance_uuid': ('numa_topology', 'instance_uuid'), + 'emulator_threads_policy': ('numa_topology', + 'emulator_threads_policy') + } + + fields = { + 'instance_uuid': fields.UUIDField(), + 'cells': fields.ListOfObjectsField('InstanceNUMACellPayload'), + 'emulator_threads_policy': fields.CPUEmulatorThreadsPolicyField( + nullable=True) + } + + def __init__(self, numa_topology): + super(InstanceNUMATopologyPayload, self).__init__() + self.cells = InstanceNUMACellPayload.from_numa_cell_list_obj( + numa_topology.cells) + self.populate_schema(numa_topology=numa_topology) + + +@nova_base.NovaObjectRegistry.register_notification +class InstanceNUMACellPayload(base.NotificationPayloadBase): + # Version 1.0: Initial version + VERSION = '1.0' + + SCHEMA = { + 'id': ('numa_cell', 'id'), + 'cpuset': ('numa_cell', 'cpuset'), + 'memory': ('numa_cell', 'memory'), + 'pagesize': ('numa_cell', 'pagesize'), + 'cpu_pinning_raw': ('numa_cell', 'cpu_pinning_raw'), + 'cpu_policy': ('numa_cell', 'cpu_policy'), + 'cpu_thread_policy': ('numa_cell', 'cpu_thread_policy'), + 'cpuset_reserved': ('numa_cell', 'cpuset_reserved'), + } + + fields = { + 'id': fields.IntegerField(), + 'cpuset': fields.SetOfIntegersField(), + 'memory': fields.IntegerField(), + 'pagesize': fields.IntegerField(nullable=True), + 'cpu_topology': fields.ObjectField('VirtCPUTopologyPayload', + nullable=True), + 'cpu_pinning_raw': fields.DictOfIntegersField(nullable=True), + 'cpu_policy': fields.CPUAllocationPolicyField(nullable=True), + 'cpu_thread_policy': fields.CPUThreadAllocationPolicyField( + nullable=True), + 'cpuset_reserved': fields.SetOfIntegersField(nullable=True) + } + + def __init__(self, numa_cell): + super(InstanceNUMACellPayload, self).__init__() + if (numa_cell.obj_attr_is_set('cpu_topology') and + numa_cell.cpu_topology is not None): + self.cpu_topology = VirtCPUTopologyPayload(numa_cell.cpu_topology) + else: + self.cpu_topology = None + self.populate_schema(numa_cell=numa_cell) + + @classmethod + def from_numa_cell_list_obj(cls, numa_cell_list): + """Returns a list of InstanceNUMACellPayload objects + based on the passed list of InstanceNUMACell objects. + """ + payloads = [] + for numa_cell in numa_cell_list: + payloads.append(cls(numa_cell)) + return payloads + + +@nova_base.NovaObjectRegistry.register_notification +class VirtCPUTopologyPayload(base.NotificationPayloadBase): + # Version 1.0: Initial version + VERSION = '1.0' + + SCHEMA = { + 'sockets': ('virt_cpu_topology', 'sockets'), + 'cores': ('virt_cpu_topology', 'cores'), + 'threads': ('virt_cpu_topology', 'threads'), + } + + fields = { + 'sockets': fields.IntegerField(nullable=True, default=1), + 'cores': fields.IntegerField(nullable=True, default=1), + 'threads': fields.IntegerField(nullable=True, default=1), + } + + def __init__(self, virt_cpu_topology): + super(VirtCPUTopologyPayload, self).__init__() + self.populate_schema(virt_cpu_topology=virt_cpu_topology) + + +@nova_base.NovaObjectRegistry.register_notification +class InstancePCIRequestsPayload(base.NotificationPayloadBase): + # Version 1.0: Initial version + VERSION = '1.0' + + SCHEMA = { + 'instance_uuid': ('pci_requests', 'instance_uuid') + } + + fields = { + 'instance_uuid': fields.UUIDField(), + 'requests': fields.ListOfObjectsField('InstancePCIRequestPayload') + } + + def __init__(self, pci_requests): + super(InstancePCIRequestsPayload, self).__init__() + self.requests = InstancePCIRequestPayload.from_pci_request_list_obj( + pci_requests.requests) + self.populate_schema(pci_requests=pci_requests) + + +@nova_base.NovaObjectRegistry.register_notification +class InstancePCIRequestPayload(base.NotificationPayloadBase): + # Version 1.0: Initial version + VERSION = '1.0' + + SCHEMA = { + 'count': ('pci_request', 'count'), + 'spec': ('pci_request', 'spec'), + 'alias_name': ('pci_request', 'alias_name'), + 'request_id': ('pci_request', 'request_id'), + 'numa_policy': ('pci_request', 'numa_policy') + } + + fields = { + 'count': fields.IntegerField(), + 'spec': fields.ListOfDictOfNullableStringsField(), + 'alias_name': fields.StringField(nullable=True), + 'request_id': fields.UUIDField(nullable=True), + 'numa_policy': fields.PCINUMAAffinityPolicyField(nullable=True) + } + + def __init__(self, pci_request): + super(InstancePCIRequestPayload, self).__init__() + self.populate_schema(pci_request=pci_request) + + @classmethod + def from_pci_request_list_obj(cls, pci_request_list): + """Returns a list of InstancePCIRequestPayload objects + based on the passed list of InstancePCIRequest objects. + """ + payloads = [] + for pci_request in pci_request_list: + payloads.append(cls(pci_request)) + return payloads |