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

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. 

14 

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 

19 

20 

21@nova_base.NovaObjectRegistry.register_notification 

22class ImageMetaPayload(base.NotificationPayloadBase): 

23 # Version 1.0: Initial version 

24 VERSION = '1.0' 

25 

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 } 

45 

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 } 

98 

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) 

104 

105 

106@nova_base.NovaObjectRegistry.register_notification 

107class ImageMetaPropsPayload(base.NotificationPayloadBase): 

108 """Built dynamically from ImageMetaProps. 

109 

110 This has the following implications: 

111 

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' 

137 

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',)} 

147 

148 SCHEMA = { 

149 k: ('image_meta_props', k) for k in fields} 

150 

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)