Merge lp:~david-goetz/swift/db_double_quar into lp:~hudson-openstack/swift/trunk

Proposed by David Goetz
Status: Merged
Approved by: gholt
Approved revision: 264
Merged at revision: 283
Proposed branch: lp:~david-goetz/swift/db_double_quar
Merge into: lp:~hudson-openstack/swift/trunk
Diff against target: 96 lines (+44/-1)
2 files modified
swift/common/db_replicator.py (+9/-1)
test/unit/common/test_db_replicator.py (+35/-0)
To merge this branch: bzr merge lp:~david-goetz/swift/db_double_quar
Reviewer Review Type Date Requested Status
Swift Core security contacts Pending
Review via email: mp+58205@code.launchpad.net

Description of the change

Allow for double quarantining of dbs. Just appends a uuid if there's naming conflict.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'swift/common/db_replicator.py'
2--- swift/common/db_replicator.py 2011-03-03 21:48:38 +0000
3+++ swift/common/db_replicator.py 2011-04-18 22:10:57 +0000
4@@ -20,6 +20,8 @@
5 import math
6 import time
7 import shutil
8+import uuid
9+import errno
10
11 from eventlet import GreenPool, sleep, Timeout, TimeoutError
12 from eventlet.green import subprocess
13@@ -49,7 +51,13 @@
14 quarantine_dir = os.path.abspath(os.path.join(object_dir, '..',
15 '..', '..', '..', 'quarantined', server_type + 's',
16 os.path.basename(object_dir)))
17- renamer(object_dir, quarantine_dir)
18+ try:
19+ renamer(object_dir, quarantine_dir)
20+ except OSError, e:
21+ if e.errno not in (errno.EEXIST, errno.ENOTEMPTY):
22+ raise
23+ quarantine_dir = "%s-%s" % (quarantine_dir, uuid.uuid4().hex)
24+ renamer(object_dir, quarantine_dir)
25
26
27 class ReplConnection(BufferedHTTPConnection):
28
29=== modified file 'test/unit/common/test_db_replicator.py'
30--- test/unit/common/test_db_replicator.py 2011-01-04 23:34:43 +0000
31+++ test/unit/common/test_db_replicator.py 2011-04-18 22:10:57 +0000
32@@ -17,8 +17,10 @@
33 from contextlib import contextmanager
34 import os
35 import logging
36+import errno
37
38 from swift.common import db_replicator
39+from swift.common import utils
40 from swift.common.utils import normalize_timestamp
41 from swift.container import server as container_server
42
43@@ -86,6 +88,8 @@
44
45 class FakeBroker:
46 db_file = __file__
47+ get_repl_missing_table = False
48+ db_type = 'container'
49 def __init__(self, *args, **kwargs):
50 return None
51 @contextmanager
52@@ -104,6 +108,8 @@
53 def merge_items(self, *args):
54 self.args = args
55 def get_replication_info(self):
56+ if self.get_repl_missing_table:
57+ raise Exception('no such table')
58 return {'delete_timestamp': 0, 'put_timestamp': 1, 'count': 0}
59 def reclaim(self, item_timestamp, sync_timestamp):
60 pass
61@@ -202,6 +208,35 @@
62 replicator = TestReplicator({})
63 replicator._replicate_object('0', 'file', 'node_id')
64
65+ def test_replicate_object_quarantine(self):
66+ replicator = TestReplicator({})
67+ was_db_file = replicator.brokerclass.db_file
68+ try:
69+
70+ def mock_renamer(was, new, cause_colision=False):
71+ if cause_colision and '-' not in new:
72+ raise OSError(errno.EEXIST, "File already exists")
73+ self.assertEquals('/a/b/c/d/e', was)
74+ if '-' in new:
75+ self.assert_(
76+ new.startswith('/a/quarantined/containers/e-'))
77+ else:
78+ self.assertEquals('/a/quarantined/containers/e', new)
79+
80+ def mock_renamer_error(was, new):
81+ return mock_renamer(was, new, cause_colision=True)
82+ was_renamer = db_replicator.renamer
83+ db_replicator.renamer = mock_renamer
84+ db_replicator.lock_parent_directory = lock_parent_directory
85+ replicator.brokerclass.get_repl_missing_table = True
86+ replicator.brokerclass.db_file = '/a/b/c/d/e/hey'
87+ replicator._replicate_object('0', 'file', 'node_id')
88+ # try the double quarantine
89+ db_replicator.renamer = mock_renamer_error
90+ replicator._replicate_object('0', 'file', 'node_id')
91+ finally:
92+ replicator.brokerclass.db_file = was_db_file
93+ db_replicator.renamer = was_renamer
94
95 # def test_dispatch(self):
96 # rpc = db_replicator.ReplicatorRpc('/', '/', FakeBroker, False)