Skip to content

Commit

Permalink
Fixes lp653358
Browse files Browse the repository at this point in the history
Using swift.common.client rather than python-cloudfiles for Teller's Swift backend.
  • Loading branch information
rconradharris authored and Tarmac committed Oct 15, 2010
2 parents ae51a14 + 854c906 commit 543911e
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 31 deletions.
62 changes: 37 additions & 25 deletions glance/teller/backends/swift.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,36 +30,48 @@ def get(cls, parsed_uri, expected_size, conn_class=None):
Takes a parsed_uri in the format of:
swift://user:password@auth_url/container/file.gz.0, connects to the
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:
pass # Use the provided conn_class
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
# with a faked swift client in the unittests, avoiding import
# errors if the test system does not have cloudfiles installed
import cloudfiles
conn_class = cloudfiles

swift_conn = conn_class.get_connection(username=user, api_key=api_key,
authurl=authurl)

container = swift_conn.get_container(container)

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)

conn_class = swift.common.client.Connection

(user, key, authurl, container, obj) = \
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)

(resp_headers, resp_body) = swift_conn.get_object(
container=container, obj=obj, resp_chunk_size=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
def parse_swift_tokens(cls, parsed_uri):
def _parse_swift_tokens(cls, parsed_uri):
"""
Parsing the swift uri is three phases:
1) urlparse to split the tokens
Expand All @@ -77,9 +89,9 @@ def parse_swift_tokens(cls, parsed_uri):
# see lp659445 and Python issue7904
creds, path = path.split('@')

user, api_key = creds.split(':')
user, key = creds.split(':')
path_parts = path.split('/')
file = path_parts.pop()
obj = path_parts.pop()
container = path_parts.pop()
except (ValueError, IndexError):
raise BackendException(
Expand All @@ -89,4 +101,4 @@ def parse_swift_tokens(cls, parsed_uri):

authurl = "https://%s" % '/'.join(path_parts)

return user, api_key, authurl, container, file
return user, key, authurl, container, obj
4 changes: 2 additions & 2 deletions tests/stubs.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ def get(cls, parsed_uri, expected_size, conn_class=None):
SwiftBackend = glance.teller.backends.swift.SwiftBackend

# raise BackendException if URI is bad.
(user, api_key, authurl, container, file) = \
SwiftBackend.parse_swift_tokens(parsed_uri)
(user, key, authurl, container, obj) = \
SwiftBackend._parse_swift_tokens(parsed_uri)

def chunk_it():
for i in xrange(0, len(cls.DATA), cls.CHUNK_SIZE):
Expand Down
4 changes: 2 additions & 2 deletions tests/test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def make_real_image():
dict(name="testsnap",
state="available",
public=True,
image_type="tarball"))
image_type="raw"))

location = (
"swift://%s:%s@"
Expand All @@ -52,7 +52,7 @@ def make_fake_image():
dict(name="Test Image",
state="available",
public=True,
image_type="tarball"))
image_type="raw"))

db.image_file_create(
None,
Expand Down
4 changes: 2 additions & 2 deletions tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
"""Common utilities used in testing"""


def is_cloudfiles_available():
def is_swift_available():
"""Returns True if Swift/Cloudfiles is importable"""
try:
import cloudfiles
import swift
return True
except ImportError:
return False

0 comments on commit 543911e

Please sign in to comment.