]> git-server-git.apps.pok.os.sepia.ceph.com Git - radosgw-agent.git/commitdiff
full data sync: treat 404 from bucket list as success
authorJosh Durgin <jdurgin@redhat.com>
Thu, 18 Dec 2014 05:20:21 +0000 (21:20 -0800)
committerJosh Durgin <jdurgin@redhat.com>
Fri, 19 Dec 2014 11:22:09 +0000 (03:22 -0800)
Since results are paged, the exception may not occur immediately, so
add a new type to distinguish it from other client exceptions, and
catch it at any point during full sync of a bucket.

Signed-off-by: Josh Durgin <jdurgin@redhat.com>
radosgw_agent/client.py
radosgw_agent/tests/test_worker.py
radosgw_agent/worker.py

index f7343eb64df763944470193914229cc15233c5d3..42a03ec90080f96906a8ef09954f6bef547b4b1e 100644 (file)
@@ -59,6 +59,8 @@ class InvalidZone(ClientException):
     pass
 class ZoneNotFound(ClientException):
     pass
+class BucketEmpty(ClientException):
+    pass
 
 def parse_endpoint(endpoint):
     url = urlparse(endpoint)
@@ -205,8 +207,18 @@ def get_bucket_list(connection):
 def list_objects_in_bucket(connection, bucket_name):
     # use the boto library to do this
     bucket = connection.get_bucket(bucket_name)
-    for key in bucket.list():
-        yield key.name
+    try:
+        for key in bucket.list():
+            yield key.name
+    except boto.exception.S3ResponseError as e:
+        # since this is a generator, the exception will be raised when
+        # it's read, rather than when this call returns, so raise a
+        # unique exception to distinguish this from client errors from
+        # other calls
+        if e.status == 404:
+            raise BucketEmpty()
+        else:
+            raise
 
 
 @boto_call
index 195bedf7d98d4b7dc4e1e4f72deedf15031c2f18..2d1e486ed52683f2e7835c450dca3ca20a523bc5 100644 (file)
@@ -160,3 +160,14 @@ class TestSyncObject(object):
 
         exc_message = exc.exconly()
         assert 'state is error' in exc_message
+
+    def test_sync_bucket_delayed_not_found(self):
+        class fake_iterable(object):
+            def __iter__(self):
+                raise client.BucketEmpty
+        with patch('radosgw_agent.worker.client', self.client):
+            w = worker.DataWorker(None, None, None, self.src, None, daemon_id=1)
+            w.sync_object = lambda *a: None
+            objects = fake_iterable()
+            with py.test.raises(client.BucketEmpty):
+                w.sync_bucket('foo', objects)
index c259ffb69a26270b57bd5246742191d1bf6a53b4..d46061ed31f06d241fca0010168b3644d422b04d 100644 (file)
@@ -364,17 +364,17 @@ class DataWorkerFull(DataWorker):
             log.debug('bucket instance is "%s" with marker %s', instance, marker)
 
             objects = client.list_objects_in_bucket(self.src_conn, bucket)
-            if not objects:
-                return True
-        except Exception as e:
-            log.error('error preparing for full sync of bucket "%s": %s',
-                      bucket, e)
-            return False
-
-        retries = self.sync_bucket(bucket, objects)
+            retries = self.sync_bucket(bucket, objects)
 
-        result = self.set_bound(instance, marker, retries, 'bucket-index')
-        return not retries and result == RESULT_SUCCESS
+            result = self.set_bound(instance, marker, retries, 'bucket-index')
+            return not retries and result == RESULT_SUCCESS
+        except client.BucketEmpty:
+            log.debug('no objects in bucket %s', bucket)
+            return True
+        except Exception:
+            log.exception('error preparing for full sync of bucket "%s"',
+                          bucket)
+            return False
 
     def run(self):
         self.prepare_lock()