Fixes lp653358

Using swift.common.client rather than python-cloudfiles for Teller's Swift backend.
This commit is contained in:
Rick Harris 2010-10-15 15:26:41 +00:00 committed by Tarmac
commit 543911e581
4 changed files with 40 additions and 28 deletions

View File

@ -30,36 +30,48 @@ class SwiftBackend(Backend):
Takes a parsed_uri in the format of: Takes a parsed_uri in the format of:
swift://user:password@auth_url/container/file.gz.0, connects to the swift://user:password@auth_url/container/file.gz.0, connects to the
swift instance at auth_url and downloads the file. Returns the generator swift instance at auth_url and downloads the file. Returns the generator
provided by stream() on the swift object representing the file. resp_body provided by get_object.
""" """
(user, api_key, authurl, container, file) = \
cls.parse_swift_tokens(parsed_uri)
if conn_class: if conn_class:
pass # Use the provided conn_class pass # Use the provided conn_class
else: else:
# NOTE(sirp): A standard import statement won't work here because
# this file ('swift.py') is shadowing the swift module, and since
# the import statement searches locally before globally, we'd end
# up importing ourselves.
#
# see http://docs.python.org/library/functions.html#__import__
PERFORM_ABSOLUTE_IMPORTS = 0
swift = __import__('swift.common.client', globals(), locals(), [],
PERFORM_ABSOLUTE_IMPORTS)
# Import cloudfiles here because stubout will replace this call # Import cloudfiles here because stubout will replace this call
# with a faked swift client in the unittests, avoiding import # with a faked swift client in the unittests, avoiding import
# errors if the test system does not have cloudfiles installed # errors if the test system does not have cloudfiles installed
import cloudfiles conn_class = swift.common.client.Connection
conn_class = cloudfiles
swift_conn = conn_class.get_connection(username=user, api_key=api_key, (user, key, authurl, container, obj) = \
authurl=authurl) cls._parse_swift_tokens(parsed_uri)
# TODO(sirp): snet=False for now, however, if the instance of
# swift we're talking to is within our same region, we should set
# snet=True
swift_conn = conn_class(
authurl=authurl, user=user, key=key, snet=False)
container = swift_conn.get_container(container) (resp_headers, resp_body) = swift_conn.get_object(
container=container, obj=obj, resp_chunk_size=cls.CHUNKSIZE)
obj = container.get_object(file)
if obj.size != expected_size:
raise BackendException("Expected %s size file, Swift has %s"
% (expected_size, obj.size))
# Return the generator provided from obj.stream()
return obj.stream(chunksize=cls.CHUNKSIZE)
obj_size = int(resp_headers['content-length'])
if obj_size != expected_size:
raise BackendException("Expected %s byte file, Swift has %s bytes"
% (expected_size, obj_size))
return resp_body
@classmethod @classmethod
def parse_swift_tokens(cls, parsed_uri): def _parse_swift_tokens(cls, parsed_uri):
""" """
Parsing the swift uri is three phases: Parsing the swift uri is three phases:
1) urlparse to split the tokens 1) urlparse to split the tokens
@ -77,9 +89,9 @@ class SwiftBackend(Backend):
# see lp659445 and Python issue7904 # see lp659445 and Python issue7904
creds, path = path.split('@') creds, path = path.split('@')
user, api_key = creds.split(':') user, key = creds.split(':')
path_parts = path.split('/') path_parts = path.split('/')
file = path_parts.pop() obj = path_parts.pop()
container = path_parts.pop() container = path_parts.pop()
except (ValueError, IndexError): except (ValueError, IndexError):
raise BackendException( raise BackendException(
@ -89,4 +101,4 @@ class SwiftBackend(Backend):
authurl = "https://%s" % '/'.join(path_parts) authurl = "https://%s" % '/'.join(path_parts)
return user, api_key, authurl, container, file return user, key, authurl, container, obj

View File

@ -108,8 +108,8 @@ def stub_out_swift_backend(stubs):
SwiftBackend = glance.teller.backends.swift.SwiftBackend SwiftBackend = glance.teller.backends.swift.SwiftBackend
# raise BackendException if URI is bad. # raise BackendException if URI is bad.
(user, api_key, authurl, container, file) = \ (user, key, authurl, container, obj) = \
SwiftBackend.parse_swift_tokens(parsed_uri) SwiftBackend._parse_swift_tokens(parsed_uri)
def chunk_it(): def chunk_it():
for i in xrange(0, len(cls.DATA), cls.CHUNK_SIZE): for i in xrange(0, len(cls.DATA), cls.CHUNK_SIZE):

View File

@ -31,7 +31,7 @@ def make_real_image():
dict(name="testsnap", dict(name="testsnap",
state="available", state="available",
public=True, public=True,
image_type="tarball")) image_type="raw"))
location = ( location = (
"swift://%s:%s@" "swift://%s:%s@"
@ -52,7 +52,7 @@ def make_fake_image():
dict(name="Test Image", dict(name="Test Image",
state="available", state="available",
public=True, public=True,
image_type="tarball")) image_type="raw"))
db.image_file_create( db.image_file_create(
None, None,

View File

@ -18,10 +18,10 @@
"""Common utilities used in testing""" """Common utilities used in testing"""
def is_cloudfiles_available(): def is_swift_available():
"""Returns True if Swift/Cloudfiles is importable""" """Returns True if Swift/Cloudfiles is importable"""
try: try:
import cloudfiles import swift
return True return True
except ImportError: except ImportError:
return False return False