Make copy_image plugin use action wrapper
This makes the copy_image plugin use the action wrapper for its manipulation of the image, in line with all the others. This adds image_size and image_locations properties to the wrapper, which copy-image needs. Change-Id: Id5251b77fe1671594912e0dcfef7296007dab9b5
This commit is contained in:
parent
2e06864b2c
commit
a3af071997
@ -46,11 +46,14 @@ class _CopyImage(task.Task):
|
||||
'os_glance_staging_store')
|
||||
|
||||
def execute(self):
|
||||
with self.action_wrapper as action:
|
||||
return self._execute(action)
|
||||
|
||||
def _execute(self, action):
|
||||
"""Create temp file into store and return path to it
|
||||
|
||||
:param image_id: Glance Image ID
|
||||
"""
|
||||
image = self.image_repo.get(self.image_id)
|
||||
# NOTE (abhishekk): If ``all_stores_must_succeed`` is set to True
|
||||
# and copying task fails then we keep data in staging area as it
|
||||
# is so that if second call is made to copy the same image then
|
||||
@ -66,7 +69,7 @@ class _CopyImage(task.Task):
|
||||
# re-stage the fresh image data.
|
||||
# Ref: https://bugs.launchpad.net/glance/+bug/1885003
|
||||
size_in_staging = os.path.getsize(file_path)
|
||||
if image.size == size_in_staging:
|
||||
if action.image_size == size_in_staging:
|
||||
return file_path, 0
|
||||
else:
|
||||
LOG.debug(("Found partial image data in staging "
|
||||
@ -83,7 +86,7 @@ class _CopyImage(task.Task):
|
||||
|
||||
# At first search image in default_backend
|
||||
default_store = CONF.glance_store.default_backend
|
||||
for loc in image.locations:
|
||||
for loc in action.image_locations:
|
||||
if loc['metadata'].get('store') == default_store:
|
||||
try:
|
||||
return self._copy_to_staging_store(loc)
|
||||
@ -95,7 +98,7 @@ class _CopyImage(task.Task):
|
||||
break
|
||||
|
||||
available_backends = CONF.enabled_backends
|
||||
for loc in image.locations:
|
||||
for loc in action.image_locations:
|
||||
image_backend = loc['metadata'].get('store')
|
||||
if (image_backend in available_backends.keys()
|
||||
and image_backend != default_store):
|
||||
|
@ -12,6 +12,7 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import copy
|
||||
import functools
|
||||
import os
|
||||
|
||||
@ -193,6 +194,18 @@ class _ImportActions(object):
|
||||
def image_id(self):
|
||||
return self._image.image_id
|
||||
|
||||
@property
|
||||
def image_size(self):
|
||||
return self._image.size
|
||||
|
||||
@property
|
||||
def image_locations(self):
|
||||
# Return a copy of this complex structure to make sure we do
|
||||
# not allow the plugin to mutate this underneath us for our
|
||||
# later save. If this needs to be a thing in the future, we
|
||||
# should have moderated access like all the other things here.
|
||||
return copy.deepcopy(self._image.locations)
|
||||
|
||||
@property
|
||||
def image_status(self):
|
||||
return self._image.status
|
||||
|
@ -730,6 +730,35 @@ class TestImportActionWrapper(test_utils.BaseTestCase):
|
||||
{'key': 'os_glance_foo', 'val': 'baz',
|
||||
'image': IMAGE_ID1})
|
||||
|
||||
def test_image_size(self):
|
||||
mock_repo = mock.MagicMock()
|
||||
mock_image = mock_repo.get.return_value
|
||||
mock_image.image_id = IMAGE_ID1
|
||||
mock_image.extra_properties = {'os_glance_import_task': TASK_ID1}
|
||||
mock_image.size = 123
|
||||
wrapper = import_flow.ImportActionWrapper(mock_repo, IMAGE_ID1,
|
||||
TASK_ID1)
|
||||
with wrapper as action:
|
||||
self.assertEqual(123, action.image_size)
|
||||
|
||||
def test_image_locations(self):
|
||||
mock_repo = mock.MagicMock()
|
||||
mock_image = mock_repo.get.return_value
|
||||
mock_image.image_id = IMAGE_ID1
|
||||
mock_image.extra_properties = {'os_glance_import_task': TASK_ID1}
|
||||
mock_image.locations = {'some': {'complex': ['structure']}}
|
||||
wrapper = import_flow.ImportActionWrapper(mock_repo, IMAGE_ID1,
|
||||
TASK_ID1)
|
||||
with wrapper as action:
|
||||
self.assertEqual({'some': {'complex': ['structure']}},
|
||||
action.image_locations)
|
||||
# Mutate our copy
|
||||
action.image_locations['foo'] = 'bar'
|
||||
|
||||
# Make sure we did not mutate the image itself
|
||||
self.assertEqual({'some': {'complex': ['structure']}},
|
||||
mock_image.locations)
|
||||
|
||||
def test_drop_lock_for_task(self):
|
||||
mock_repo = mock.MagicMock()
|
||||
mock_repo.get.return_value.extra_properties = {
|
||||
|
@ -137,6 +137,7 @@ class TestCopyImageTask(test_utils.BaseTestCase):
|
||||
get_mock.return_value = mock.MagicMock(
|
||||
image_id=self.images[0]['id'],
|
||||
locations=self.images[0]['locations'],
|
||||
extra_properties={'os_glance_import_task': self.task.task_id},
|
||||
status=self.images[0]['status']
|
||||
)
|
||||
with mock.patch.object(store_api, 'get') as get_data:
|
||||
@ -164,6 +165,7 @@ class TestCopyImageTask(test_utils.BaseTestCase):
|
||||
image_id=self.images[0]['id'],
|
||||
locations=self.images[0]['locations'],
|
||||
status=self.images[0]['status'],
|
||||
extra_properties={'os_glance_import_task': self.task.task_id},
|
||||
size=4
|
||||
)
|
||||
with mock.patch.object(store_api, 'get') as get_data:
|
||||
@ -194,6 +196,7 @@ class TestCopyImageTask(test_utils.BaseTestCase):
|
||||
image_id=self.images[0]['id'],
|
||||
locations=self.images[0]['locations'],
|
||||
status=self.images[0]['status'],
|
||||
extra_properties={'os_glance_import_task': self.task.task_id},
|
||||
size=4
|
||||
)
|
||||
copy_image_task.execute()
|
||||
|
Loading…
Reference in New Issue
Block a user