Merge "Support for deleting images stored as SLO in Swift"

This commit is contained in:
Jenkins 2015-03-05 17:00:26 +00:00 committed by Gerrit Code Review
commit c1e8697f12
2 changed files with 69 additions and 7 deletions

View File

@ -22,6 +22,7 @@ import math
from oslo.config import cfg
from oslo.utils import excutils
import six
import six.moves.urllib.parse as urlparse
import swiftclient
import urllib
@ -373,6 +374,14 @@ def Store(conf):
Store.OPTIONS = _SWIFT_OPTS + sutils.swift_opts
def _is_slo(slo_header):
if (slo_header is not None and isinstance(slo_header, six.string_types)
and slo_header.lower() == 'true'):
return True
return False
class BaseStore(driver.Store):
_CAPABILITIES = capabilities.BitMasks.RW_ACCESS
@ -612,17 +621,27 @@ class BaseStore(driver.Store):
# that means the object was uploaded in chunks/segments,
# and we need to delete all the chunks as well as the
# manifest.
manifest = None
dlo_manifest = None
slo_manifest = None
try:
headers = connection.head_object(
location.container, location.obj)
manifest = headers.get('x-object-manifest')
dlo_manifest = headers.get('x-object-manifest')
slo_manifest = headers.get('x-static-large-object')
except swiftclient.ClientException as e:
if e.http_status != httplib.NOT_FOUND:
raise
if manifest:
if _is_slo(slo_manifest):
# Delete the manifest as well as the segments
query_string = 'multipart-manifest=delete'
connection.delete_object(location.container, location.obj,
query_string=query_string)
return
if dlo_manifest:
# Delete all the chunks before the object manifest itself
obj_container, obj_prefix = manifest.split('/', 1)
obj_container, obj_prefix = dlo_manifest.split('/', 1)
segments = connection.get_container(
obj_container, prefix=obj_prefix)[1]
for segment in segments:

View File

@ -49,6 +49,7 @@ from tests.unit import test_store_capabilities
CONF = cfg.CONF
FAKE_UUID = lambda: str(uuid.uuid4())
FAKE_UUID2 = lambda: str(uuid.uuid4())
Store = swift.Store
FIVE_KB = 5 * units.Ki
@ -76,10 +77,11 @@ def stub_out_swiftclient(stubs, swift_store_auth_version):
'glance/%s' % FAKE_UUID: {
'content-length': FIVE_KB,
'etag': 'c2e5db72bd7fd153f53ede5da5a06de3'
}
},
'glance/%s' % FAKE_UUID2: {'x-static-large-object': 'true', },
}
fixture_objects = {'glance/%s' % FAKE_UUID:
six.StringIO("*" * FIVE_KB)}
fixture_objects = {'glance/%s' % FAKE_UUID: six.StringIO("*" * FIVE_KB),
'glance/%s' % FAKE_UUID2: six.StringIO("*" * FIVE_KB), }
def fake_head_container(url, token, container, **kwargs):
if container not in fixture_containers:
@ -810,6 +812,47 @@ class SwiftTests(object):
self.assertRaises(exceptions.NotFound, self.store.get, loc)
@mock.patch.object(swiftclient.client, 'delete_object')
def test_delete_slo(self, mock_del_obj):
"""
Test we can delete an existing image stored as SLO, static large object
"""
conf = copy.deepcopy(SWIFT_CONF)
self.config(**conf)
reload(swift)
self.store = Store(self.conf)
self.store.configure()
uri = "swift://%s:key@authurl/glance/%s" % (self.swift_store_user,
FAKE_UUID2)
loc = location.get_location_from_uri(uri, conf=self.conf)
self.store.delete(loc)
mock_del_obj.assert_called_once()
_, kwargs = mock_del_obj.call_args
self.assertEqual('multipart-manifest=delete',
kwargs.get('query_string'))
@mock.patch.object(swiftclient.client, 'delete_object')
def test_delete_nonslo_not_deleted_as_slo(self, mock_del_obj):
"""
Test that non-SLOs are not being deleted the SLO way
"""
conf = copy.deepcopy(SWIFT_CONF)
self.config(**conf)
reload(swift)
self.store = Store(self.conf)
self.store.configure()
uri = "swift://%s:key@authurl/glance/%s" % (self.swift_store_user,
FAKE_UUID)
loc = location.get_location_from_uri(uri, conf=self.conf)
self.store.delete(loc)
mock_del_obj.assert_called_once()
_, kwargs = mock_del_obj.call_args
self.assertEqual(None, kwargs.get('query_string'))
def test_delete_with_reference_params(self):
"""
Test we can delete an existing image in the swift store