From 01349f3793e918f21d0e8fbf285b4ba698f8987b Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Fri, 1 Dec 2023 00:00:50 +0900 Subject: [PATCH] Hide OS::Glance::Image This resource requires Glance v1 API which was already removed[1][2]. It was deprecated some time ago so we can hide it now. [1] 3dde3204d5c1b5323dba2d7b7607e69bcc58bbb2 [2] 30680961994b36ed12713c0f106b661535ce41c6 Change-Id: Ifbefdbc032c0b1ac538d68b41f13d0547b793ba5 --- .../resources/openstack/glance/image.py | 272 +----------- heat/tests/engine/test_resource_type.py | 3 +- heat/tests/openstack/glance/test_image.py | 419 +----------------- .../hide-glance-image-6855b061a8c2b8ca.yaml | 4 + 4 files changed, 25 insertions(+), 673 deletions(-) create mode 100644 releasenotes/notes/hide-glance-image-6855b061a8c2b8ca.yaml diff --git a/heat/engine/resources/openstack/glance/image.py b/heat/engine/resources/openstack/glance/image.py index 74d834523f..dd3a1e853d 100644 --- a/heat/engine/resources/openstack/glance/image.py +++ b/heat/engine/resources/openstack/glance/image.py @@ -16,6 +16,7 @@ from heat.common.i18n import _ from heat.engine import constraints from heat.engine import properties from heat.engine import resource +from heat.engine.resources.openstack.heat import none_resource from heat.engine import support @@ -338,7 +339,7 @@ class GlanceWebImage(resource.Resource): return image_reality -class GlanceImage(resource.Resource): +class GlanceImage(none_resource.NoneResource): """A resource managing images in Glance. A resource provides managing images that are meant to be used with other @@ -346,266 +347,17 @@ class GlanceImage(resource.Resource): """ support_status = support.SupportStatus( - status=support.DEPRECATED, - version='8.0.0', - message=_('Creating a Glance Image based on an existing URL location ' - 'requires the Glance v1 API, which is deprecated.'), - previous_status=support.SupportStatus(version='2014.2') - ) - - PROPERTIES = ( - NAME, IMAGE_ID, IS_PUBLIC, MIN_DISK, MIN_RAM, PROTECTED, - DISK_FORMAT, CONTAINER_FORMAT, LOCATION, TAGS, EXTRA_PROPERTIES, - ARCHITECTURE, KERNEL_ID, OS_DISTRO, OWNER, RAMDISK_ID - ) = ( - 'name', 'id', 'is_public', 'min_disk', 'min_ram', 'protected', - 'disk_format', 'container_format', 'location', 'tags', - 'extra_properties', 'architecture', 'kernel_id', 'os_distro', - 'owner', 'ramdisk_id' - ) - - glance_id_pattern = ('^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}' - '-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$') - - properties_schema = { - NAME: properties.Schema( - properties.Schema.STRING, - _('Name for the image. The name of an image is not ' - 'unique to a Image Service node.') - ), - IMAGE_ID: properties.Schema( - properties.Schema.STRING, - _('The image ID. Glance will generate a UUID if not specified.') - ), - IS_PUBLIC: properties.Schema( - properties.Schema.BOOLEAN, - _('Scope of image accessibility. Public or private. ' - 'Default value is False means private. Note: The policy ' - 'setting of glance allows only users with admin roles to create ' - 'public image by default.'), - default=False, - ), - MIN_DISK: properties.Schema( - properties.Schema.INTEGER, - _('Amount of disk space (in GB) required to boot image. ' - 'Default value is 0 if not specified ' - 'and means no limit on the disk size.'), - constraints=[ - constraints.Range(min=0), - ], - default=0 - ), - MIN_RAM: properties.Schema( - properties.Schema.INTEGER, - _('Amount of ram (in MB) required to boot image. Default value ' - 'is 0 if not specified and means no limit on the ram size.'), - constraints=[ - constraints.Range(min=0), - ], - default=0 - ), - PROTECTED: properties.Schema( - properties.Schema.BOOLEAN, - _('Whether the image can be deleted. If the value is True, ' - 'the image is protected and cannot be deleted.'), - default=False - ), - DISK_FORMAT: properties.Schema( - properties.Schema.STRING, - _('Disk format of image.'), - required=True, - constraints=[ - constraints.AllowedValues(['ami', 'ari', 'aki', - 'vhd', 'vmdk', 'raw', - 'qcow2', 'vdi', 'iso']) - ] - ), - CONTAINER_FORMAT: properties.Schema( - properties.Schema.STRING, - _('Container format of image.'), - required=True, - constraints=[ - constraints.AllowedValues(['ami', 'ari', 'aki', - 'bare', 'ova', 'ovf']) - ] - ), - LOCATION: properties.Schema( - properties.Schema.STRING, - _('URL where the data for this image already resides. For ' - 'example, if the image data is stored in swift, you could ' - 'specify "swift://example.com/container/obj".'), - required=True, - ), - TAGS: properties.Schema( - properties.Schema.LIST, - _('List of image tags.'), - update_allowed=True, - support_status=support.SupportStatus(version='7.0.0') - ), - EXTRA_PROPERTIES: properties.Schema( - properties.Schema.MAP, - _('Arbitrary properties to associate with the image.'), - update_allowed=True, - default={}, - support_status=support.SupportStatus(version='7.0.0') - ), - ARCHITECTURE: properties.Schema( - properties.Schema.STRING, - _('Operating system architecture.'), - update_allowed=True, - support_status=support.SupportStatus(version='7.0.0') - ), - KERNEL_ID: properties.Schema( - properties.Schema.STRING, - _('ID of image stored in Glance that should be used as ' - 'the kernel when booting an AMI-style image.'), - update_allowed=True, - support_status=support.SupportStatus(version='7.0.0'), - constraints=[ - constraints.AllowedPattern(glance_id_pattern) - ] - ), - OS_DISTRO: properties.Schema( - properties.Schema.STRING, - _('The common name of the operating system distribution ' - 'in lowercase.'), - update_allowed=True, - support_status=support.SupportStatus(version='7.0.0') - ), - OWNER: properties.Schema( - properties.Schema.STRING, - _('Owner of the image.'), - update_allowed=True, - support_status=support.SupportStatus(version='7.0.0') - ), - RAMDISK_ID: properties.Schema( - properties.Schema.STRING, - _('ID of image stored in Glance that should be used as ' - 'the ramdisk when booting an AMI-style image.'), - update_allowed=True, - support_status=support.SupportStatus(version='7.0.0'), - constraints=[ - constraints.AllowedPattern(glance_id_pattern) - ] + status=support.HIDDEN, + version='22.0.0', + previous_status=support.SupportStatus( + status=support.DEPRECATED, + version='8.0.0', + message=_( + 'Creating a Glance Image based on an existing URL location ' + 'requires the Glance v1 API, which is deprecated.'), + previous_status=support.SupportStatus(version='2014.2') ) - } - - default_client_name = 'glance' - - entity = 'images' - - def handle_create(self): - args = dict((k, v) for k, v in self.properties.items() - if v is not None) - - tags = args.pop(self.TAGS, []) - args['properties'] = args.pop(self.EXTRA_PROPERTIES, {}) - architecture = args.pop(self.ARCHITECTURE, None) - kernel_id = args.pop(self.KERNEL_ID, None) - os_distro = args.pop(self.OS_DISTRO, None) - ramdisk_id = args.pop(self.RAMDISK_ID, None) - - image_id = self.client(version=self.client_plugin().V1).images.create( - **args).id - self.resource_id_set(image_id) - - images = self.client().images - if architecture is not None: - images.update(image_id, architecture=architecture) - if kernel_id is not None: - images.update(image_id, kernel_id=kernel_id) - if os_distro is not None: - images.update(image_id, os_distro=os_distro) - if ramdisk_id is not None: - images.update(image_id, ramdisk_id=ramdisk_id) - - for tag in tags: - self.client().image_tags.update( - image_id, - tag) - - return image_id - - def check_create_complete(self, image_id): - image = self.client().images.get(image_id) - return image.status == 'active' - - def handle_update(self, json_snippet, tmpl_diff, prop_diff): - if prop_diff and self.TAGS in prop_diff: - existing_tags = self.properties.get(self.TAGS) or [] - diff_tags = prop_diff.pop(self.TAGS) or [] - - new_tags = set(diff_tags) - set(existing_tags) - for tag in new_tags: - self.client().image_tags.update( - self.resource_id, - tag) - - removed_tags = set(existing_tags) - set(diff_tags) - for tag in removed_tags: - with self.client_plugin().ignore_not_found: - self.client().image_tags.delete( - self.resource_id, - tag) - - images = self.client().images - - if self.EXTRA_PROPERTIES in prop_diff: - old_properties = self.properties.get(self.EXTRA_PROPERTIES) or {} - new_properties = prop_diff.pop(self.EXTRA_PROPERTIES) - prop_diff.update(new_properties) - remove_props = list(set(old_properties) - set(new_properties)) - - # Though remove_props defaults to None within the glanceclient, - # setting it to a list (possibly []) every time ensures only one - # calling format to images.update - images.update(self.resource_id, remove_props, **prop_diff) - else: - images.update(self.resource_id, **prop_diff) - - def validate(self): - super(GlanceImage, self).validate() - container_format = self.properties[self.CONTAINER_FORMAT] - if (container_format in ['ami', 'ari', 'aki'] - and self.properties[self.DISK_FORMAT] != container_format): - msg = _("Invalid mix of disk and container formats. When " - "setting a disk or container format to one of 'aki', " - "'ari', or 'ami', the container and disk formats must " - "match.") - raise exception.StackValidationFailed(message=msg) - - def get_live_resource_data(self): - image_data = super(GlanceImage, self).get_live_resource_data() - if image_data.get('status') in ('deleted', 'killed'): - raise exception.EntityNotFound(entity='Resource', - name=self.name) - return image_data - - def parse_live_resource_data(self, resource_properties, resource_data): - image_reality = {} - - # NOTE(prazumovsky): At first, there's no way to get location from - # glance; at second, location property is doubtful, because glance - # client v2 doesn't use location, it uses locations. So, we should - # get location property from resource properties. - if self.client().version == 1.0: - image_reality.update( - {self.LOCATION: resource_properties[self.LOCATION]}) - - for key in self.PROPERTIES: - if key == self.LOCATION: - continue - if key == self.IMAGE_ID: - if (resource_properties.get(self.IMAGE_ID) is not None or - resource_data.get(self.IMAGE_ID) != self.resource_id): - image_reality.update({self.IMAGE_ID: resource_data.get( - self.IMAGE_ID)}) - else: - image_reality.update({self.IMAGE_ID: None}) - else: - image_reality.update({key: resource_data.get(key)}) - - return image_reality + ) def resource_mapping(): diff --git a/heat/tests/engine/test_resource_type.py b/heat/tests/engine/test_resource_type.py index 770a357ffa..eab8ea8fa5 100644 --- a/heat/tests/engine/test_resource_type.py +++ b/heat/tests/engine/test_resource_type.py @@ -42,8 +42,7 @@ class ResourceTypeTest(common.HeatTestCase): mock_is_service_available): mock_is_service_available.return_value = (True, None) resources = self.eng.list_resource_types(self.ctx, "DEPRECATED") - self.assertEqual(set(['OS::Aodh::Alarm', - 'OS::Glance::Image']), + self.assertEqual(set(['OS::Aodh::Alarm']), set(resources)) @mock.patch.object(res.Resource, 'is_service_available') diff --git a/heat/tests/openstack/glance/test_image.py b/heat/tests/openstack/glance/test_image.py index 275bad39a7..294672e0bb 100644 --- a/heat/tests/openstack/glance/test_image.py +++ b/heat/tests/openstack/glance/test_image.py @@ -21,42 +21,6 @@ from heat.engine import template from heat.tests import common from heat.tests import utils -image_template = ''' -heat_template_version: 2013-05-23 -description: This template to define a glance image. -resources: - my_image: - type: OS::Glance::Image - properties: - name: cirros_image - id: 41f0e60c-ebb4-4375-a2b4-845ae8b9c995 - disk_format: qcow2 - container_format: bare - is_public: True - min_disk: 10 - min_ram: 512 - protected: False - location: https://launchpad.net/cirros/cirros-0.3.0-x86_64-disk.img - architecture: test_architecture - kernel_id: 12345678-1234-1234-1234-123456789012 - os_distro: test_distro - owner: test_owner - ramdisk_id: 12345678-1234-1234-1234-123456789012 -''' - -image_template_validate = ''' -heat_template_version: 2013-05-23 -description: This template to define a glance image. -resources: - image: - type: OS::Glance::Image - properties: - name: image_validate - disk_format: qcow2 - container_format: bare - location: https://launchpad.net/cirros/cirros-0.3.0-x86_64-disk.img -''' - image_download_template = ''' heat_template_version: rocky description: This template to define a glance image. @@ -93,373 +57,6 @@ resources: ''' -class GlanceImageTest(common.HeatTestCase): - def setUp(self): - super(GlanceImageTest, self).setUp() - - self.ctx = utils.dummy_context() - tpl = template_format.parse(image_template) - self.stack = parser.Stack( - self.ctx, 'glance_image_test_stack', - template.Template(tpl) - ) - - self.my_image = self.stack['my_image'] - glance = mock.MagicMock() - self.glanceclient = mock.MagicMock() - self.my_image.client = glance - glance.return_value = self.glanceclient - self.images = self.glanceclient.images - self.image_tags = self.glanceclient.image_tags - self.image_members = self.glanceclient.image_members - - def _test_validate(self, resource, error_msg): - exc = self.assertRaises(exception.StackValidationFailed, - resource.validate) - self.assertIn(error_msg, str(exc)) - - def test_invalid_min_disk(self): - # invalid 'min_disk' - tpl = template_format.parse(image_template_validate) - stack = parser.Stack( - self.ctx, 'glance_image_stack_validate', - template.Template(tpl) - ) - image = stack['image'] - props = stack.t.t['resources']['image']['properties'].copy() - props['min_disk'] = -1 - image.t = image.t.freeze(properties=props) - image.reparse() - error_msg = ('Property error: resources.image.properties.min_disk: ' - '-1 is out of range (min: 0, max: None)') - self._test_validate(image, error_msg) - - def test_invalid_min_ram(self): - # invalid 'min_ram' - tpl = template_format.parse(image_template_validate) - stack = parser.Stack( - self.ctx, 'glance_image_stack_validate', - template.Template(tpl) - ) - image = stack['image'] - props = stack.t.t['resources']['image']['properties'].copy() - props['min_ram'] = -1 - image.t = image.t.freeze(properties=props) - image.reparse() - error_msg = ('Property error: resources.image.properties.min_ram: ' - '-1 is out of range (min: 0, max: None)') - self._test_validate(image, error_msg) - - def test_miss_disk_format(self): - # miss disk_format - tpl = template_format.parse(image_template_validate) - stack = parser.Stack( - self.ctx, 'glance_image_stack_validate', - template.Template(tpl) - ) - image = stack['image'] - props = stack.t.t['resources']['image']['properties'].copy() - del props['disk_format'] - image.t = image.t.freeze(properties=props) - image.reparse() - error_msg = 'Property disk_format not assigned' - self._test_validate(image, error_msg) - - def test_invalid_disk_format(self): - # invalid disk_format - tpl = template_format.parse(image_template_validate) - stack = parser.Stack( - self.ctx, 'glance_image_stack_validate', - template.Template(tpl) - ) - image = stack['image'] - props = stack.t.t['resources']['image']['properties'].copy() - props['disk_format'] = 'incorrect_format' - image.t = image.t.freeze(properties=props) - image.reparse() - error_msg = ('resources.image.properties.disk_format: ' - '"incorrect_format" is not an allowed value') - self._test_validate(image, error_msg) - - def test_miss_container_format(self): - # miss container_format - tpl = template_format.parse(image_template_validate) - stack = parser.Stack( - self.ctx, 'glance_image_stack_validate', - template.Template(tpl) - ) - image = stack['image'] - props = stack.t.t['resources']['image']['properties'].copy() - del props['container_format'] - image.t = image.t.freeze(properties=props) - image.reparse() - error_msg = 'Property container_format not assigned' - self._test_validate(image, error_msg) - - def test_invalid_container_format(self): - # invalid container_format - tpl = template_format.parse(image_template_validate) - stack = parser.Stack( - self.ctx, 'glance_image_stack_validate', - template.Template(tpl) - ) - image = stack['image'] - props = stack.t.t['resources']['image']['properties'].copy() - props['container_format'] = 'incorrect_format' - image.t = image.t.freeze(properties=props) - image.reparse() - error_msg = ('resources.image.properties.container_format: ' - '"incorrect_format" is not an allowed value') - self._test_validate(image, error_msg) - - def test_miss_location(self): - # miss location - tpl = template_format.parse(image_template_validate) - stack = parser.Stack( - self.ctx, 'glance_image_stack_validate', - template.Template(tpl) - ) - image = stack['image'] - props = stack.t.t['resources']['image']['properties'].copy() - del props['location'] - image.t = image.t.freeze(properties=props) - image.reparse() - error_msg = 'Property location not assigned' - self._test_validate(image, error_msg) - - def test_invalid_disk_container_mix(self): - tpl = template_format.parse(image_template_validate) - stack = parser.Stack( - self.ctx, 'glance_image_stack_validate', - template.Template(tpl) - ) - image = stack['image'] - props = stack.t.t['resources']['image']['properties'].copy() - props['disk_format'] = 'raw' - props['container_format'] = 'ari' - image.t = image.t.freeze(properties=props) - image.reparse() - error_msg = ("Invalid mix of disk and container formats. When " - "setting a disk or container format to one of 'aki', " - "'ari', or 'ami', the container and disk formats must " - "match.") - self._test_validate(image, error_msg) - - def test_image_handle_create(self): - value = mock.MagicMock() - image_id = '41f0e60c-ebb4-4375-a2b4-845ae8b9c995' - value.id = image_id - self.images.create.return_value = value - self.image_tags.update.return_value = None - props = self.stack.t.t['resources']['my_image']['properties'].copy() - props['tags'] = ['tag1'] - self.my_image.t = self.my_image.t.freeze(properties=props) - self.my_image.reparse() - self.my_image.handle_create() - - self.assertEqual(image_id, self.my_image.resource_id) - # assert that no tags pass when image create - self.images.create.assert_called_once_with( - container_format=u'bare', - disk_format=u'qcow2', - id=u'41f0e60c-ebb4-4375-a2b4-845ae8b9c995', - is_public=True, - location=u'https://launchpad.net/cirros/' - u'cirros-0.3.0-x86_64-disk.img', - min_disk=10, - min_ram=512, - name=u'cirros_image', - protected=False, - owner=u'test_owner', - properties={} - ) - self.image_tags.update.assert_called_once_with( - self.my_image.resource_id, - 'tag1') - calls = [mock.call(self.my_image.resource_id, - architecture='test_architecture'), - mock.call(self.my_image.resource_id, - kernel_id='12345678-1234-1234-1234-123456789012'), - mock.call(self.my_image.resource_id, - os_distro='test_distro'), - mock.call(self.my_image.resource_id, - ramdisk_id='12345678-1234-1234-1234-123456789012'), - ] - self.images.update.assert_has_calls(calls) - - def _handle_update_tags(self, prop_diff): - self.my_image.handle_update(json_snippet=None, - tmpl_diff=None, - prop_diff=prop_diff) - - self.image_tags.update.assert_called_once_with( - self.my_image.resource_id, - 'tag2' - ) - self.image_tags.delete.assert_called_once_with( - self.my_image.resource_id, - 'tag1' - ) - - def test_image_handle_update(self): - self.my_image.resource_id = '477e8273-60a7-4c41-b683-fdb0bc7cd151' - prop_diff = { - 'architecture': 'test_architecture', - 'kernel_id': '12345678-1234-1234-1234-123456789012', - 'os_distro': 'test_distro', - 'owner': 'test_owner', - 'ramdisk_id': '12345678-1234-1234-1234-123456789012', - 'extra_properties': {'key1': 'value1', 'key2': 'value2'}} - - self.my_image.handle_update(json_snippet=None, - tmpl_diff=None, - prop_diff=prop_diff) - self.images.update.assert_called_once_with( - self.my_image.resource_id, - [], - architecture='test_architecture', - kernel_id='12345678-1234-1234-1234-123456789012', - os_distro='test_distro', - owner='test_owner', - ramdisk_id='12345678-1234-1234-1234-123456789012', - key1='value1', key2='value2' - ) - - def test_image_handle_update_tags(self): - self.my_image.resource_id = '477e8273-60a7-4c41-b683-fdb0bc7cd151' - - props = self.stack.t.t['resources']['my_image']['properties'].copy() - props['tags'] = ['tag1'] - self.my_image.t = self.my_image.t.freeze(properties=props) - self.my_image.reparse() - prop_diff = {'tags': ['tag2']} - - self._handle_update_tags(prop_diff) - - def test_image_handle_update_remove_tags(self): - self.my_image.resource_id = '477e8273-60a7-4c41-b683-fdb0bc7cd151' - - props = self.stack.t.t['resources']['my_image']['properties'].copy() - props['tags'] = ['tag1'] - self.my_image.t = self.my_image.t.freeze(properties=props) - self.my_image.reparse() - prop_diff = {'tags': None} - - self.my_image.handle_update(json_snippet=None, - tmpl_diff=None, - prop_diff=prop_diff) - - self.image_tags.delete.assert_called_once_with( - self.my_image.resource_id, - 'tag1' - ) - - def test_image_handle_update_tags_delete_not_found(self): - self.my_image.resource_id = '477e8273-60a7-4c41-b683-fdb0bc7cd151' - - props = self.stack.t.t['resources']['my_image']['properties'].copy() - props['tags'] = ['tag1'] - self.my_image.t = self.my_image.t.freeze(properties=props) - self.my_image.reparse() - prop_diff = {'tags': ['tag2']} - - self.image_tags.delete.side_effect = exc.HTTPNotFound() - - self._handle_update_tags(prop_diff) - - def test_image_show_resource_v1(self): - self.glanceclient.version = 1.0 - self.my_image.resource_id = 'test_image_id' - image = mock.MagicMock() - images = mock.MagicMock() - image.to_dict.return_value = {'image': 'info'} - images.get.return_value = image - self.my_image.client().images = images - self.assertEqual({'image': 'info'}, self.my_image.FnGetAtt('show')) - images.get.assert_called_once_with('test_image_id') - - def test_image_show_resource_v2(self): - self.my_image.resource_id = 'test_image_id' - # glance image in v2 is warlock.model object, so it can be - # handled via dict(). In test we use easiest analog - dict. - image = {"key1": "val1", "key2": "val2"} - self.images.get.return_value = image - self.glanceclient.version = 2.0 - self.assertEqual({"key1": "val1", "key2": "val2"}, - self.my_image.FnGetAtt('show')) - self.images.get.assert_called_once_with('test_image_id') - - def test_image_get_live_state_v1(self): - self._test_image_get_live_state(1.0) - - def test_image_get_live_state_v2(self): - self._test_image_get_live_state(2.0) - - def _test_image_get_live_state(self, version): - self.glanceclient.version = version - self.my_image.resource_id = '1234' - images = mock.MagicMock() - show_value = { - 'name': 'test', - 'disk_format': 'qcow2', - 'container_format': 'bare', - 'protected': False, - 'is_public': False, - 'min_disk': 0, - 'min_ram': 0, - 'id': '41f0e60c-ebb4-4375-a2b4-845ae8b9c995', - 'tags': [], - 'extra_properties': {}, - 'architecture': 'test_architecture', - 'kernel_id': '12345678-1234-1234-1234-123456789012', - 'os_distro': 'test_distro', - 'owner': 'test_owner', - 'ramdisk_id': '12345678-1234-1234-1234-123456789012' - } - if version == 1.0: - image = mock.MagicMock() - image.to_dict.return_value = show_value - else: - image = show_value - images.get.return_value = image - self.my_image.client().images = images - if version == 1.0: - self.my_image.properties.data.update( - {self.my_image.LOCATION: 'stub'}) - - reality = self.my_image.get_live_state(self.my_image.properties) - expected = { - 'name': 'test', - 'disk_format': 'qcow2', - 'container_format': 'bare', - 'protected': False, - 'is_public': False, - 'min_disk': 0, - 'min_ram': 0, - 'id': '41f0e60c-ebb4-4375-a2b4-845ae8b9c995', - 'tags': [], - 'extra_properties': {}, - 'architecture': 'test_architecture', - 'kernel_id': '12345678-1234-1234-1234-123456789012', - 'os_distro': 'test_distro', - 'owner': 'test_owner', - 'ramdisk_id': '12345678-1234-1234-1234-123456789012' - } - if version == 1.0: - expected.update({'location': 'stub'}) - - self.assertEqual(set(expected.keys()), set(reality.keys())) - for key in expected: - self.assertEqual(expected[key], reality[key]) - - def test_get_live_state_resource_is_deleted(self): - self.my_image.resource_id = '1234' - self.my_image.client().images.get.return_value = {'status': 'deleted'} - self.assertRaises(exception.EntityNotFound, - self.my_image.get_live_state, - self.my_image.properties) - - class GlanceWebImageTest(common.HeatTestCase): def setUp(self): super(GlanceWebImageTest, self).setUp() @@ -488,7 +85,7 @@ class GlanceWebImageTest(common.HeatTestCase): def test_invalid_min_disk(self): # invalid 'min_disk' - tpl = template_format.parse(image_template_validate) + tpl = template_format.parse(image_download_template_validate) stack = parser.Stack( self.ctx, 'glance_image_stack_validate', template.Template(tpl) @@ -504,7 +101,7 @@ class GlanceWebImageTest(common.HeatTestCase): def test_invalid_min_ram(self): # invalid 'min_ram' - tpl = template_format.parse(image_template_validate) + tpl = template_format.parse(image_download_template_validate) stack = parser.Stack( self.ctx, 'glance_image_stack_validate', template.Template(tpl) @@ -520,7 +117,7 @@ class GlanceWebImageTest(common.HeatTestCase): def test_miss_disk_format(self): # miss disk_format - tpl = template_format.parse(image_template_validate) + tpl = template_format.parse(image_download_template_validate) stack = parser.Stack( self.ctx, 'glance_image_stack_validate', template.Template(tpl) @@ -535,7 +132,7 @@ class GlanceWebImageTest(common.HeatTestCase): def test_invalid_disk_format(self): # invalid disk_format - tpl = template_format.parse(image_template_validate) + tpl = template_format.parse(image_download_template_validate) stack = parser.Stack( self.ctx, 'glance_image_stack_validate', template.Template(tpl) @@ -552,7 +149,7 @@ class GlanceWebImageTest(common.HeatTestCase): def test_miss_container_format(self): # miss container_format - tpl = template_format.parse(image_template_validate) + tpl = template_format.parse(image_download_template_validate) stack = parser.Stack( self.ctx, 'glance_image_stack_validate', template.Template(tpl) @@ -567,7 +164,7 @@ class GlanceWebImageTest(common.HeatTestCase): def test_invalid_container_format(self): # invalid container_format - tpl = template_format.parse(image_template_validate) + tpl = template_format.parse(image_download_template_validate) stack = parser.Stack( self.ctx, 'glance_image_stack_validate', template.Template(tpl) @@ -584,7 +181,7 @@ class GlanceWebImageTest(common.HeatTestCase): def test_miss_location(self): # miss location - tpl = template_format.parse(image_template_validate) + tpl = template_format.parse(image_download_template_validate) stack = parser.Stack( self.ctx, 'glance_image_stack_validate', template.Template(tpl) @@ -598,7 +195,7 @@ class GlanceWebImageTest(common.HeatTestCase): self._test_validate(image, error_msg) def test_invalid_disk_container_mix(self): - tpl = template_format.parse(image_template_validate) + tpl = template_format.parse(image_download_template_validate) stack = parser.Stack( self.ctx, 'glance_image_stack_validate', template.Template(tpl) diff --git a/releasenotes/notes/hide-glance-image-6855b061a8c2b8ca.yaml b/releasenotes/notes/hide-glance-image-6855b061a8c2b8ca.yaml new file mode 100644 index 0000000000..b16cd07cbe --- /dev/null +++ b/releasenotes/notes/hide-glance-image-6855b061a8c2b8ca.yaml @@ -0,0 +1,4 @@ +--- +upgrade: + - | + The ``OS::Glance::Image`` type is now hidden.