From 5c3f75ba6adb160bb61431b77d399b123a2a7546 Mon Sep 17 00:00:00 2001 From: Kun Huang Date: Sun, 17 Mar 2013 07:30:00 +0800 Subject: [PATCH] Add x-remove-versions-location for feature: disable versioning We can set x-versions-location empty to remove this header in API, but to keep consistent, we should allow x-remove-versions-location too. The usage is post "x-remove-versions-locaion: x", just like ACL remove headers. Fixed: bug #1107592 Change-Id: I1271eec6401d4a0e8c1a7c2d63aeb8dfef00bf6d --- doc/source/overview_object_versioning.rst | 14 +++++++++++++- swift/proxy/controllers/base.py | 7 ++++--- swift/proxy/controllers/container.py | 6 ++++++ test/unit/proxy/test_server.py | 22 ++++++++++++++++++++++ 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/doc/source/overview_object_versioning.rst b/doc/source/overview_object_versioning.rst index c9355a9b51..7a02a343b6 100644 --- a/doc/source/overview_object_versioning.rst +++ b/doc/source/overview_object_versioning.rst @@ -15,7 +15,7 @@ container where the versions are stored. It is recommended to use a different When data is ``PUT`` into a versioned container (a container with the versioning flag turned on), the existing data in the file is redirected to a new object and the data in the ``PUT`` request is saved as the data for the -versioned object. The new object name (for the previous version) is +versioned object. The new object name (for the previous version) is ``//``, where ``length`` is the 3-character zero-padded hexidecimal length of the ```` and ```` is the timestamp of when the previous version was created. @@ -75,3 +75,15 @@ gone:: http:///container/myobject curl -i -H "X-Auth-Token: " \ http:///versions?prefix=008myobject/ + +--------------------------------------------------- +How to Disable Object Versioning in a Swift Cluster +--------------------------------------------------- + +If you want to disable all functionality, set ``allow_versions`` back to +``False`` in the container server config. + +Disable versioning a versioned container (x is any value except empty):: + + curl -i -HPOST -H "X-Auth-Token: " \ + -H "X-Remove-Versions-Location: x" http:///container diff --git a/swift/proxy/controllers/base.py b/swift/proxy/controllers/base.py index 4a4d13ffa5..a0f4464666 100644 --- a/swift/proxy/controllers/base.py +++ b/swift/proxy/controllers/base.py @@ -278,17 +278,18 @@ class Controller(object): if getattr(m, 'publicly_accessible', False): self.allowed_methods.add(name) + def _x_remove_headers(self): + return [] + def transfer_headers(self, src_headers, dst_headers): st = self.server_type.lower() x_remove = 'x-remove-%s-meta-' % st - x_remove_read = 'x-remove-%s-read' % st - x_remove_write = 'x-remove-%s-write' % st x_meta = 'x-%s-meta-' % st dst_headers.update((k.lower().replace('-remove', '', 1), '') for k in src_headers if k.lower().startswith(x_remove) or - k.lower() in (x_remove_read, x_remove_write)) + k.lower() in self._x_remove_headers()) dst_headers.update((k.lower(), v) for k, v in src_headers.iteritems() diff --git a/swift/proxy/controllers/container.py b/swift/proxy/controllers/container.py index 61d1aa1198..f4ae435c95 100644 --- a/swift/proxy/controllers/container.py +++ b/swift/proxy/controllers/container.py @@ -50,6 +50,12 @@ class ContainerController(Controller): self.account_name = unquote(account_name) self.container_name = unquote(container_name) + def _x_remove_headers(self): + st = self.server_type.lower() + return ['x-remove-%s-read' % st, + 'x-remove-%s-write' % st, + 'x-remove-versions-location'] + def clean_acls(self, req): if 'swift.clean_acl' in req.environ: for header in ('x-container-read', 'x-container-write'): diff --git a/test/unit/proxy/test_server.py b/test/unit/proxy/test_server.py index d510d30a9d..a97d71ebc7 100644 --- a/test/unit/proxy/test_server.py +++ b/test/unit/proxy/test_server.py @@ -437,6 +437,17 @@ class TestController(unittest.TestCase): self.read_acl = 'read_acl' self.write_acl = 'write_acl' + def test_transfer_headers(self): + src_headers = {'x-remove-base-meta-owner': 'x', + 'x-base-meta-size': '151M', + 'new-owner': 'Kun'} + dst_headers = {'x-base-meta-owner': 'Gareth', + 'x-base-meta-size': '150M'} + self.controller.transfer_headers(src_headers, dst_headers) + expected_headers = {'x-base-meta-owner': '', + 'x-base-meta-size': '151M'} + self.assertEquals(dst_headers, expected_headers) + def check_account_info_return(self, partition, nodes, is_none=False): if is_none: p, n = None, None @@ -4318,6 +4329,17 @@ class TestContainerController(unittest.TestCase): container_ring=FakeRing(), object_ring=FakeRing()) + def test_transfer_headers(self): + src_headers = {'x-remove-versions-location': 'x', + 'x-container-read': '*:user'} + dst_headers = {'x-versions-location': 'backup'} + controller = swift.proxy.controllers.ContainerController(self.app, + 'a', 'c') + controller.transfer_headers(src_headers, dst_headers) + expected_headers = {'x-versions-location': '', + 'x-container-read': '*:user'} + self.assertEqual(dst_headers, expected_headers) + def assert_status_map(self, method, statuses, expected, raise_exc=False, missing_container=False): with save_globals():