def _test_update_store_in_location(self, metadata, store_id, expected): locations = [{'url': 'rbd://aaaaaaaa/images/id', 'metadata': metadata}] with mock.patch.object(store_utils, '_get_store_id_from_uri') as mock_get_store_id: mock_get_store_id.return_value = store_id store_utils.update_store_in_locations(locations, mock.Mock()) self.assertEqual(locations[0]['metadata'].get('store'), expected)
def wrapped(context, image, **kwargs): image_repo = kwargs.get('image_repo') if CONF.enabled_backends: store_utils.update_store_in_locations(image.locations, image.image_id) image_repo.save(image) return func(context, image, **kwargs)
def get(self, image_id): image = super(ImageRepoProxy, self).get(image_id) if CONF.enabled_backends: try: store_utils.update_store_in_locations(self.context, image, self.image_repo) except exception.Forbidden: # NOTE(danms): We may not be able to complete a store # update if we do not own the image. That should not # break us, so avoid raising Forbidden in that # case. Note that modifications to @image here will # still be returned to the user, just not saved in the # DB. That is probably what we want anyway. pass return image
def _test_update_cinder_store_in_location(self, mock_url_prefix, mock_associate_store, is_valid=True): volume_id = 'db457a25-8f16-4b2c-a644-eae8d17fe224' store_id = 'fast-cinder' expected = 'fast-cinder' image = mock.Mock() image_repo = mock.Mock() image_repo.save = mock.Mock() context = mock.Mock() mock_associate_store.return_value = is_valid locations = [{'url': 'cinder://%s' % volume_id, 'metadata': {}}] mock_url_prefix.return_value = 'cinder://%s' % store_id image.locations = locations store_utils.update_store_in_locations(context, image, image_repo) if is_valid: # This is the case where we found an image that has an # old-style URL which does not include the store name, # but for which we know the corresponding store that # refers to the volume type that backs it. We expect that # the URL should be updated to point to the store/volume from # just a naked pointer to the volume, as was the old # format i.e. this is the case when store is valid and location # url, metadata are updated and image_repo.save is called expected_url = mock_url_prefix.return_value + '/' + volume_id self.assertEqual(expected_url, image.locations[0].get('url')) self.assertEqual(expected, image.locations[0]['metadata'].get('store')) self.assertEqual(1, image_repo.save.call_count) else: # Here, we've got an image backed by a volume which does # not have a corresponding store specifying the volume_type. # Expect that we leave these alone and do not touch the # location URL since we cannot update it with a valid store i.e. # this is the case when store is invalid and location url, # metadata are not updated and image_repo.save is not called self.assertEqual(locations[0]['url'], image.locations[0].get('url')) self.assertEqual({}, image.locations[0]['metadata']) self.assertEqual(0, image_repo.save.call_count)
def _test_update_store_in_location(self, metadata, store_id, expected, store_id_call_count=1, save_call_count=1): image = mock.Mock() image_repo = mock.Mock() image_repo.save = mock.Mock() context = mock.Mock() locations = [{'url': 'rbd://aaaaaaaa/images/id', 'metadata': metadata}] image.locations = locations with mock.patch.object(store_utils, '_get_store_id_from_uri') as mock_get_store_id: mock_get_store_id.return_value = store_id store_utils.update_store_in_locations(context, image, image_repo) self.assertEqual(image.locations[0]['metadata'].get('store'), expected) self.assertEqual(store_id_call_count, mock_get_store_id.call_count) self.assertEqual(save_call_count, image_repo.save.call_count)
def wrapped(context, image, image_repo, **kwargs): if CONF.enabled_backends: store_utils.update_store_in_locations(context, image, image_repo) return func(context, image, image_repo, **kwargs)