[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#769334: marked as done (unblock: python-boto/2.34.0-2)



Your message dated Sun, 16 Nov 2014 15:38:32 +0000
with message-id <20141116153832.GP6216@lupin.home.powdarrmonkey.net>
and subject line Re: Bug#769334: unblock: python-boto/2.34.0-2
has caused the Debian Bug report #769334,
regarding unblock: python-boto/2.34.0-2
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
769334: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=769334
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package python-boto to address bts#769310.

Much of the full diff consists of whitespace changes, so I've attached
output that separates them (filterdiff commands at the bottom of this
email).  

I realize that new upstreams are frowned upon at this stage, but aside
from the sigv4 fixes (important in their own right), and the addition of
support for eu-central-1 (a big deal, particularly for German users of
AWS), there is only a handful of minor changes (typos and the like) that
remain.  Backporting the required changes would come very close to
yielding the same results.

I also realize that I pulled the trigger on an unstable upload too quickly,
and that I should have sought approval first.  I also failed to reference
#769310 in the changelog.  Sorry about that, I have no excuse.

Thanks,


unblock python-boto/2.34.0-2

-- System Information:
Debian Release: jessie/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing'), (500, 'stable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.16.0-4-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_US.utf8, LC_CTYPE=en_US.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

[1]: whitespace
  debdiff python-boto_2.33.0-1.dsc python-boto_2.34.0-2.dsc \
      | filterdiff \
            -ipython-boto-2.33.0/boto/cloudtrail/exceptions.py \
            -ipython-boto-2.33.0/boto/cloudtrail/layer1.py \
            -ipython-boto-2.33.0/boto/datapipeline/layer1.py \
            -ipython-boto-2.33.0/boto/directconnect/exceptions.py \
            -ipython-boto-2.33.0/boto/directconnect/layer1.py \
            -ipython-boto-2.33.0/boto/logs/layer1.py

[2]: without whitespace
  debdiff python-boto_2.33.0-1.dsc python-boto_2.34.0-2.dsc \
      | filterdiff \
            -xpython-boto-2.33.0/boto/cloudtrail/exceptions.py \
            -xpython-boto-2.33.0/boto/cloudtrail/layer1.py \
            -xpython-boto-2.33.0/boto/datapipeline/layer1.py \
            -xpython-boto-2.33.0/boto/directconnect/exceptions.py \
            -xpython-boto-2.33.0/boto/directconnect/layer1.py \
            -xpython-boto-2.33.0/boto/logs/layer1.py
 

-- 
Eric Evans
eevans@debian.org
--- python-boto-2.33.0/boto/cloudtrail/exceptions.py	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/boto/cloudtrail/exceptions.py	2014-10-23 11:19:50.000000000 -0500
@@ -24,6 +24,7 @@
     """
     pass
 
+
 class InsufficientSnsTopicPolicyException(BotoServerError):
     """
     Raised when the SNS topic does not allow Cloudtrail to post
@@ -31,18 +32,21 @@
     """
     pass
 
+
 class InvalidTrailNameException(BotoServerError):
     """
     Raised when the trail name is invalid.
     """
     pass
 
+
 class InternalErrorException(BotoServerError):
     """
     Raised when there was an internal Cloudtrail error.
     """
     pass
 
+
 class TrailNotFoundException(BotoServerError):
     """
     Raised when the given trail name is not found.
--- python-boto-2.33.0/boto/cloudtrail/layer1.py	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/boto/cloudtrail/layer1.py	2014-10-23 11:19:50.000000000 -0500
@@ -75,7 +75,6 @@
         "InsufficientS3BucketPolicyException": exceptions.InsufficientS3BucketPolicyException,
     }
 
-
     def __init__(self, **kwargs):
         region = kwargs.pop('region', None)
         if not region:
@@ -351,4 +350,3 @@
             exception_class = self._faults.get(fault_name, self.ResponseError)
             raise exception_class(response.status, response.reason,
                                   body=json_body)
-
--- python-boto-2.33.0/boto/datapipeline/layer1.py	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/boto/datapipeline/layer1.py	2014-10-23 11:19:50.000000000 -0500
@@ -83,7 +83,6 @@
         "InternalServiceError": exceptions.InternalServiceError,
     }
 
-
     def __init__(self, **kwargs):
         region = kwargs.pop('region', None)
         if not region:
@@ -638,4 +637,3 @@
             exception_class = self._faults.get(fault_name, self.ResponseError)
             raise exception_class(response.status, response.reason,
                                   body=json_body)
-
--- python-boto-2.33.0/boto/directconnect/exceptions.py	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/boto/directconnect/exceptions.py	2014-10-23 11:19:50.000000000 -0500
@@ -20,6 +20,7 @@
 # IN THE SOFTWARE.
 #
 
+
 class DirectConnectClientException(Exception):
     pass
 
--- python-boto-2.33.0/boto/directconnect/layer1.py	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/boto/directconnect/layer1.py	2014-10-23 11:19:50.000000000 -0500
@@ -65,7 +65,6 @@
         "DirectConnectServerException": exceptions.DirectConnectServerException,
     }
 
-
     def __init__(self, **kwargs):
         region = kwargs.pop('region', None)
         if not region:
@@ -626,4 +625,3 @@
             exception_class = self._faults.get(fault_name, self.ResponseError)
             raise exception_class(response.status, response.reason,
                                   body=json_body)
-
--- python-boto-2.33.0/boto/logs/layer1.py	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/boto/logs/layer1.py	2014-10-23 11:19:50.000000000 -0500
@@ -95,7 +95,6 @@
         "InvalidSequenceTokenException": exceptions.InvalidSequenceTokenException,
     }
 
-
     def __init__(self, **kwargs):
         region = kwargs.pop('region', None)
         if not region:
diff -Nru python-boto-2.33.0/boto/auth.py python-boto-2.34.0/boto/auth.py
--- python-boto-2.33.0/boto/auth.py	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/boto/auth.py	2014-10-23 11:19:50.000000000 -0500
@@ -345,7 +345,7 @@
         for param in sorted(http_request.params):
             value = boto.utils.get_utf8_value(http_request.params[param])
             l.append('%s=%s' % (urllib.parse.quote(param, safe='-_.~'),
-                                urllib.parse.quote(value.decode('utf-8'), safe='-_.~')))
+                                urllib.parse.quote(value, safe='-_.~')))
         return '&'.join(l)
 
     def canonical_headers(self, headers_to_sign):
@@ -494,10 +494,25 @@
         if self._provider.security_token:
             req.headers['X-Amz-Security-Token'] = self._provider.security_token
         qs = self.query_string(req)
-        if qs and req.method == 'POST':
+
+        qs_to_post = qs
+
+        # We do not want to include any params that were mangled into
+        # the params if performing s3-sigv4 since it does not
+        # belong in the body of a post for some requests.  Mangled
+        # refers to items in the query string URL being added to the
+        # http response params. However, these params get added to
+        # the body of the request, but the query string URL does not
+        # belong in the body of the request. ``unmangled_resp`` is the
+        # response that happened prior to the mangling.  This ``unmangled_req``
+        # kwarg will only appear for s3-sigv4.
+        if 'unmangled_req' in kwargs:
+            qs_to_post = self.query_string(kwargs['unmangled_req'])
+
+        if qs_to_post and req.method == 'POST':
             # Stash request parameters into post body
             # before we generate the signature.
-            req.body = qs
+            req.body = qs_to_post
             req.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
             req.headers['Content-Length'] = str(len(req.body))
         else:
@@ -549,6 +564,17 @@
         encoded = urllib.parse.quote(unquoted)
         return encoded
 
+    def canonical_query_string(self, http_request):
+        # Note that we just do not return an empty string for
+        # POST request. Query strings in url are included in canonical
+        # query string.
+        l = []
+        for param in sorted(http_request.params):
+            value = boto.utils.get_utf8_value(http_request.params[param])
+            l.append('%s=%s' % (urllib.parse.quote(param, safe='-_.~'),
+                                urllib.parse.quote(value, safe='-_.~')))
+        return '&'.join(l)
+
     def host_header(self, host, http_request):
         port = http_request.port
         secure = http_request.protocol == 'https'
@@ -641,6 +667,13 @@
 
         if modified_req.params is None:
             modified_req.params = {}
+        else:
+            # To keep the original request object untouched. We must make
+            # a copy of the params dictionary. Because the copy of the
+            # original request directly refers to the params dictionary
+            # of the original request.
+            copy_params = req.params.copy()
+            modified_req.params = copy_params
 
         raw_qs = parsed_path.query
         existing_qs = urllib.parse.parse_qs(
@@ -670,9 +703,10 @@
                 req.headers['x-amz-content-sha256'] = req.headers.pop('_sha256')
             else:
                 req.headers['x-amz-content-sha256'] = self.payload(req)
-
-        req = self.mangle_path_and_params(req)
-        return super(S3HmacAuthV4Handler, self).add_auth(req, **kwargs)
+        updated_req = self.mangle_path_and_params(req)
+        return super(S3HmacAuthV4Handler, self).add_auth(updated_req,
+                                                         unmangled_req=req,
+                                                         **kwargs)
 
     def presign(self, req, expires, iso_date=None):
         """
@@ -966,7 +1000,8 @@
             # ``boto/iam/connection.py``, as several things there are also
             # endpoint-related.
             if getattr(self.region, 'endpoint', ''):
-                if '.cn-' in self.region.endpoint:
+                if '.cn-' in self.region.endpoint or \
+                        '.eu-central' in self.region.endpoint:
                     return ['hmac-v4']
 
         return func(self)
@@ -985,7 +1020,7 @@
             # If you're making changes here, you should also check
             # ``boto/iam/connection.py``, as several things there are also
             # endpoint-related.
-            if '.cn-' in self.host:
+            if '.cn-' in self.host or '.eu-central' in self.host:
                 return ['hmac-v4-s3']
 
         return func(self)
diff -Nru python-boto-2.33.0/boto/cloudtrail/exceptions.py python-boto-2.34.0/boto/cloudtrail/exceptions.py
diff -Nru python-boto-2.33.0/boto/cloudtrail/layer1.py python-boto-2.34.0/boto/cloudtrail/layer1.py
diff -Nru python-boto-2.33.0/boto/datapipeline/layer1.py python-boto-2.34.0/boto/datapipeline/layer1.py
diff -Nru python-boto-2.33.0/boto/directconnect/exceptions.py python-boto-2.34.0/boto/directconnect/exceptions.py
diff -Nru python-boto-2.33.0/boto/directconnect/layer1.py python-boto-2.34.0/boto/directconnect/layer1.py
diff -Nru python-boto-2.33.0/boto/endpoints.json python-boto-2.34.0/boto/endpoints.json
--- python-boto-2.33.0/boto/endpoints.json	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/boto/endpoints.json	2014-10-23 11:19:50.000000000 -0500
@@ -9,7 +9,8 @@
         "us-east-1": "autoscaling.us-east-1.amazonaws.com",
         "us-gov-west-1": "autoscaling.us-gov-west-1.amazonaws.com",
         "us-west-1": "autoscaling.us-west-1.amazonaws.com",
-        "us-west-2": "autoscaling.us-west-2.amazonaws.com"
+        "us-west-2": "autoscaling.us-west-2.amazonaws.com",
+        "eu-central-1": "autoscaling.eu-central-1.amazonaws.com"
     },
     "cloudformation": {
         "ap-northeast-1": "cloudformation.ap-northeast-1.amazonaws.com",
@@ -21,7 +22,8 @@
         "us-east-1": "cloudformation.us-east-1.amazonaws.com",
         "us-gov-west-1": "cloudformation.us-gov-west-1.amazonaws.com",
         "us-west-1": "cloudformation.us-west-1.amazonaws.com",
-        "us-west-2": "cloudformation.us-west-2.amazonaws.com"
+        "us-west-2": "cloudformation.us-west-2.amazonaws.com",
+        "eu-central-1": "cloudformation.eu-central-1.amazonaws.com"
     },
     "cloudfront": {
         "ap-northeast-1": "cloudfront.amazonaws.com",
@@ -31,7 +33,8 @@
         "sa-east-1": "cloudfront.amazonaws.com",
         "us-east-1": "cloudfront.amazonaws.com",
         "us-west-1": "cloudfront.amazonaws.com",
-        "us-west-2": "cloudfront.amazonaws.com"
+        "us-west-2": "cloudfront.amazonaws.com",
+        "eu-central-1": "cloudfront.amazonaws.com"
     },
     "cloudsearch": {
         "ap-southeast-1": "cloudsearch.ap-southeast-1.amazonaws.com",
@@ -41,7 +44,8 @@
         "eu-west-1": "cloudsearch.eu-west-1.amazonaws.com",
         "us-east-1": "cloudsearch.us-east-1.amazonaws.com",
         "us-west-1": "cloudsearch.us-west-1.amazonaws.com",
-        "us-west-2": "cloudsearch.us-west-2.amazonaws.com"
+        "us-west-2": "cloudsearch.us-west-2.amazonaws.com",
+        "eu-central-1": "cloudsearch.eu-central-1.amazonaws.com"
     },
     "cloudtrail": {
         "ap-northeast-1": "cloudtrail.ap-northeast-1.amazonaws.com",
@@ -51,7 +55,8 @@
         "sa-east-1": "cloudtrail.sa-east-1.amazonaws.com",
         "us-east-1": "cloudtrail.us-east-1.amazonaws.com",
         "us-west-1": "cloudtrail.us-west-1.amazonaws.com",
-        "us-west-2": "cloudtrail.us-west-2.amazonaws.com"
+        "us-west-2": "cloudtrail.us-west-2.amazonaws.com",
+        "eu-central-1": "cloudtrail.eu-central-1.amazonaws.com"
     },
     "cloudwatch": {
         "ap-northeast-1": "monitoring.ap-northeast-1.amazonaws.com",
@@ -63,7 +68,8 @@
         "us-east-1": "monitoring.us-east-1.amazonaws.com",
         "us-gov-west-1": "monitoring.us-gov-west-1.amazonaws.com",
         "us-west-1": "monitoring.us-west-1.amazonaws.com",
-        "us-west-2": "monitoring.us-west-2.amazonaws.com"
+        "us-west-2": "monitoring.us-west-2.amazonaws.com",
+        "eu-central-1": "monitoring.eu-central-1.amazonaws.com"
     },
     "cognito-identity": {
         "us-east-1": "cognito-identity.us-east-1.amazonaws.com"
@@ -76,7 +82,8 @@
         "us-west-2": "datapipeline.us-west-2.amazonaws.com",
         "eu-west-1": "datapipeline.eu-west-1.amazonaws.com",
         "ap-southeast-2": "datapipeline.ap-southeast-2.amazonaws.com",
-        "ap-northeast-1": "datapipeline.ap-northeast-1.amazonaws.com"
+        "ap-northeast-1": "datapipeline.ap-northeast-1.amazonaws.com",
+        "eu-central-1": "datapipeline.eu-central-1.amazonaws.com"
     },
     "directconnect": {
         "ap-northeast-1": "directconnect.ap-northeast-1.amazonaws.com",
@@ -86,7 +93,8 @@
         "sa-east-1": "directconnect.sa-east-1.amazonaws.com",
         "us-east-1": "directconnect.us-east-1.amazonaws.com",
         "us-west-1": "directconnect.us-west-1.amazonaws.com",
-        "us-west-2": "directconnect.us-west-2.amazonaws.com"
+        "us-west-2": "directconnect.us-west-2.amazonaws.com",
+        "eu-central-1": "directconnect.eu-central-1.amazonaws.com"
     },
     "dynamodb": {
         "ap-northeast-1": "dynamodb.ap-northeast-1.amazonaws.com",
@@ -98,7 +106,8 @@
         "us-east-1": "dynamodb.us-east-1.amazonaws.com",
         "us-gov-west-1": "dynamodb.us-gov-west-1.amazonaws.com",
         "us-west-1": "dynamodb.us-west-1.amazonaws.com",
-        "us-west-2": "dynamodb.us-west-2.amazonaws.com"
+        "us-west-2": "dynamodb.us-west-2.amazonaws.com",
+        "eu-central-1": "dynamodb.eu-central-1.amazonaws.com"
     },
     "ec2": {
         "ap-northeast-1": "ec2.ap-northeast-1.amazonaws.com",
@@ -110,7 +119,8 @@
         "us-east-1": "ec2.us-east-1.amazonaws.com",
         "us-gov-west-1": "ec2.us-gov-west-1.amazonaws.com",
         "us-west-1": "ec2.us-west-1.amazonaws.com",
-        "us-west-2": "ec2.us-west-2.amazonaws.com"
+        "us-west-2": "ec2.us-west-2.amazonaws.com",
+        "eu-central-1": "ec2.eu-central-1.amazonaws.com"
     },
     "elasticache": {
         "ap-northeast-1": "elasticache.ap-northeast-1.amazonaws.com",
@@ -121,7 +131,8 @@
         "sa-east-1": "elasticache.sa-east-1.amazonaws.com",
         "us-east-1": "elasticache.us-east-1.amazonaws.com",
         "us-west-1": "elasticache.us-west-1.amazonaws.com",
-        "us-west-2": "elasticache.us-west-2.amazonaws.com"
+        "us-west-2": "elasticache.us-west-2.amazonaws.com",
+        "eu-central-1": "elasticache.eu-central-1.amazonaws.com"
     },
     "elasticbeanstalk": {
         "ap-northeast-1": "elasticbeanstalk.ap-northeast-1.amazonaws.com",
@@ -131,7 +142,8 @@
         "sa-east-1": "elasticbeanstalk.sa-east-1.amazonaws.com",
         "us-east-1": "elasticbeanstalk.us-east-1.amazonaws.com",
         "us-west-1": "elasticbeanstalk.us-west-1.amazonaws.com",
-        "us-west-2": "elasticbeanstalk.us-west-2.amazonaws.com"
+        "us-west-2": "elasticbeanstalk.us-west-2.amazonaws.com",
+        "eu-central-1": "elasticbeanstalk.eu-central-1.amazonaws.com"
     },
     "elasticloadbalancing": {
         "ap-northeast-1": "elasticloadbalancing.ap-northeast-1.amazonaws.com",
@@ -143,7 +155,8 @@
         "us-east-1": "elasticloadbalancing.us-east-1.amazonaws.com",
         "us-gov-west-1": "elasticloadbalancing.us-gov-west-1.amazonaws.com",
         "us-west-1": "elasticloadbalancing.us-west-1.amazonaws.com",
-        "us-west-2": "elasticloadbalancing.us-west-2.amazonaws.com"
+        "us-west-2": "elasticloadbalancing.us-west-2.amazonaws.com",
+        "eu-central-1": "elasticloadbalancing.eu-central-1.amazonaws.com"
     },
     "elasticmapreduce": {
         "ap-northeast-1": "ap-northeast-1.elasticmapreduce.amazonaws.com",
@@ -155,7 +168,8 @@
         "us-east-1": "elasticmapreduce.us-east-1.amazonaws.com",
         "us-gov-west-1": "us-gov-west-1.elasticmapreduce.amazonaws.com",
         "us-west-1": "us-west-1.elasticmapreduce.amazonaws.com",
-        "us-west-2": "us-west-2.elasticmapreduce.amazonaws.com"
+        "us-west-2": "us-west-2.elasticmapreduce.amazonaws.com",
+        "eu-central-1": "eu-central-1.elasticmapreduce.amazonaws.com"
     },
     "elastictranscoder": {
         "ap-northeast-1": "elastictranscoder.ap-northeast-1.amazonaws.com",
@@ -163,7 +177,8 @@
         "eu-west-1": "elastictranscoder.eu-west-1.amazonaws.com",
         "us-east-1": "elastictranscoder.us-east-1.amazonaws.com",
         "us-west-1": "elastictranscoder.us-west-1.amazonaws.com",
-        "us-west-2": "elastictranscoder.us-west-2.amazonaws.com"
+        "us-west-2": "elastictranscoder.us-west-2.amazonaws.com",
+        "eu-central-1": "elastictranscoder.eu-central-1.amazonaws.com"
     },
     "glacier": {
         "ap-northeast-1": "glacier.ap-northeast-1.amazonaws.com",
@@ -172,7 +187,8 @@
         "eu-west-1": "glacier.eu-west-1.amazonaws.com",
         "us-east-1": "glacier.us-east-1.amazonaws.com",
         "us-west-1": "glacier.us-west-1.amazonaws.com",
-        "us-west-2": "glacier.us-west-2.amazonaws.com"
+        "us-west-2": "glacier.us-west-2.amazonaws.com",
+        "eu-central-1": "glacier.eu-central-1.amazonaws.com"
     },
     "iam": {
         "ap-northeast-1": "iam.amazonaws.com",
@@ -202,13 +218,18 @@
         "eu-west-1": "kinesis.eu-west-1.amazonaws.com",
         "ap-southeast-1": "kinesis.ap-southeast-1.amazonaws.com",
         "ap-southeast-2": "kinesis.ap-southeast-2.amazonaws.com",
-        "ap-northeast-1": "kinesis.ap-northeast-1.amazonaws.com"
+        "ap-northeast-1": "kinesis.ap-northeast-1.amazonaws.com",
+        "eu-central-1": "kinesis.eu-central-1.amazonaws.com"
     },
     "logs": {
-        "us-east-1": "logs.us-east-1.amazonaws.com"
+        "us-east-1": "logs.us-east-1.amazonaws.com",
+        "us-west-2": "logs.us-west-2.amazonaws.com",
+        "eu-west-1": "logs.eu-west-1.amazonaws.com",
+        "eu-central-1": "logs.eu-central-1.amazonaws.com"
     },
     "opsworks": {
-        "us-east-1": "opsworks.us-east-1.amazonaws.com"
+        "us-east-1": "opsworks.us-east-1.amazonaws.com",
+        "eu-central-1": "opsworks.eu-central-1.amazonaws.com"
     },
     "rds": {
         "ap-northeast-1": "rds.ap-northeast-1.amazonaws.com",
@@ -220,7 +241,8 @@
         "us-east-1": "rds.amazonaws.com",
         "us-gov-west-1": "rds.us-gov-west-1.amazonaws.com",
         "us-west-1": "rds.us-west-1.amazonaws.com",
-        "us-west-2": "rds.us-west-2.amazonaws.com"
+        "us-west-2": "rds.us-west-2.amazonaws.com",
+        "eu-central-1": "rds.eu-central-1.amazonaws.com"
     },
     "redshift": {
         "ap-northeast-1": "redshift.ap-northeast-1.amazonaws.com",
@@ -228,7 +250,8 @@
         "ap-southeast-2": "redshift.ap-southeast-2.amazonaws.com",
         "eu-west-1": "redshift.eu-west-1.amazonaws.com",
         "us-east-1": "redshift.us-east-1.amazonaws.com",
-        "us-west-2": "redshift.us-west-2.amazonaws.com"
+        "us-west-2": "redshift.us-west-2.amazonaws.com",
+        "eu-central-1": "redshift.eu-central-1.amazonaws.com"
     },
     "route53": {
         "ap-northeast-1": "route53.amazonaws.com",
@@ -253,7 +276,8 @@
         "us-east-1": "s3.amazonaws.com",
         "us-gov-west-1": "s3-us-gov-west-1.amazonaws.com",
         "us-west-1": "s3-us-west-1.amazonaws.com",
-        "us-west-2": "s3-us-west-2.amazonaws.com"
+        "us-west-2": "s3-us-west-2.amazonaws.com",
+        "eu-central-1": "s3.eu-central-1.amazonaws.com"
     },
     "sdb": {
         "ap-northeast-1": "sdb.ap-northeast-1.amazonaws.com",
@@ -263,12 +287,14 @@
         "sa-east-1": "sdb.sa-east-1.amazonaws.com",
         "us-east-1": "sdb.amazonaws.com",
         "us-west-1": "sdb.us-west-1.amazonaws.com",
-        "us-west-2": "sdb.us-west-2.amazonaws.com"
+        "us-west-2": "sdb.us-west-2.amazonaws.com",
+        "eu-central-1": "sdb.eu-central-1.amazonaws.com"
     },
     "ses": {
         "eu-west-1": "email.eu-west-1.amazonaws.com",
         "us-east-1": "email.us-east-1.amazonaws.com",
-        "us-west-2": "email.us-west-2.amazonaws.com"
+        "us-west-2": "email.us-west-2.amazonaws.com",
+        "eu-central-1": "email.eu-central-1.amazonaws.com"
     },
     "sns": {
         "ap-northeast-1": "sns.ap-northeast-1.amazonaws.com",
@@ -280,7 +306,8 @@
         "us-east-1": "sns.us-east-1.amazonaws.com",
         "us-gov-west-1": "sns.us-gov-west-1.amazonaws.com",
         "us-west-1": "sns.us-west-1.amazonaws.com",
-        "us-west-2": "sns.us-west-2.amazonaws.com"
+        "us-west-2": "sns.us-west-2.amazonaws.com",
+        "eu-central-1": "sns.eu-central-1.amazonaws.com"
     },
     "sqs": {
         "ap-northeast-1": "ap-northeast-1.queue.amazonaws.com",
@@ -292,7 +319,8 @@
         "us-east-1": "queue.amazonaws.com",
         "us-gov-west-1": "us-gov-west-1.queue.amazonaws.com",
         "us-west-1": "us-west-1.queue.amazonaws.com",
-        "us-west-2": "us-west-2.queue.amazonaws.com"
+        "us-west-2": "us-west-2.queue.amazonaws.com",
+        "eu-central-1": "eu-central-1.queue.amazonaws.com"
     },
     "storagegateway": {
         "ap-northeast-1": "storagegateway.ap-northeast-1.amazonaws.com",
@@ -302,7 +330,8 @@
         "sa-east-1": "storagegateway.sa-east-1.amazonaws.com",
         "us-east-1": "storagegateway.us-east-1.amazonaws.com",
         "us-west-1": "storagegateway.us-west-1.amazonaws.com",
-        "us-west-2": "storagegateway.us-west-2.amazonaws.com"
+        "us-west-2": "storagegateway.us-west-2.amazonaws.com",
+        "eu-central-1": "storagegateway.eu-central-1.amazonaws.com"
     },
     "sts": {
         "ap-northeast-1": "sts.amazonaws.com",
@@ -317,7 +346,8 @@
         "us-west-2": "sts.amazonaws.com"
     },
     "support": {
-        "us-east-1": "support.us-east-1.amazonaws.com"
+        "us-east-1": "support.us-east-1.amazonaws.com",
+        "eu-central-1": "support.eu-central-1.amazonaws.com"
     },
     "swf": {
         "ap-northeast-1": "swf.ap-northeast-1.amazonaws.com",
@@ -329,6 +359,7 @@
         "us-east-1": "swf.us-east-1.amazonaws.com",
         "us-gov-west-1": "swf.us-gov-west-1.amazonaws.com",
         "us-west-1": "swf.us-west-1.amazonaws.com",
-        "us-west-2": "swf.us-west-2.amazonaws.com"
+        "us-west-2": "swf.us-west-2.amazonaws.com",
+        "eu-central-1": "swf.eu-central-1.amazonaws.com"
     }
 }
diff -Nru python-boto-2.33.0/boto/iam/connection.py python-boto-2.34.0/boto/iam/connection.py
--- python-boto-2.33.0/boto/iam/connection.py	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/boto/iam/connection.py	2014-10-23 11:19:50.000000000 -0500
@@ -1523,3 +1523,24 @@
         """
         params = {}
         return self.get_response('GetCredentialReport', params)
+
+    def create_virtual_mfa_device(self, path, device_name):
+        """
+        Creates a new virtual MFA device for the AWS account.
+
+        After creating the virtual MFA, use enable-mfa-device to
+        attach the MFA device to an IAM user.
+
+        :type path: string
+        :param path: The path for the virtual MFA device.
+
+        :type device_name: string
+        :param device_name: The name of the virtual MFA device.
+            Used with path to uniquely identify a virtual MFA device.
+
+        """
+        params = {
+            'Path': path,
+            'VirtualMFADeviceName': device_name
+        }
+        return self.get_response('CreateVirtualMFADevice', params)
diff -Nru python-boto-2.33.0/boto/__init__.py python-boto-2.34.0/boto/__init__.py
--- python-boto-2.33.0/boto/__init__.py	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/boto/__init__.py	2014-10-23 11:19:50.000000000 -0500
@@ -38,7 +38,7 @@
 from boto.compat import urlparse
 from boto.exception import InvalidUriError
 
-__version__ = '2.33.0'
+__version__ = '2.34.0'
 Version = __version__  # for backware compatibility
 
 # http://bugs.python.org/issue7980
diff -Nru python-boto-2.33.0/boto/logs/layer1.py python-boto-2.34.0/boto/logs/layer1.py
diff -Nru python-boto-2.33.0/boto/mws/connection.py python-boto-2.34.0/boto/mws/connection.py
--- python-boto-2.33.0/boto/mws/connection.py	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/boto/mws/connection.py	2014-10-23 11:19:50.000000000 -0500
@@ -309,7 +309,7 @@
         try:
             response = self._mexe(request, override_num_retries=None)
         except BotoServerError as bs:
-            raise self._response_error_factor(bs.status, bs.reason, bs.body)
+            raise self._response_error_factory(bs.status, bs.reason, bs.body)
         body = response.read()
         boto.log.debug(body)
         if not body:
diff -Nru python-boto-2.33.0/boto/s3/key.py python-boto-2.34.0/boto/s3/key.py
--- python-boto-2.33.0/boto/s3/key.py	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/boto/s3/key.py	2014-10-23 11:19:50.000000000 -0500
@@ -934,7 +934,10 @@
         # the auth mechanism (because closures). Detect if it's SigV4 & embelish
         # while we can before the auth calculations occur.
         if 'hmac-v4-s3' in self.bucket.connection._required_auth_capability():
-            headers['_sha256'] = compute_hash(fp, hash_algorithm=hashlib.sha256)[0]
+            kwargs = {'fp': fp, 'hash_algorithm': hashlib.sha256}
+            if size is not None:
+                kwargs['size'] = size
+            headers['_sha256'] = compute_hash(**kwargs)[0]
         headers['Expect'] = '100-Continue'
         headers = boto.utils.merge_meta(headers, self.metadata, provider)
         resp = self.bucket.connection.make_request(
diff -Nru python-boto-2.33.0/debian/changelog python-boto-2.34.0/debian/changelog
--- python-boto-2.33.0/debian/changelog	2014-11-12 14:56:27.000000000 -0600
+++ python-boto-2.34.0/debian/changelog	2014-11-12 14:56:27.000000000 -0600
@@ -1,3 +1,15 @@
+python-boto (2.34.0-2) unstable; urgency=medium
+
+  * Upload to unstable.
+
+ -- Eric Evans <eevans@debian.org>  Wed, 12 Nov 2014 11:39:34 -0600
+
+python-boto (2.34.0-1) experimental; urgency=medium
+
+  * New upstream release.
+
+ -- Eric Evans <eevans@debian.org>  Mon, 10 Nov 2014 20:39:11 -0600
+
 python-boto (2.33.0-1) unstable; urgency=medium
 
   * New upstream release.
diff -Nru python-boto-2.33.0/docs/source/index.rst python-boto-2.34.0/docs/source/index.rst
--- python-boto-2.33.0/docs/source/index.rst	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/docs/source/index.rst	2014-10-23 11:19:50.000000000 -0500
@@ -73,8 +73,8 @@
   * :doc:`Simple Queue Service (SQS) <sqs_tut>` -- (:doc:`API Reference <ref/sqs>`) (Python 3)
   * Simple Notification Service (SNS) -- (:doc:`API Reference <ref/sns>`) (Python 3)
   * :doc:`Simple Email Service (SES) <ses_tut>` -- (:doc:`API Reference <ref/ses>`) (Python 3)
-  * Amazon Cognito Identity -- (:doc:`API Reference <ref/cognito-identity`) (Python 3)
-  * Amazon Cognito Sync -- (:doc:`API Reference <ref/cognito-sync`) (Python 3)
+  * Amazon Cognito Identity -- (:doc:`API Reference <ref/cognito-identity>`) (Python 3)
+  * Amazon Cognito Sync -- (:doc:`API Reference <ref/cognito-sync>`) (Python 3)
 
 * **Monitoring**
 
@@ -135,6 +135,7 @@
 .. toctree::
    :titlesonly:
 
+   releasenotes/v2.34.0
    releasenotes/v2.33.0
    releasenotes/v2.32.1
    releasenotes/v2.32.0
diff -Nru python-boto-2.33.0/docs/source/releasenotes/v2.34.0.rst python-boto-2.34.0/docs/source/releasenotes/v2.34.0.rst
--- python-boto-2.33.0/docs/source/releasenotes/v2.34.0.rst	1969-12-31 18:00:00.000000000 -0600
+++ python-boto-2.34.0/docs/source/releasenotes/v2.34.0.rst	2014-10-23 11:19:50.000000000 -0500
@@ -0,0 +1,21 @@
+boto v2.34.0
+============
+
+:date: 2014/10/23
+
+This release adds region support for ``eu-central-1`` , support to create
+virtual mfa devices for Identity and Access Management, and fixes several
+sigv4 issues.
+
+
+Changes
+-------
+* Calculate sha_256 correctly for s3 (:issue:`2691`, :sha:`c0a001f`)
+* Fix MTurk typo. (:issue:`2429`, :issue:`2428`, :sha:`9bfff19`)
+* Fix Amazon Cognito links in docs (:issue:`2674`, :sha:`7c28577`)
+* Add the ability to IAM to create a virtual mfa device. (:issue:`2675`, :sha:`075d402`)
+* PEP8 tidy up for several modules. (:issue:`2673`, :sha:`38abbd9`)
+* Fix s3 create multipart upload for sigv4 (:issue:`2684`, :sha:`fc73641`)
+* Updated endpoints.json for cloudwatch logs to support more regions. (:issue:`2685`, :sha:`5db2ea8`)
+
+
diff -Nru python-boto-2.33.0/docs/source/s3_tut.rst python-boto-2.34.0/docs/source/s3_tut.rst
--- python-boto-2.33.0/docs/source/s3_tut.rst	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/docs/source/s3_tut.rst	2014-10-23 11:19:50.000000000 -0500
@@ -143,7 +143,7 @@
 to and from S3 so you should be able to send and receive large files without
 any problem.
 
-When fetching a key that has already exists, you have two options. If you're
+When fetching a key that already exists, you have two options. If you're
 uncertain whether a key exists (or if you need the metadata set on it, you can
 call ``Bucket.get_key(key_name_here)``. However, if you're sure a key already
 exists within a bucket, you can skip the check for a key on the server.
diff -Nru python-boto-2.33.0/README.rst python-boto-2.34.0/README.rst
--- python-boto-2.33.0/README.rst	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/README.rst	2014-10-23 11:19:50.000000000 -0500
@@ -1,9 +1,9 @@
 ####
 boto
 ####
-boto 2.33.0
+boto 2.34.0
 
-Released: 08-Oct-2014
+Released: 23-Oct-2014
 
 .. image:: https://travis-ci.org/boto/boto.svg?branch=develop
         :target: https://travis-ci.org/boto/boto
diff -Nru python-boto-2.33.0/requirements-docs.txt python-boto-2.34.0/requirements-docs.txt
--- python-boto-2.33.0/requirements-docs.txt	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/requirements-docs.txt	2014-10-23 11:19:50.000000000 -0500
@@ -1,6 +1,6 @@
 requests>=1.2.3,<=2.0.1
 rsa==3.1.4
-Sphinx==1.1.3
+Sphinx>=1.1.3,<1.3
 simplejson==3.5.2
 argparse==1.2.1
 paramiko>=1.10.0
diff -Nru python-boto-2.33.0/tests/integration/s3/test_multipart.py python-boto-2.34.0/tests/integration/s3/test_multipart.py
--- python-boto-2.33.0/tests/integration/s3/test_multipart.py	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/tests/integration/s3/test_multipart.py	2014-10-23 11:19:50.000000000 -0500
@@ -32,10 +32,14 @@
 # bigger than 5M. Hence we just use 1 part so we can keep
 # things small and still test logic.
 
+import os
 import unittest
 import time
 from boto.compat import StringIO
 
+import mock
+
+import boto
 from boto.s3.connection import S3Connection
 
 
@@ -163,3 +167,63 @@
             pn += 1
         # Can't complete 2 small parts so just clean up.
         mpu.cancel_upload()
+
+
+class S3MultiPartUploadSigV4Test(unittest.TestCase):
+    s3 = True
+
+    def setUp(self):
+        self.env_patch = mock.patch('os.environ', {'S3_USE_SIGV4': True})
+        self.env_patch.start()
+        self.conn = boto.s3.connect_to_region('us-west-2')
+        self.bucket_name = 'multipart-%d' % int(time.time())
+        self.bucket = self.conn.create_bucket(self.bucket_name,
+                                              location='us-west-2')
+
+    def tearDown(self):
+        for key in self.bucket:
+            key.delete()
+        self.bucket.delete()
+        self.env_patch.stop()
+
+    def test_initiate_multipart(self):
+        key_name = "multipart"
+        multipart_upload = self.bucket.initiate_multipart_upload(key_name)
+        multipart_uploads = self.bucket.get_all_multipart_uploads()
+        for upload in multipart_uploads:
+            # Check that the multipart upload was created.
+            self.assertEqual(upload.key_name, multipart_upload.key_name)
+            self.assertEqual(upload.id, multipart_upload.id)
+        multipart_upload.cancel_upload()
+
+    def test_upload_part_by_size(self):
+        key_name = "k"
+        contents = "01234567890123456789"
+        sfp = StringIO(contents)
+
+        # upload 20 bytes in 4 parts of 5 bytes each
+        mpu = self.bucket.initiate_multipart_upload(key_name)
+        mpu.upload_part_from_file(sfp, part_num=1, size=5)
+        mpu.upload_part_from_file(sfp, part_num=2, size=5)
+        mpu.upload_part_from_file(sfp, part_num=3, size=5)
+        mpu.upload_part_from_file(sfp, part_num=4, size=5)
+        sfp.close()
+
+        etags = {}
+        pn = 0
+        for part in mpu:
+            pn += 1
+            self.assertEqual(5, part.size)
+            etags[pn] = part.etag
+        self.assertEqual(pn, 4)
+        # etags for 01234
+        self.assertEqual(etags[1], etags[3])
+        # etags for 56789
+        self.assertEqual(etags[2], etags[4])
+        # etag 01234 != etag 56789
+        self.assertNotEqual(etags[1], etags[2])
+
+        # parts are too small to complete as each part must
+        # be a min of 5MB so so we'll assume that is enough
+        # testing and abort the upload.
+        mpu.cancel_upload()
diff -Nru python-boto-2.33.0/tests/unit/iam/test_connection.py python-boto-2.34.0/tests/unit/iam/test_connection.py
--- python-boto-2.33.0/tests/unit/iam/test_connection.py	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/tests/unit/iam/test_connection.py	2014-10-23 11:19:50.000000000 -0500
@@ -360,3 +360,36 @@
         b64decode(response['get_credential_report_response']
                           ['get_credential_report_result']
                           ['content'])
+
+class TestCreateVirtualMFADevice(AWSMockServiceTestCase):
+    connection_class = IAMConnection
+
+    def default_body(self):
+        return b"""
+            <CreateVirtualMFADeviceResponse>
+              <CreateVirtualMFADeviceResult>
+                <VirtualMFADevice>
+                  <SerialNumber>arn:aws:iam::123456789012:mfa/ExampleName</SerialNumber>
+                  <Base32StringSeed>2K5K5XTLA7GGE75TQLYEXAMPLEEXAMPLEEXAMPLECHDFW4KJYZ6
+                  UFQ75LL7COCYKM</Base32StringSeed>
+                  <QRCodePNG>89504E470D0A1A0AASDFAHSDFKJKLJFKALSDFJASDF</QRCodePNG>
+                </VirtualMFADevice>
+              </CreateVirtualMFADeviceResult>
+              <ResponseMetadata>
+                <RequestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</RequestId>
+              </ResponseMetadata>
+            </CreateVirtualMFADeviceResponse>
+        """
+
+    def test_create_virtual_mfa_device(self):
+        self.set_http_response(status_code=200)
+        response = self.service_connection.create_virtual_mfa_device('/', 'ExampleName')
+        self.assert_request_parameters(
+            {'Path': '/',
+             'VirtualMFADeviceName': 'ExampleName',
+             'Action': 'CreateVirtualMFADevice'},
+            ignore_params_values=['Version'])
+        self.assertEquals(response['create_virtual_mfa_device_response']
+                                  ['create_virtual_mfa_device_result']
+                                  ['virtual_mfa_device']
+                                  ['serial_number'], 'arn:aws:iam::123456789012:mfa/ExampleName')
diff -Nru python-boto-2.33.0/tests/unit/mws/test_connection.py python-boto-2.34.0/tests/unit/mws/test_connection.py
--- python-boto-2.33.0/tests/unit/mws/test_connection.py	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/tests/unit/mws/test_connection.py	2014-10-23 11:19:50.000000000 -0500
@@ -23,10 +23,14 @@
 from boto.mws.connection import MWSConnection, api_call_map, destructure_object
 from boto.mws.response import (ResponseElement, GetFeedSubmissionListResult,
                                ResponseFactory)
+from boto.exception import BotoServerError
+
 from tests.compat import unittest
 
 from tests.unit import AWSMockServiceTestCase
 
+from mock import MagicMock
+
 
 class TestMWSConnection(AWSMockServiceTestCase):
     connection_class = MWSConnection
@@ -51,6 +55,22 @@
   </ResponseMetadata>
 </GetFeedSubmissionListResponse>"""
 
+    def default_body_error(self):
+        return b"""<?xml version="1.0" encoding="UTF-8"?>
+<ErrorResponse xmlns="http://mws.amazonaws.com/doc/2009-01-01/";>
+  <!--1 or more repetitions:-->
+  <Error>
+    <Type>Sender</Type>
+    <Code>string</Code>
+    <Message>string</Message>
+    <Detail>
+      <!--You may enter ANY elements at this point-->
+      <AnyElement xmlns=""/>
+    </Detail>
+  </Error>
+  <RequestId>string</RequestId>
+</ErrorResponse>"""
+
     def test_destructure_object(self):
         # Test that parsing of user input to Amazon input works.
         response = ResponseElement()
@@ -156,6 +176,22 @@
         self.assertTrue('inventory' in str(err.exception))
         self.assertTrue('feeds' in str(err.exception))
 
+    def test_post_request(self):
+
+        self.service_connection._mexe = MagicMock(
+            side_effect=
+                BotoServerError(500, 'You request has bee throttled', body=self.default_body_error()))
+
+        with self.assertRaises(BotoServerError) as err:
+            self.service_connection.get_lowest_offer_listings_for_asin(
+                MarketplaceId='12345',
+                ASINList='ASIN12345',
+                condition='Any',
+                SellerId='1234',
+                excludeme='True')
+
+            self.assertTrue('throttled' in str(err.reason))
+            self.assertEqual(int(err.status), 200)
 
 if __name__ == '__main__':
     unittest.main()
diff -Nru python-boto-2.33.0/tests/unit/test_regioninfo.py python-boto-2.34.0/tests/unit/test_regioninfo.py
--- python-boto-2.33.0/tests/unit/test_regioninfo.py	2014-10-08 14:41:04.000000000 -0500
+++ python-boto-2.34.0/tests/unit/test_regioninfo.py	2014-10-23 11:19:50.000000000 -0500
@@ -104,7 +104,7 @@
     def test_get_regions(self):
         # With defaults.
         ec2_regions = get_regions('ec2')
-        self.assertEqual(len(ec2_regions), 10)
+        self.assertTrue(len(ec2_regions) >= 10)
         west_2 = None
 
         for region_info in ec2_regions:
@@ -124,7 +124,7 @@
             region_cls=TestRegionInfo,
             connection_cls=FakeConn
         )
-        self.assertEqual(len(ec2_regions), 10)
+        self.assertTrue(len(ec2_regions) >= 10)
         west_2 = None
 
         for region_info in ec2_regions:
python-boto (2.34.0-2) unstable; urgency=medium

  * Upload to unstable.

 -- Eric Evans <eevans@debian.org>  Wed, 12 Nov 2014 11:39:34 -0600

python-boto (2.34.0-1) experimental; urgency=medium

  * New upstream release.

 -- Eric Evans <eevans@debian.org>  Mon, 10 Nov 2014 20:39:11 -0600

Attachment: signature.asc
Description: Digital signature


--- End Message ---
--- Begin Message ---
On Wed, Nov 12, 2014 at 03:35:37PM -0600, Eric Evans wrote:
> Please unblock package python-boto to address bts#769310.

Unblocked.

> I also failed to reference
> #769310 in the changelog.  Sorry about that, I have no excuse.

Fixed that for you, otherwise it'll never migrate.


-- 
Jonathan Wiltshire                                      jmw@debian.org
Debian Developer                         http://people.debian.org/~jmw

4096R: 0xD3524C51 / 0A55 B7C5 1223 3942 86EC  74C3 5394 479D D352 4C51

Attachment: signature.asc
Description: Digital signature


--- End Message ---

Reply to: