← Back to team overview

duplicity-team team mailing list archive

[Merge] lp:~noizyland/duplicity/azurebackend-fixes into lp:duplicity

 

Scott McKenzie has proposed merging lp:~noizyland/duplicity/azurebackend-fixes into lp:duplicity.

Requested reviews:
  duplicity-team (duplicity-team)

For more details, see:
https://code.launchpad.net/~noizyland/duplicity/azurebackend-fixes/+merge/279347
-- 
Your team duplicity-team is requested to review the proposed merge of lp:~noizyland/duplicity/azurebackend-fixes into lp:duplicity.
=== modified file 'bin/duplicity.1'
--- bin/duplicity.1	2015-10-10 00:02:35 +0000
+++ bin/duplicity.1	2015-12-02 20:23:07 +0000
@@ -1465,8 +1465,8 @@
 if /home/ben/1234567 existed.
 
 .SH A NOTE ON AZURE ACCESS
-The Azure backend requires the Microsoft Azure SDK for Python to be installed
-on the system.
+The Azure backend requires the Microsoft Azure Storage SDK for Python to be 
+installed on the system.
 See
 .B REQUIREMENTS
 above.
@@ -1960,8 +1960,8 @@
 Some backends also require additional components (probably available as packages for your specific platform):
 .TP
 .BR "azure backend" " (Azure Blob Storage Service)"
-.B Microsoft Azure SDK for Python
-- https://github.com/Azure/azure-sdk-for-python
+.B Microsoft Azure Storage SDK for Python
+- https://pypi.python.org/pypi/azure-storage/
 .TP
 .BR "boto backend" " (S3 Amazon Web Services, Google Cloud Storage)"
 .B boto version 2.0+

=== modified file 'duplicity/backends/azurebackend.py'
--- duplicity/backends/azurebackend.py	2015-11-24 14:25:01 +0000
+++ duplicity/backends/azurebackend.py	2015-12-02 20:23:07 +0000
@@ -33,29 +33,36 @@
     def __init__(self, parsed_url):
         duplicity.backend.Backend.__init__(self, parsed_url)
 
-        # Import Microsoft Azure SDK for Python library.
+        # Import Microsoft Azure Storage SDK for Python library.
         try:
             import azure
-            from azure.storage.blob import BlobService
+            import azure.storage
+            if hasattr(azure.storage, 'BlobService'):
+                # v0.11.1 and below
+                from azure.storage import BlobService
+                self.AzureMissingResourceError = azure.WindowsAzureMissingResourceError
+                self.AzureConflictError = azure.WindowsAzureConflictError
+            else:
+                # v1.0.0 and above
+                from azure.storage.blob import BlobService
+                self.AzureMissingResourceError = azure.common.AzureMissingResourceHttpError
+                self.AzureConflictError = azure.common.AzureConflictHttpError
         except ImportError:
-            raise BackendException('Azure backend requires Microsoft Azure SDK for Python '
-                                   '(https://github.com/Azure/azure-sdk-for-python).')
+            raise BackendException('Azure backend requires Microsoft Azure Storage SDK for Python '
+                                   '(https://pypi.python.org/pypi/azure-storage/).')
 
         if 'AZURE_ACCOUNT_NAME' not in os.environ:
             raise BackendException('AZURE_ACCOUNT_NAME environment variable not set.')
-
         if 'AZURE_ACCOUNT_KEY' not in os.environ:
             raise BackendException('AZURE_ACCOUNT_KEY environment variable not set.')
+        self.blob_service = BlobService(account_name=os.environ['AZURE_ACCOUNT_NAME'],
+                                        account_key=os.environ['AZURE_ACCOUNT_KEY'])
 
-        account_name = os.environ['AZURE_ACCOUNT_NAME']
-        account_key = os.environ['AZURE_ACCOUNT_KEY']
-        self.WindowsAzureMissingResourceError = azure.common.AzureMissingResourceHttpError
-        self.blob_service = BlobService(account_name=account_name, account_key=account_key)
         # TODO: validate container name
         self.container = parsed_url.path.lstrip('/')
         try:
             self.blob_service.create_container(self.container, fail_on_exist=True)
-        except azure.common.AzureConflictHttpError:
+        except self.AzureConflictError:
             # Indicates that the resource could not be created because it already exists.
             pass
         except Exception as e:
@@ -64,16 +71,23 @@
                            log.ErrorCode.connection_failed)
 
     def _put(self, source_path, remote_filename):
-        # http://azure.microsoft.com/en-us/documentation/articles/storage-python-how-to-use-blob-storage/#upload-blob
+        # https://azure.microsoft.com/en-us/documentation/articles/storage-python-how-to-use-blob-storage/#upload-a-blob-into-a-container
         self.blob_service.put_block_blob_from_path(self.container, remote_filename, source_path.name)
 
     def _get(self, remote_filename, local_path):
-        # http://azure.microsoft.com/en-us/documentation/articles/storage-python-how-to-use-blob-storage/#download-blobs
+        # https://azure.microsoft.com/en-us/documentation/articles/storage-python-how-to-use-blob-storage/#download-blobs
         self.blob_service.get_blob_to_path(self.container, remote_filename, local_path.name)
 
     def _list(self):
-        # http://azure.microsoft.com/en-us/documentation/articles/storage-python-how-to-use-blob-storage/#list-blob
-        blobs = self.blob_service.list_blobs(self.container)
+        # https://azure.microsoft.com/en-us/documentation/articles/storage-python-how-to-use-blob-storage/#list-the-blobs-in-a-container
+        blobs = []
+        marker = None
+        while True:
+            batch = self.blob_service.list_blobs(self.container, marker=marker)
+            blobs.extend(batch)
+            if not batch.next_marker:
+                break
+            marker = batch.next_marker
         return [blob.name for blob in blobs]
 
     def _delete(self, filename):


Follow ups