Coverage for nova/notifications/objects/image.py: 76%
21 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-24 11:16 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-24 11:16 +0000
1# Copyright 2018 NTT Corporation
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
15from nova.notifications.objects import base
16from nova.objects import base as nova_base
17from nova.objects import fields
18from nova.objects import image_meta
21@nova_base.NovaObjectRegistry.register_notification
22class ImageMetaPayload(base.NotificationPayloadBase):
23 # Version 1.0: Initial version
24 VERSION = '1.0'
26 SCHEMA = {
27 'id': ('image_meta', 'id'),
28 'name': ('image_meta', 'name'),
29 'status': ('image_meta', 'status'),
30 'visibility': ('image_meta', 'visibility'),
31 'protected': ('image_meta', 'protected'),
32 'checksum': ('image_meta', 'checksum'),
33 'owner': ('image_meta', 'owner'),
34 'size': ('image_meta', 'size'),
35 'virtual_size': ('image_meta', 'virtual_size'),
36 'container_format': ('image_meta', 'container_format'),
37 'disk_format': ('image_meta', 'disk_format'),
38 'created_at': ('image_meta', 'created_at'),
39 'updated_at': ('image_meta', 'updated_at'),
40 'tags': ('image_meta', 'tags'),
41 'direct_url': ('image_meta', 'direct_url'),
42 'min_ram': ('image_meta', 'min_ram'),
43 'min_disk': ('image_meta', 'min_disk')
44 }
46 # NOTE(takashin): The reason that each field is nullable is as follows.
47 #
48 # a. It is defined as "The value might be null (JSON null data type)."
49 # in the "Show image" API (GET /v2/images/{image_id})
50 # in the glance API v2 Reference.
51 # (https://docs.openstack.org/api-ref/image/v2/index.html)
52 #
53 # * checksum
54 # * container_format
55 # * disk_format
56 # * min_disk
57 # * min_ram
58 # * name
59 # * owner
60 # * size
61 # * updated_at
62 # * virtual_size
63 #
64 # b. It is optional in the response from glance.
65 # * direct_url
66 #
67 # a. It is defined as nullable in the ImageMeta object.
68 # * created_at
69 #
70 # c. It cannot be got in the boot from volume case.
71 # See VIM_IMAGE_ATTRIBUTES in nova/block_device.py.
72 #
73 # * id (not 'image_id')
74 # * visibility
75 # * protected
76 # * status
77 # * tags
78 fields = {
79 'id': fields.UUIDField(nullable=True),
80 'name': fields.StringField(nullable=True),
81 'status': fields.StringField(nullable=True),
82 'visibility': fields.StringField(nullable=True),
83 'protected': fields.FlexibleBooleanField(nullable=True),
84 'checksum': fields.StringField(nullable=True),
85 'owner': fields.StringField(nullable=True),
86 'size': fields.IntegerField(nullable=True),
87 'virtual_size': fields.IntegerField(nullable=True),
88 'container_format': fields.StringField(nullable=True),
89 'disk_format': fields.StringField(nullable=True),
90 'created_at': fields.DateTimeField(nullable=True),
91 'updated_at': fields.DateTimeField(nullable=True),
92 'tags': fields.ListOfStringsField(nullable=True),
93 'direct_url': fields.StringField(nullable=True),
94 'min_ram': fields.IntegerField(nullable=True),
95 'min_disk': fields.IntegerField(nullable=True),
96 'properties': fields.ObjectField('ImageMetaPropsPayload')
97 }
99 def __init__(self, image_meta):
100 super(ImageMetaPayload, self).__init__()
101 self.properties = ImageMetaPropsPayload(
102 image_meta_props=image_meta.properties)
103 self.populate_schema(image_meta=image_meta)
106@nova_base.NovaObjectRegistry.register_notification
107class ImageMetaPropsPayload(base.NotificationPayloadBase):
108 """Built dynamically from ImageMetaProps.
110 This has the following implications:
112 * When you make a versioned update to ImageMetaProps, you must *also* bump
113 the version of this object, even though you didn't make any explicit
114 changes here. There's an object hash test that should catch this for you.
115 * As currently written, this relies on all of the fields of ImageMetaProps
116 being initialized with no arguments. If you add one with arguments (e.g.
117 ``nullable=True`` or with a ``default``), something needs to change here.
118 """
119 # Version 1.0: Initial version
120 # Version 1.1: Added 'gop', 'virtio' and 'none' to hw_video_model field
121 # Version 1.2: Added hw_pci_numa_affinity_policy field
122 # Version 1.3: Added hw_mem_encryption, hw_pmu and hw_time_hpet fields
123 # Version 1.4: Added 'mixed' to hw_cpu_policy field
124 # Version 1.5: Added 'hw_tpm_model' and 'hw_tpm_version' fields
125 # Version 1.6: Added 'socket' to hw_pci_numa_affinity_policy
126 # Version 1.7: Added 'hw_input_bus' field
127 # Version 1.8: Added 'bochs' as an option to 'hw_video_model'
128 # Version 1.9: Added 'hw_emulation_architecture' field
129 # Version 1.10: Added 'hw_ephemeral_encryption' and
130 # 'hw_ephemeral_encryption_format' fields
131 # Version 1.11: Added 'hw_locked_memory' field
132 # Version 1.12: Added 'hw_viommu_model' field
133 # Version 1.13: Added 'hw_virtio_packed_ring' field
134 # Version 1.14: Added 'hw_firmware_stateless' field
135 # Version 1.15: Added igb value to 'hw_vif_model' enum
136 VERSION = '1.15'
138 # NOTE(efried): This logic currently relies on all of the fields of
139 # ImageMetaProps being initialized with no arguments. See the docstring.
140 # NOTE(efried): It's possible this could just be:
141 # fields = image_meta.ImageMetaProps.fields
142 # But it is not clear that OVO can tolerate the same *instance* of a type
143 # class being used in more than one place.
144 fields = {
145 k: v.__class__() for k, v in image_meta.ImageMetaProps.fields.items()
146 if k not in ('hw_ephemeral_encryption_secret_uuid',)}
148 SCHEMA = {
149 k: ('image_meta_props', k) for k in fields}
151 def __init__(self, image_meta_props):
152 super(ImageMetaPropsPayload, self).__init__()
153 # NOTE(takashin): If fields are not set in the ImageMetaProps object,
154 # it will not set the fields in the ImageMetaPropsPayload
155 # in order to avoid too many fields whose values are None.
156 self.populate_schema(set_none=False, image_meta_props=image_meta_props)