Created
March 21, 2016 20:06
-
-
Save alistairncoles/0dd102384c47bfe95787 to your computer and use it in GitHub Desktop.
container sync fixups
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/swift/container/sync.py b/swift/container/sync.py | |
index 95cd38a..cbf6a34 100644 | |
--- a/swift/container/sync.py | |
+++ b/swift/container/sync.py | |
@@ -409,10 +409,10 @@ class ContainerSync(Daemon): | |
self.logger.exception(_('ERROR Syncing %s'), | |
broker if broker else path) | |
- def _update_sync_to_headers(self, sync_to, name, realm_key, user_key, | |
- realm, method, headers): | |
+ def _get_sync_headers(self, sync_to, name, realm_key, user_key, realm, | |
+ method, timestamp_str): | |
""" | |
- Updates container sync headers | |
+ Returns container sync headers | |
:param sync_to: The URL to the remote container. | |
:param name: The name of the object | |
@@ -424,24 +424,24 @@ class ContainerSync(Daemon): | |
:param realm: The realm from self.realms_conf, if there is one. | |
If None, fallback to using the older allowed_sync_hosts | |
way of syncing. | |
- :param method: HTTP method to create sig with | |
- :param headers: headers to update with container sync headers | |
- | |
- :returns: True if object already exists in remote | |
+ :param method: HTTP method to create signature with | |
+ :param timestamp_str: string representation of object x-timestamp | |
+ :returns: a dict containing appropriate container sync auth header | |
""" | |
+ headers = {'x-timestamp': timestamp_str} | |
if realm and realm_key: | |
nonce = uuid.uuid4().hex | |
path = urlparse(sync_to).path + '/' + quote(name) | |
sig = self.realms_conf.get_sig(method, path, | |
- headers.get('x-timestamp', 0), | |
+ timestamp_str, | |
nonce, realm_key, | |
user_key) | |
- headers['x-container-sync-auth'] = '%s %s %s' % (realm, | |
- nonce, | |
- sig) | |
+ headers['x-container-sync-auth'] = '%s %s %s' % (realm, nonce, sig) | |
else: | |
headers['x-container-sync-key'] = user_key | |
+ return headers | |
+ | |
def _object_in_remote_container(self, name, timestamp, sync_to, user_key, | |
realm, realm_key): | |
""" | |
@@ -462,10 +462,9 @@ class ContainerSync(Daemon): | |
allowed_sync_hosts way of syncing. | |
:returns: True if object already exists in remote | |
""" | |
- headers = {} | |
- headers['x-timestamp'] = timestamp.internal | |
- self._update_sync_to_headers(sync_to, name, realm_key, | |
- user_key, realm, 'HEAD', headers) | |
+ headers = self._get_sync_headers( | |
+ sync_to, name, realm_key, user_key, realm, 'HEAD', | |
+ timestamp.internal) | |
try: | |
metadata, _ = head_object(sync_to, name=name, | |
headers=headers, | |
@@ -515,11 +514,10 @@ class ContainerSync(Daemon): | |
if row['deleted']: | |
# when sync'ing a deleted object, use ts_data - this is the | |
# timestamp of the source tombstone | |
+ headers = self._get_sync_headers( | |
+ sync_to, row['name'], realm_key, user_key, realm, 'DELETE', | |
+ ts_data.internal) | |
try: | |
- headers = {'x-timestamp': ts_data.internal} | |
- self._update_sync_to_headers(sync_to, row['name'], | |
- realm_key, user_key, | |
- realm, 'DELETE', headers) | |
delete_object(sync_to, name=row['name'], headers=headers, | |
proxy=self.select_http_proxy(), | |
logger=self.logger, | |
@@ -576,8 +574,9 @@ class ContainerSync(Daemon): | |
if 'content-type' in headers: | |
headers['content-type'] = clean_content_type( | |
headers['content-type']) | |
- self._update_sync_to_headers(sync_to, row['name'], realm_key, | |
- user_key, realm, 'PUT', headers) | |
+ headers.update(self._get_sync_headers( | |
+ sync_to, row['name'], realm_key, user_key, realm, 'PUT', | |
+ headers['x-timestamp'])) | |
put_object(sync_to, name=row['name'], headers=headers, | |
contents=FileLikeIter(body), | |
proxy=self.select_http_proxy(), logger=self.logger, | |
diff --git a/test/unit/container/test_sync.py b/test/unit/container/test_sync.py | |
index 88122db..7a79127 100644 | |
--- a/test/unit/container/test_sync.py | |
+++ b/test/unit/container/test_sync.py | |
@@ -1101,12 +1101,17 @@ class TestContainerSync(unittest.TestCase): | |
def fake_put_object(*args, **kwargs): | |
actual_puts.append((args, kwargs)) | |
- def fake_head_object(*args, **kwargs): | |
- raise ClientException('test client exception', http_status=404) | |
+ def make_fake_head_object(exception=None): | |
+ def fake_head_object(*args, **kwargs): | |
+ if exception: | |
+ raise exception | |
+ return ({}, {}) | |
+ return fake_head_object | |
cs._object_in_remote_container = orig_object_in_rcontainer | |
sync.put_object = fake_put_object | |
- sync.head_object = fake_head_object | |
+ sync.head_object = make_fake_head_object( | |
+ ClientException('test client exception', http_status=404)) | |
self.assertTrue(cs.container_sync_row( | |
test_row, 'http://sync/to/path', | |
'key', FakeContainerBroker('broker'), | |
@@ -1116,10 +1121,8 @@ class TestContainerSync(unittest.TestCase): | |
# No additional errors | |
self.assertEqual(cs.container_failures, excepted_failure_count) | |
- def fake_head_object(*args, **kwargs): | |
- raise ClientException('test client exception', http_status=401) | |
- | |
- sync.head_object = fake_head_object | |
+ sync.head_object = make_fake_head_object( | |
+ ClientException('test client exception', http_status=401)) | |
self.assertFalse(cs.container_sync_row( | |
test_row, 'http://sync/to/path', | |
'key', FakeContainerBroker('broker'), | |
@@ -1129,10 +1132,7 @@ class TestContainerSync(unittest.TestCase): | |
excepted_failure_count += 1 | |
self.assertEqual(cs.container_failures, excepted_failure_count) | |
- def fake_head_object(*args, **kwargs): | |
- raise Exception() | |
- | |
- sync.head_object = fake_head_object | |
+ sync.head_object = make_fake_head_object(Exception()) | |
self.assertFalse(cs.container_sync_row( | |
test_row, | |
'http://sync/to/path', | |
@@ -1143,10 +1143,7 @@ class TestContainerSync(unittest.TestCase): | |
excepted_failure_count += 1 | |
self.assertEqual(cs.container_failures, excepted_failure_count) | |
- def fake_head_object(*args, **kwargs): | |
- return ({}, {}) | |
- | |
- sync.head_object = fake_head_object | |
+ sync.head_object = make_fake_head_object() | |
self.assertTrue(cs.container_sync_row( | |
test_row, 'http://sync/to/path', | |
'key', FakeContainerBroker('broker'), |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment