Files
glance/glance/store/swift.py
Ewan Mellor f11c8c4c07 Bug #696385: Glance is not pep8-clean
Fix all Glance's pep8 problems.
2011-01-02 02:47:59 +00:00

135 lines
4.8 KiB
Python

# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2010 OpenStack, LLC
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import glance.store
class SwiftBackend(glance.store.Backend):
"""
An implementation of the swift backend adapter.
"""
EXAMPLE_URL = "swift://user:password@auth_url/container/file.gz.0"
CHUNKSIZE = 65536
@classmethod
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 resp_body provided by get_object.
"""
(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
connection_class = get_connection_class(conn_class)
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 glance.store.BackendException(
"Expected %s byte file, Swift has %s bytes" %
(expected_size, obj_size))
return resp_body
@classmethod
def delete(cls, parsed_uri, conn_class=None):
"""
Deletes the swift object(s) at the parsed_uri location
"""
(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
connection_class = get_connection_class(conn_class)
swift_conn = conn_class(
authurl=authurl, user=user, key=key, snet=False)
(resp_headers, resp_body) = swift_conn.delete_object(
container=container, obj=obj)
# TODO(jaypipes): What to return here? After reading the docs
# at swift.common.client, I'm not sure what to check for...
@classmethod
def _parse_swift_tokens(cls, parsed_uri):
"""
Parsing the swift uri is three phases:
1) urlparse to split the tokens
2) use RE to split on @ and /
3) reassemble authurl
"""
path = parsed_uri.path.lstrip('//')
netloc = parsed_uri.netloc
try:
try:
creds, netloc = netloc.split('@')
path = '/'.join([netloc, path])
except ValueError:
# Python 2.6.1 compat
# see lp659445 and Python issue7904
creds, path = path.split('@')
user, key = creds.split(':')
path_parts = path.split('/')
obj = path_parts.pop()
container = path_parts.pop()
except (ValueError, IndexError):
raise glance.store.BackendException(
"Expected four values to unpack in: swift:%s. "
"Should have received something like: %s."
% (parsed_uri.path, cls.EXAMPLE_URL))
authurl = "https://%s" % '/'.join(path_parts)
return user, key, authurl, container, obj
def get_connection_class(conn_class):
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.
#
# NOTE(jaypipes): This can be resolved by putting this code in
# /glance/store/swift/__init__.py
#
# see http://docs.python.org/library/functions.html#__import__
PERFORM_ABSOLUTE_IMPORTS = 0
swift = __import__('swift.common.client', globals(), locals(), [],
PERFORM_ABSOLUTE_IMPORTS)
conn_class = swift.common.client.Connection
return conn_class