diff --git a/src/lib/charm/openstack/octavia_diskimage_retrofit.py b/src/lib/charm/openstack/octavia_diskimage_retrofit.py index 3504a6f..5b7de33 100644 --- a/src/lib/charm/openstack/octavia_diskimage_retrofit.py +++ b/src/lib/charm/openstack/octavia_diskimage_retrofit.py @@ -27,6 +27,14 @@ import charm.openstack.glance_retrofitter as glance_retrofitter TMPDIR = '/var/snap/octavia-diskimage-retrofit/common/tmp' +class SourceImageNotFound(Exception): + pass + + +class DestinationImageExists(Exception): + pass + + class OctaviaDiskimageRetrofitCharm(charms_openstack.charm.OpenStackCharm): release = 'rocky' name = 'octavia-diskimage-retrofit' @@ -54,28 +62,30 @@ class OctaviaDiskimageRetrofitCharm(charms_openstack.charm.OpenStackCharm): :type force: bool :param image_id: Use specific source image for retrofitting :type image_id: str - :raises:Exception + :raises:SourceImageNotFound,DestinationImageExists """ session = glance_retrofitter.session_from_identity_credentials( keystone_endpoint) glance = glance_retrofitter.get_glance_client(session) if image_id: - source_image = glance.images.list(filters={'id': image_id}) + source_image = next(glance.images.list(filters={'id': image_id})) else: source_image = glance_retrofitter.find_source_image(glance) if not source_image: - raise Exception('unable to find suitable source image') + raise SourceImageNotFound('unable to find suitable source image') if not image_id: - existing_image = glance_retrofitter.find_destination_image( - glance, source_image.product_name, source_image.version_name) - if existing_image and not force: - raise Exception('image with product_name "{}" and ' - 'version_name "{}" already exists: "{}"' - .format(source_image.product_name, - source_image.version_name, - existing_image.id)) + for image in glance_retrofitter.find_destination_image( + glance, + source_image.product_name, + source_image.version_name): + if not force: + raise DestinationImageExists( + 'image with product_name "{}" and ' + 'version_name "{}" already exists: "{}"' + .format(source_image.product_name, + source_image.version_name, image.id)) input_file = tempfile.NamedTemporaryFile(delete=False, dir=TMPDIR) ch_core.hookenv.atexit(os.unlink, input_file.name) diff --git a/unit_tests/test_lib_charm_openstack_octavia_diskimage_retrofit.py b/unit_tests/test_lib_charm_openstack_octavia_diskimage_retrofit.py index 12e0f73..4610038 100644 --- a/unit_tests/test_lib_charm_openstack_octavia_diskimage_retrofit.py +++ b/unit_tests/test_lib_charm_openstack_octavia_diskimage_retrofit.py @@ -68,13 +68,17 @@ class TestOctaviaDiskimageRetrofitCharm(test_utils.PatchHelper): c = octavia_diskimage_retrofit.OctaviaDiskimageRetrofitCharm() with mock.patch('charm.openstack.octavia_diskimage_retrofit.open', create=True) as mocked_open: + self.glance_retrofitter.find_destination_image.return_value = \ + [fake_image] with self.assertRaises(Exception): c.retrofit('aKeystone') self.glance_retrofitter.session_from_identity_credentials.\ assert_called_once_with('aKeystone') self.glance_retrofitter.get_glance_client.assert_called_once_with( self.glance_retrofitter.session_from_identity_credentials()) - self.glance_retrofitter.find_destination_image.return_value = None + + self.glance_retrofitter.find_destination_image.return_value = \ + [] c.retrofit('aKeystone') self.NamedTemporaryFile.assert_has_calls([ mock.call(delete=False,