Fix Delete Multiple Objects process when multipart object is deleted
When delete a object created by Complete Multipart Upload in Delete Multiple Objects operation, delete both manifest file and segments by adding "multipart-manifest=delete" to query string. Change-Id: I3759e6f43d8c531d7a7d961c2069af1e411d04ef
This commit is contained in:
parent
2f6ad2f6aa
commit
822dd7f395
@ -242,6 +242,11 @@ class MultiObjectDeleteAclHandler(BaseAclHandler):
|
|||||||
"""
|
"""
|
||||||
MultiObjectDeleteAclHandler: Handler for MultiObjectDeleteController
|
MultiObjectDeleteAclHandler: Handler for MultiObjectDeleteController
|
||||||
"""
|
"""
|
||||||
|
def HEAD(self, app):
|
||||||
|
# Only bucket write acl is required
|
||||||
|
if not self.obj:
|
||||||
|
return self._handle_acl(app, 'HEAD')
|
||||||
|
|
||||||
def DELETE(self, app):
|
def DELETE(self, app):
|
||||||
# Only bucket write acl is required
|
# Only bucket write acl is required
|
||||||
pass
|
pass
|
||||||
|
@ -99,7 +99,8 @@ class MultiObjectDeleteController(Controller):
|
|||||||
req.object_name = key
|
req.object_name = key
|
||||||
|
|
||||||
try:
|
try:
|
||||||
req.get_response(self.app, method='DELETE')
|
query = req.gen_multipart_manifest_delete_query(self.app)
|
||||||
|
req.get_response(self.app, method='DELETE', query=query)
|
||||||
except NoSuchKey:
|
except NoSuchKey:
|
||||||
pass
|
pass
|
||||||
except ErrorResponse as e:
|
except ErrorResponse as e:
|
||||||
|
@ -17,6 +17,7 @@ import unittest
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
|
|
||||||
|
from six.moves import urllib
|
||||||
from swift.common import swob
|
from swift.common import swob
|
||||||
from swift.common.swob import Request
|
from swift.common.swob import Request
|
||||||
|
|
||||||
@ -30,6 +31,10 @@ class TestSwift3MultiDelete(Swift3TestCase):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestSwift3MultiDelete, self).setUp()
|
super(TestSwift3MultiDelete, self).setUp()
|
||||||
|
self.swift.register('HEAD', '/v1/AUTH_test/bucket/Key1',
|
||||||
|
swob.HTTPOk, {}, None)
|
||||||
|
self.swift.register('HEAD', '/v1/AUTH_test/bucket/Key2',
|
||||||
|
swob.HTTPNotFound, {}, None)
|
||||||
|
|
||||||
@s3acl
|
@s3acl
|
||||||
def test_object_multi_DELETE_to_object(self):
|
def test_object_multi_DELETE_to_object(self):
|
||||||
@ -51,13 +56,19 @@ class TestSwift3MultiDelete(Swift3TestCase):
|
|||||||
|
|
||||||
@s3acl
|
@s3acl
|
||||||
def test_object_multi_DELETE(self):
|
def test_object_multi_DELETE(self):
|
||||||
|
self.swift.register('HEAD', '/v1/AUTH_test/bucket/Key3',
|
||||||
|
swob.HTTPOk,
|
||||||
|
{'x-static-large-object': 'True'},
|
||||||
|
None)
|
||||||
self.swift.register('DELETE', '/v1/AUTH_test/bucket/Key1',
|
self.swift.register('DELETE', '/v1/AUTH_test/bucket/Key1',
|
||||||
swob.HTTPNoContent, {}, None)
|
swob.HTTPNoContent, {}, None)
|
||||||
self.swift.register('DELETE', '/v1/AUTH_test/bucket/Key2',
|
self.swift.register('DELETE', '/v1/AUTH_test/bucket/Key2',
|
||||||
swob.HTTPNotFound, {}, None)
|
swob.HTTPNotFound, {}, None)
|
||||||
|
self.swift.register('DELETE', '/v1/AUTH_test/bucket/Key3',
|
||||||
|
swob.HTTPOk, {}, None)
|
||||||
|
|
||||||
elem = Element('Delete')
|
elem = Element('Delete')
|
||||||
for key in ['Key1', 'Key2']:
|
for key in ['Key1', 'Key2', 'Key3']:
|
||||||
obj = SubElement(elem, 'Object')
|
obj = SubElement(elem, 'Object')
|
||||||
SubElement(obj, 'Key').text = key
|
SubElement(obj, 'Key').text = key
|
||||||
body = tostring(elem, use_s3ns=False)
|
body = tostring(elem, use_s3ns=False)
|
||||||
@ -75,7 +86,12 @@ class TestSwift3MultiDelete(Swift3TestCase):
|
|||||||
self.assertEquals(status.split()[0], '200')
|
self.assertEquals(status.split()[0], '200')
|
||||||
|
|
||||||
elem = fromstring(body)
|
elem = fromstring(body)
|
||||||
self.assertEquals(len(elem.findall('Deleted')), 2)
|
self.assertEquals(len(elem.findall('Deleted')), 3)
|
||||||
|
_, path, _ = self.swift.calls_with_headers[-1]
|
||||||
|
path, query_string = path.split('?', 1)
|
||||||
|
self.assertEquals(path, '/v1/AUTH_test/bucket/Key3')
|
||||||
|
query = dict(urllib.parse.parse_qsl(query_string))
|
||||||
|
self.assertEquals(query['multipart-manifest'], 'delete')
|
||||||
|
|
||||||
@s3acl
|
@s3acl
|
||||||
def test_object_multi_DELETE_quiet(self):
|
def test_object_multi_DELETE_quiet(self):
|
||||||
|
@ -7,3 +7,4 @@ mock
|
|||||||
pylint
|
pylint
|
||||||
python-openstackclient<=1.9.0
|
python-openstackclient<=1.9.0
|
||||||
boto
|
boto
|
||||||
|
six>=1.9.0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user