Skip to content

Commit

Permalink
Specify location when creating s3 bucket.
Browse files Browse the repository at this point in the history
Fixes bug 961050

Avoids bucket creation failure when a region-specific S3 endpoint
(e.g. s3-eu-west-1.amazonaws.com) and also bucket create-on-demand
are configured.

Change-Id: Ieba9c535ccb961a1f81bd2632b5ac49c23ac7901
  • Loading branch information
Eoghan Glynn authored and bcwaldon committed Mar 27, 2012
1 parent f4a7035 commit e677abf
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 2 deletions.
19 changes: 18 additions & 1 deletion glance/store/s3.py
Expand Up @@ -442,6 +442,22 @@ def get_bucket(conn, bucket_id):
return bucket


def get_s3_location(s3_host):
from boto.s3.connection import Location
locations = {
's3.amazonaws.com': Location.DEFAULT,
's3-eu-west-1.amazonaws.com': Location.EU,
's3-us-west-1.amazonaws.com': Location.USWest,
's3-ap-southeast-1.amazonaws.com': Location.APSoutheast,
's3-ap-northeast-1.amazonaws.com': Location.APNortheast,
}
# strip off scheme and port if present
key = re.sub('^(https?://)?(?P<host>[^:]+)(:[0-9]+)?$',
'\g<host>',
s3_host)
return locations.get(key, Location.DEFAULT)


def create_bucket_if_missing(bucket, s3_conn, conf):
"""
Creates a missing bucket in S3 if the
Expand All @@ -457,8 +473,9 @@ def create_bucket_if_missing(bucket, s3_conn, conf):
except S3ResponseError, e:
if e.status == httplib.NOT_FOUND:
if conf.s3_store_create_bucket_on_put:
location = get_s3_location(conf.s3_store_host)
try:
s3_conn.create_bucket(bucket)
s3_conn.create_bucket(bucket, location=location)
except S3ResponseError, e:
msg = ("Failed to add bucket to S3.\n"
"Got error from S3: %(e)s" % locals())
Expand Down
37 changes: 36 additions & 1 deletion glance/tests/unit/test_s3_store.py
Expand Up @@ -31,7 +31,7 @@
from glance.common import utils
from glance.store import BackendException, UnsupportedBackend
from glance.store.location import get_location_from_uri
from glance.store.s3 import Store
from glance.store.s3 import Store, get_s3_location
from glance.tests import utils as test_utils


Expand Down Expand Up @@ -335,3 +335,38 @@ def test_delete_non_existing(self):
uri = "s3://user:key@auth_address/glance/noexist"
loc = get_location_from_uri(uri)
self.assertRaises(exception.NotFound, self.store.delete, loc)

def _do_test_get_s3_location(self, host, loc):
self.assertEquals(get_s3_location(host), loc)
self.assertEquals(get_s3_location(host + ':80'), loc)
self.assertEquals(get_s3_location('http://' + host), loc)
self.assertEquals(get_s3_location('http://' + host + ':80'), loc)
self.assertEquals(get_s3_location('https://' + host), loc)
self.assertEquals(get_s3_location('https://' + host + ':80'), loc)

def test_get_s3_good_location(self):
"""
Test that the s3 location can be derived from the host
"""
good_locations = [
('s3.amazonaws.com', ''),
('s3-eu-west-1.amazonaws.com', 'EU'),
('s3-us-west-1.amazonaws.com', 'us-west-1'),
('s3-ap-southeast-1.amazonaws.com', 'ap-southeast-1'),
('s3-ap-northeast-1.amazonaws.com', 'ap-northeast-1'),
]
for (url, expected) in good_locations:
self._do_test_get_s3_location(url, expected)

def test_get_s3_bad_location(self):
"""
Test that the s3 location cannot be derived from an unexpected host
"""
bad_locations = [
('', ''),
('s3.amazon.co.uk', ''),
('s3-govcloud.amazonaws.com', ''),
('cloudfiles.rackspace.com', ''),
]
for (url, expected) in bad_locations:
self._do_test_get_s3_location(url, expected)

0 comments on commit e677abf

Please sign in to comment.