Enhance configuration handling
1. Changed drivers to prevent using global CONF but access it from client by interface. 2. Corrected swift driver to involve options from swift driver utils, allow glance_store exports and registers them for client. 3. Added missing test cases for the functions of swift driver util. Change-Id: I8fac6800efde202e29179791ea05c4814ec58435 Signed-off-by: Zhi Yan Liu <zhiyanl@cn.ibm.com>
This commit is contained in:
parent
56af7fd60c
commit
22dbccb491
@ -174,7 +174,7 @@ class Store(glance_store.driver.Store):
|
|||||||
:raises `glance_store.exceptions.Duplicate` if the image already
|
:raises `glance_store.exceptions.Duplicate` if the image already
|
||||||
existed
|
existed
|
||||||
"""
|
"""
|
||||||
loc = StoreLocation({'image_id': image_id})
|
loc = StoreLocation({'image_id': image_id}, self.conf)
|
||||||
|
|
||||||
if self.fs.exists(image_id):
|
if self.fs.exists(image_id):
|
||||||
raise exceptions.Duplicate(_("GridFS already has an image at "
|
raise exceptions.Duplicate(_("GridFS already has an image at "
|
||||||
|
@ -192,6 +192,7 @@ class Store(glance_store.driver.Store):
|
|||||||
location_class = glance_store.location.Location
|
location_class = glance_store.location.Location
|
||||||
new_loc = location_class(location.store_name,
|
new_loc = location_class(location.store_name,
|
||||||
location.store_location.__class__,
|
location.store_location.__class__,
|
||||||
|
self.conf,
|
||||||
uri=location_header,
|
uri=location_header,
|
||||||
image_id=location.image_id,
|
image_id=location.image_id,
|
||||||
store_specs=location.store_specs)
|
store_specs=location.store_specs)
|
||||||
|
@ -261,10 +261,10 @@ class Store(driver.Store):
|
|||||||
'pool': self.pool,
|
'pool': self.pool,
|
||||||
'image': image_name,
|
'image': image_name,
|
||||||
'snapshot': DEFAULT_SNAPNAME,
|
'snapshot': DEFAULT_SNAPNAME,
|
||||||
})
|
}, self.conf)
|
||||||
else:
|
else:
|
||||||
librbd.create(ioctx, image_name, size, order, old_format=True)
|
librbd.create(ioctx, image_name, size, order, old_format=True)
|
||||||
return StoreLocation({'image': image_name})
|
return StoreLocation({'image': image_name}, self.conf)
|
||||||
|
|
||||||
def _delete_image(self, image_name, snapshot_name=None, context=None):
|
def _delete_image(self, image_name, snapshot_name=None, context=None):
|
||||||
"""
|
"""
|
||||||
|
@ -352,7 +352,7 @@ class Store(glance_store.driver.Store):
|
|||||||
'key': image_id,
|
'key': image_id,
|
||||||
's3serviceurl': self.full_s3_host,
|
's3serviceurl': self.full_s3_host,
|
||||||
'accesskey': self.access_key,
|
'accesskey': self.access_key,
|
||||||
'secretkey': self.secret_key})
|
'secretkey': self.secret_key}, self.conf)
|
||||||
|
|
||||||
uformat = self.conf.glance_store.s3_store_bucket_url_format
|
uformat = self.conf.glance_store.s3_store_bucket_url_format
|
||||||
calling_format = get_calling_format(s3_store_bucket_url_format=uformat)
|
calling_format = get_calling_format(s3_store_bucket_url_format=uformat)
|
||||||
|
@ -268,7 +268,7 @@ class Store(glance_store.driver.Store):
|
|||||||
raise exceptions.Duplicate(_("Sheepdog image %s already exists")
|
raise exceptions.Duplicate(_("Sheepdog image %s already exists")
|
||||||
% image_id)
|
% image_id)
|
||||||
|
|
||||||
location = StoreLocation({'image': image_id})
|
location = StoreLocation({'image': image_id}, self.conf)
|
||||||
checksum = hashlib.md5()
|
checksum = hashlib.md5()
|
||||||
|
|
||||||
image.create(image_size)
|
image.create(image_size)
|
||||||
|
@ -102,10 +102,6 @@ _SWIFT_OPTS = [
|
|||||||
'before the request fails.'))
|
'before the request fails.'))
|
||||||
]
|
]
|
||||||
|
|
||||||
CONF = cfg.CONF
|
|
||||||
|
|
||||||
SWIFT_STORE_REF_PARAMS = sutils.SwiftParams().params
|
|
||||||
|
|
||||||
|
|
||||||
def swift_retry_iter(resp_iter, length, store, location, context):
|
def swift_retry_iter(resp_iter, length, store, location, context):
|
||||||
length = length if length else (resp_iter.len
|
length = length if length else (resp_iter.len
|
||||||
@ -139,9 +135,9 @@ def swift_retry_iter(resp_iter, length, store, location, context):
|
|||||||
'max_retries': retry_count,
|
'max_retries': retry_count,
|
||||||
'start': bytes_read,
|
'start': bytes_read,
|
||||||
'end': length})
|
'end': length})
|
||||||
(resp_headers, resp_iter) = store._get_object(location, None,
|
(_resp_headers, resp_iter) = store._get_object(location, None,
|
||||||
bytes_read,
|
bytes_read,
|
||||||
context=context)
|
context=context)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -194,7 +190,7 @@ class StoreLocation(location.StoreLocation):
|
|||||||
if not credentials_included:
|
if not credentials_included:
|
||||||
#Used only in case of an add
|
#Used only in case of an add
|
||||||
#Get the current store from config
|
#Get the current store from config
|
||||||
store = CONF.glance_store.default_swift_reference
|
store = self.conf.glance_store.default_swift_reference
|
||||||
|
|
||||||
return '%s://%s/%s/%s' % ('swift+config', store, container, obj)
|
return '%s://%s/%s/%s' % ('swift+config', store, container, obj)
|
||||||
if self.scheme == 'swift+config':
|
if self.scheme == 'swift+config':
|
||||||
@ -209,9 +205,10 @@ class StoreLocation(location.StoreLocation):
|
|||||||
|
|
||||||
def _get_conf_value_from_account_ref(self, netloc):
|
def _get_conf_value_from_account_ref(self, netloc):
|
||||||
try:
|
try:
|
||||||
self.user = SWIFT_STORE_REF_PARAMS[netloc]['user']
|
ref_params = sutils.SwiftParams(self.conf).params
|
||||||
self.key = SWIFT_STORE_REF_PARAMS[netloc]['key']
|
self.user = ref_params[netloc]['user']
|
||||||
netloc = SWIFT_STORE_REF_PARAMS[netloc]['auth_address']
|
self.key = ref_params[netloc]['key']
|
||||||
|
netloc = ref_params[netloc]['auth_address']
|
||||||
self.ssl_enabled = True
|
self.ssl_enabled = True
|
||||||
if netloc != '':
|
if netloc != '':
|
||||||
if netloc.startswith('http://'):
|
if netloc.startswith('http://'):
|
||||||
@ -308,7 +305,7 @@ class StoreLocation(location.StoreLocation):
|
|||||||
path = pieces.path.lstrip('/')
|
path = pieces.path.lstrip('/')
|
||||||
|
|
||||||
# NOTE(Sridevi): Fix to map the account reference to the
|
# NOTE(Sridevi): Fix to map the account reference to the
|
||||||
# corresponding CONF value
|
# corresponding configuration value
|
||||||
if self.scheme == 'swift+config':
|
if self.scheme == 'swift+config':
|
||||||
netloc = self._get_conf_value_from_account_ref(netloc)
|
netloc = self._get_conf_value_from_account_ref(netloc)
|
||||||
else:
|
else:
|
||||||
@ -343,7 +340,8 @@ class StoreLocation(location.StoreLocation):
|
|||||||
|
|
||||||
def Store(conf):
|
def Store(conf):
|
||||||
try:
|
try:
|
||||||
conf.register_opts(_SWIFT_OPTS, group='glance_store')
|
conf.register_opts(_SWIFT_OPTS + sutils.swift_opts,
|
||||||
|
group='glance_store')
|
||||||
except cfg.DuplicateOptError:
|
except cfg.DuplicateOptError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -351,13 +349,13 @@ def Store(conf):
|
|||||||
return MultiTenantStore(conf)
|
return MultiTenantStore(conf)
|
||||||
return SingleTenantStore(conf)
|
return SingleTenantStore(conf)
|
||||||
|
|
||||||
Store.OPTIONS = _SWIFT_OPTS
|
Store.OPTIONS = _SWIFT_OPTS + sutils.swift_opts
|
||||||
|
|
||||||
|
|
||||||
class BaseStore(driver.Store):
|
class BaseStore(driver.Store):
|
||||||
|
|
||||||
CHUNKSIZE = 65536
|
CHUNKSIZE = 65536
|
||||||
OPTIONS = _SWIFT_OPTS
|
OPTIONS = _SWIFT_OPTS + sutils.swift_opts
|
||||||
|
|
||||||
def get_schemes(self):
|
def get_schemes(self):
|
||||||
return ('swift+https', 'swift', 'swift+http', 'swift+config')
|
return ('swift+https', 'swift', 'swift+http', 'swift+config')
|
||||||
@ -567,7 +565,7 @@ class BaseStore(driver.Store):
|
|||||||
# image data. We *really* should consider NOT returning
|
# image data. We *really* should consider NOT returning
|
||||||
# the location attribute from GET /images/<ID> and
|
# the location attribute from GET /images/<ID> and
|
||||||
# GET /images/details
|
# GET /images/details
|
||||||
if sutils.is_multiple_swift_store_accounts_enabled():
|
if sutils.is_multiple_swift_store_accounts_enabled(self.conf):
|
||||||
include_creds = False
|
include_creds = False
|
||||||
else:
|
else:
|
||||||
include_creds = True
|
include_creds = True
|
||||||
@ -668,14 +666,17 @@ class BaseStore(driver.Store):
|
|||||||
class SingleTenantStore(BaseStore):
|
class SingleTenantStore(BaseStore):
|
||||||
EXAMPLE_URL = "swift://<USER>:<KEY>@<AUTH_ADDRESS>/<CONTAINER>/<FILE>"
|
EXAMPLE_URL = "swift://<USER>:<KEY>@<AUTH_ADDRESS>/<CONTAINER>/<FILE>"
|
||||||
|
|
||||||
|
def __init__(self, conf):
|
||||||
|
super(SingleTenantStore, self).__init__(conf)
|
||||||
|
self.ref_params = sutils.SwiftParams(self.conf).params
|
||||||
|
|
||||||
def configure(self):
|
def configure(self):
|
||||||
super(SingleTenantStore, self).configure()
|
super(SingleTenantStore, self).configure()
|
||||||
self.auth_version = self._option_get('swift_store_auth_version')
|
self.auth_version = self._option_get('swift_store_auth_version')
|
||||||
|
|
||||||
def configure_add(self):
|
def configure_add(self):
|
||||||
default_swift_reference = \
|
default_ref = self.conf.glance_store.default_swift_reference
|
||||||
SWIFT_STORE_REF_PARAMS.get(
|
default_swift_reference = self.ref_params.get(default_ref)
|
||||||
self.conf.glance_store.default_swift_reference)
|
|
||||||
if default_swift_reference:
|
if default_swift_reference:
|
||||||
self.auth_address = default_swift_reference.get('auth_address')
|
self.auth_address = default_swift_reference.get('auth_address')
|
||||||
if (not default_swift_reference) or (not self.auth_address):
|
if (not default_swift_reference) or (not self.auth_address):
|
||||||
@ -704,7 +705,7 @@ class SingleTenantStore(BaseStore):
|
|||||||
'auth_or_store_url': self.auth_address,
|
'auth_or_store_url': self.auth_address,
|
||||||
'user': self.user,
|
'user': self.user,
|
||||||
'key': self.key}
|
'key': self.key}
|
||||||
return StoreLocation(specs)
|
return StoreLocation(specs, self.conf)
|
||||||
|
|
||||||
def get_connection(self, location, context=None):
|
def get_connection(self, location, context=None):
|
||||||
if not location.user:
|
if not location.user:
|
||||||
@ -814,7 +815,7 @@ class MultiTenantStore(BaseStore):
|
|||||||
'container': self.container + '_' + str(image_id),
|
'container': self.container + '_' + str(image_id),
|
||||||
'obj': str(image_id),
|
'obj': str(image_id),
|
||||||
'auth_or_store_url': ep}
|
'auth_or_store_url': ep}
|
||||||
return StoreLocation(specs)
|
return StoreLocation(specs, self.conf)
|
||||||
|
|
||||||
def get_connection(self, location, context=None):
|
def get_connection(self, location, context=None):
|
||||||
return swiftclient.Connection(
|
return swiftclient.Connection(
|
||||||
|
@ -50,22 +50,16 @@ CONFIG = ConfigParser.SafeConfigParser(dict_type=OrderedDict)
|
|||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
CONF = cfg.CONF
|
def is_multiple_swift_store_accounts_enabled(conf):
|
||||||
for opt in swift_opts:
|
if conf.glance_store.swift_store_config_file is None:
|
||||||
opt.deprecated_opts = [cfg.DeprecatedOpt(opt.name,
|
|
||||||
group='DEFAULT')]
|
|
||||||
CONF.register_opt(opt, group='glance_store')
|
|
||||||
|
|
||||||
|
|
||||||
def is_multiple_swift_store_accounts_enabled():
|
|
||||||
if CONF.glance_store.swift_store_config_file is None:
|
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class SwiftParams(object):
|
class SwiftParams(object):
|
||||||
def __init__(self):
|
def __init__(self, conf):
|
||||||
if is_multiple_swift_store_accounts_enabled():
|
self.conf = conf
|
||||||
|
if is_multiple_swift_store_accounts_enabled(self.conf):
|
||||||
self.params = self._load_config()
|
self.params = self._load_config()
|
||||||
else:
|
else:
|
||||||
self.params = self._form_default_params()
|
self.params = self._form_default_params()
|
||||||
@ -74,12 +68,12 @@ class SwiftParams(object):
|
|||||||
default = {}
|
default = {}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
CONF.glance_store.swift_store_user and
|
self.conf.glance_store.swift_store_user and
|
||||||
CONF.glance_store.swift_store_key and
|
self.conf.glance_store.swift_store_key and
|
||||||
CONF.glance_store.swift_store_auth_address
|
self.conf.glance_store.swift_store_auth_address
|
||||||
):
|
):
|
||||||
|
|
||||||
glance_store = CONF.glance_store
|
glance_store = self.conf.glance_store
|
||||||
default['user'] = glance_store.swift_store_user
|
default['user'] = glance_store.swift_store_user
|
||||||
default['key'] = glance_store.swift_store_key
|
default['key'] = glance_store.swift_store_key
|
||||||
default['auth_address'] = glance_store.swift_store_auth_address
|
default['auth_address'] = glance_store.swift_store_auth_address
|
||||||
@ -88,13 +82,13 @@ class SwiftParams(object):
|
|||||||
|
|
||||||
def _load_config(self):
|
def _load_config(self):
|
||||||
try:
|
try:
|
||||||
scf = CONF.glance_store.swift_store_config_file
|
scf = self.conf.glance_store.swift_store_config_file
|
||||||
conf_file = CONF.find_file(scf)
|
conf_file = self.conf.find_file(scf)
|
||||||
CONFIG.read(conf_file)
|
CONFIG.read(conf_file)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
msg = (i18n._("swift config file "
|
msg = (i18n._("swift config file "
|
||||||
"%(conf_file)s:%(exc)s not found") %
|
"%(conf)s:%(exc)s not found") %
|
||||||
{'conf_file': CONF.glance_store.swift_store_config_file,
|
{'conf': self.conf.glance_store.swift_store_config_file,
|
||||||
'exc': e})
|
'exc': e})
|
||||||
LOG.error(msg)
|
LOG.error(msg)
|
||||||
raise exceptions.BadStoreConfiguration(store_name='swift',
|
raise exceptions.BadStoreConfiguration(store_name='swift',
|
||||||
|
@ -311,7 +311,7 @@ class Store(glance_store.Store):
|
|||||||
'image_dir': self.store_image_dir,
|
'image_dir': self.store_image_dir,
|
||||||
'datacenter_path': self.datacenter_path,
|
'datacenter_path': self.datacenter_path,
|
||||||
'datastore_name': self.datastore_name,
|
'datastore_name': self.datastore_name,
|
||||||
'image_id': image_id})
|
'image_id': image_id}, self.conf)
|
||||||
# NOTE(arnaud): use a decorator when the config is not tied to self
|
# NOTE(arnaud): use a decorator when the config is not tied to self
|
||||||
for i in range(self.api_retry_count + 1):
|
for i in range(self.api_retry_count + 1):
|
||||||
cookie = self._build_vim_cookie_header(
|
cookie = self._build_vim_cookie_header(
|
||||||
|
@ -25,6 +25,7 @@ from glance_store import i18n
|
|||||||
from glance_store import location
|
from glance_store import location
|
||||||
|
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
_ = i18n._
|
_ = i18n._
|
||||||
@ -45,7 +46,6 @@ _STORE_OPTS = [
|
|||||||
deprecated_opts=[_DEPRECATED_STORE_OPTS[1]])
|
deprecated_opts=[_DEPRECATED_STORE_OPTS[1]])
|
||||||
]
|
]
|
||||||
|
|
||||||
CONF = cfg.CONF
|
|
||||||
_STORE_CFG_GROUP = 'glance_store'
|
_STORE_CFG_GROUP = 'glance_store'
|
||||||
|
|
||||||
|
|
||||||
@ -212,7 +212,7 @@ def create_stores(conf=CONF):
|
|||||||
|
|
||||||
|
|
||||||
def verify_default_store():
|
def verify_default_store():
|
||||||
scheme = cfg.CONF.glance_store.default_store
|
scheme = CONF.glance_store.default_store
|
||||||
try:
|
try:
|
||||||
get_store_from_scheme(scheme)
|
get_store_from_scheme(scheme)
|
||||||
except exceptions.UnknownScheme:
|
except exceptions.UnknownScheme:
|
||||||
@ -250,7 +250,7 @@ def get_store_from_uri(uri):
|
|||||||
def get_from_backend(uri, offset=0, chunk_size=None, context=None):
|
def get_from_backend(uri, offset=0, chunk_size=None, context=None):
|
||||||
"""Yields chunks of data from backend specified by uri."""
|
"""Yields chunks of data from backend specified by uri."""
|
||||||
|
|
||||||
loc = location.get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=CONF)
|
||||||
store = get_store_from_uri(uri)
|
store = get_store_from_uri(uri)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -264,7 +264,7 @@ def get_from_backend(uri, offset=0, chunk_size=None, context=None):
|
|||||||
def get_size_from_backend(uri, context=None):
|
def get_size_from_backend(uri, context=None):
|
||||||
"""Retrieves image size from backend specified by uri."""
|
"""Retrieves image size from backend specified by uri."""
|
||||||
|
|
||||||
loc = location.get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=CONF)
|
||||||
store = get_store_from_uri(uri)
|
store = get_store_from_uri(uri)
|
||||||
|
|
||||||
return store.get_size(loc, context=context)
|
return store.get_size(loc, context=context)
|
||||||
@ -272,7 +272,8 @@ def get_size_from_backend(uri, context=None):
|
|||||||
|
|
||||||
def delete_from_backend(uri, context=None):
|
def delete_from_backend(uri, context=None):
|
||||||
"""Removes chunks of data from backend specified by uri."""
|
"""Removes chunks of data from backend specified by uri."""
|
||||||
loc = location.get_location_from_uri(uri)
|
|
||||||
|
loc = location.get_location_from_uri(uri, conf=CONF)
|
||||||
store = get_store_from_uri(uri)
|
store = get_store_from_uri(uri)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -289,7 +290,7 @@ def get_store_from_location(uri):
|
|||||||
|
|
||||||
:param uri: Location to check for the store
|
:param uri: Location to check for the store
|
||||||
"""
|
"""
|
||||||
loc = location.get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=CONF)
|
||||||
return loc.store_name
|
return loc.store_name
|
||||||
|
|
||||||
|
|
||||||
@ -361,7 +362,7 @@ def set_acls(location_uri, public=False, read_tenants=[],
|
|||||||
if write_tenants is None:
|
if write_tenants is None:
|
||||||
write_tenants = []
|
write_tenants = []
|
||||||
|
|
||||||
loc = location.get_location_from_uri(location_uri)
|
loc = location.get_location_from_uri(location_uri, conf=CONF)
|
||||||
scheme = get_store_from_location(location_uri)
|
scheme = get_store_from_location(location_uri)
|
||||||
store = get_store_from_scheme(scheme)
|
store = get_store_from_scheme(scheme)
|
||||||
try:
|
try:
|
||||||
|
@ -40,20 +40,24 @@ credentials and is **not** user-facing.
|
|||||||
import logging
|
import logging
|
||||||
import urlparse
|
import urlparse
|
||||||
|
|
||||||
|
from oslo.config import cfg
|
||||||
|
|
||||||
from glance_store import exceptions
|
from glance_store import exceptions
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
SCHEME_TO_CLS_MAP = {}
|
SCHEME_TO_CLS_MAP = {}
|
||||||
|
|
||||||
|
|
||||||
def get_location_from_uri(uri):
|
def get_location_from_uri(uri, conf=CONF):
|
||||||
"""
|
"""
|
||||||
Given a URI, return a Location object that has had an appropriate
|
Given a URI, return a Location object that has had an appropriate
|
||||||
store parse the URI.
|
store parse the URI.
|
||||||
|
|
||||||
:param uri: A URI that could come from the end-user in the Location
|
:param uri: A URI that could come from the end-user in the Location
|
||||||
attribute/header
|
attribute/header.
|
||||||
|
:param conf: The global configuration.
|
||||||
|
|
||||||
Example URIs:
|
Example URIs:
|
||||||
https://user:pass@example.com:80/images/some-id
|
https://user:pass@example.com:80/images/some-id
|
||||||
@ -70,8 +74,8 @@ def get_location_from_uri(uri):
|
|||||||
if pieces.scheme not in SCHEME_TO_CLS_MAP.keys():
|
if pieces.scheme not in SCHEME_TO_CLS_MAP.keys():
|
||||||
raise exceptions.UnknownScheme(scheme=pieces.scheme)
|
raise exceptions.UnknownScheme(scheme=pieces.scheme)
|
||||||
scheme_info = SCHEME_TO_CLS_MAP[pieces.scheme]
|
scheme_info = SCHEME_TO_CLS_MAP[pieces.scheme]
|
||||||
return Location(pieces.scheme, uri=uri,
|
return Location(pieces.scheme, scheme_info['location_class'],
|
||||||
store_location_class=scheme_info['location_class'])
|
conf, uri=uri)
|
||||||
|
|
||||||
|
|
||||||
def register_scheme_map(scheme_map):
|
def register_scheme_map(scheme_map):
|
||||||
@ -93,7 +97,7 @@ class Location(object):
|
|||||||
Class describing the location of an image that Glance knows about
|
Class describing the location of an image that Glance knows about
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, store_name, store_location_class,
|
def __init__(self, store_name, store_location_class, conf,
|
||||||
uri=None, image_id=None, store_specs=None):
|
uri=None, image_id=None, store_specs=None):
|
||||||
"""
|
"""
|
||||||
Create a new Location object.
|
Create a new Location object.
|
||||||
@ -111,7 +115,8 @@ class Location(object):
|
|||||||
self.store_name = store_name
|
self.store_name = store_name
|
||||||
self.image_id = image_id
|
self.image_id = image_id
|
||||||
self.store_specs = store_specs or {}
|
self.store_specs = store_specs or {}
|
||||||
self.store_location = store_location_class(self.store_specs)
|
self.conf = conf
|
||||||
|
self.store_location = store_location_class(self.store_specs, conf)
|
||||||
if uri:
|
if uri:
|
||||||
self.store_location.parse_uri(uri)
|
self.store_location.parse_uri(uri)
|
||||||
|
|
||||||
@ -132,7 +137,8 @@ class StoreLocation(object):
|
|||||||
Base class that must be implemented by each store
|
Base class that must be implemented by each store
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, store_specs):
|
def __init__(self, store_specs, conf):
|
||||||
|
self.conf = conf
|
||||||
self.specs = store_specs
|
self.specs = store_specs
|
||||||
if self.specs:
|
if self.specs:
|
||||||
self.process_specs()
|
self.process_specs()
|
||||||
|
@ -18,7 +18,7 @@ import mock
|
|||||||
|
|
||||||
from glance_store._drivers import cinder
|
from glance_store._drivers import cinder
|
||||||
from glance_store import exceptions
|
from glance_store import exceptions
|
||||||
from glance_store.location import get_location_from_uri
|
from glance_store import location
|
||||||
from glance_store.tests import base
|
from glance_store.tests import base
|
||||||
|
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ class TestCinderStore(base.StoreBaseTest):
|
|||||||
tenant='fake_tenant')
|
tenant='fake_tenant')
|
||||||
|
|
||||||
uri = 'cinder://%s' % fake_volumes.keys()[0]
|
uri = 'cinder://%s' % fake_volumes.keys()[0]
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
image_size = self.store.get_size(loc, context=fake_context)
|
image_size = self.store.get_size(loc, context=fake_context)
|
||||||
self.assertEqual(image_size,
|
self.assertEqual(image_size,
|
||||||
fake_volumes.values()[0].size * (1024 ** 3))
|
fake_volumes.values()[0].size * (1024 ** 3))
|
||||||
|
@ -31,7 +31,7 @@ import six
|
|||||||
from glance_store._drivers.filesystem import ChunkedFile
|
from glance_store._drivers.filesystem import ChunkedFile
|
||||||
from glance_store._drivers.filesystem import Store
|
from glance_store._drivers.filesystem import Store
|
||||||
from glance_store import exceptions
|
from glance_store import exceptions
|
||||||
from glance_store.location import get_location_from_uri
|
from glance_store import location
|
||||||
from glance_store.openstack.common import units
|
from glance_store.openstack.common import units
|
||||||
from glance_store.tests import base
|
from glance_store.tests import base
|
||||||
|
|
||||||
@ -63,13 +63,13 @@ class TestStore(base.StoreBaseTest):
|
|||||||
file_contents = "chunk00000remainder"
|
file_contents = "chunk00000remainder"
|
||||||
image_file = StringIO.StringIO(file_contents)
|
image_file = StringIO.StringIO(file_contents)
|
||||||
|
|
||||||
location, size, checksum, _ = self.store.add(image_id,
|
loc, size, checksum, _ = self.store.add(image_id,
|
||||||
image_file,
|
image_file,
|
||||||
len(file_contents))
|
len(file_contents))
|
||||||
|
|
||||||
# Now read it back...
|
# Now read it back...
|
||||||
uri = "file:///%s/%s" % (self.test_dir, image_id)
|
uri = "file:///%s/%s" % (self.test_dir, image_id)
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
(image_file, image_size) = self.store.get(loc)
|
(image_file, image_size) = self.store.get(loc)
|
||||||
|
|
||||||
expected_data = "chunk00000remainder"
|
expected_data = "chunk00000remainder"
|
||||||
@ -90,13 +90,13 @@ class TestStore(base.StoreBaseTest):
|
|||||||
file_contents = "chunk00000remainder"
|
file_contents = "chunk00000remainder"
|
||||||
image_file = StringIO.StringIO(file_contents)
|
image_file = StringIO.StringIO(file_contents)
|
||||||
|
|
||||||
location, size, checksum, _ = self.store.add(image_id,
|
loc, size, checksum, _ = self.store.add(image_id,
|
||||||
image_file,
|
image_file,
|
||||||
len(file_contents))
|
len(file_contents))
|
||||||
|
|
||||||
# Now read it back...
|
# Now read it back...
|
||||||
uri = "file:///%s/%s" % (self.test_dir, image_id)
|
uri = "file:///%s/%s" % (self.test_dir, image_id)
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
|
|
||||||
data = ""
|
data = ""
|
||||||
for offset in range(len(file_contents)):
|
for offset in range(len(file_contents)):
|
||||||
@ -124,7 +124,8 @@ class TestStore(base.StoreBaseTest):
|
|||||||
Test that trying to retrieve a file that doesn't exist
|
Test that trying to retrieve a file that doesn't exist
|
||||||
raises an error
|
raises an error
|
||||||
"""
|
"""
|
||||||
loc = get_location_from_uri("file:///%s/non-existing" % self.test_dir)
|
loc = location.get_location_from_uri(
|
||||||
|
"file:///%s/non-existing" % self.test_dir, conf=self.conf)
|
||||||
self.assertRaises(exceptions.NotFound,
|
self.assertRaises(exceptions.NotFound,
|
||||||
self.store.get,
|
self.store.get,
|
||||||
loc)
|
loc)
|
||||||
@ -140,16 +141,16 @@ class TestStore(base.StoreBaseTest):
|
|||||||
expected_image_id)
|
expected_image_id)
|
||||||
image_file = StringIO.StringIO(expected_file_contents)
|
image_file = StringIO.StringIO(expected_file_contents)
|
||||||
|
|
||||||
location, size, checksum, _ = self.store.add(expected_image_id,
|
loc, size, checksum, _ = self.store.add(expected_image_id,
|
||||||
image_file,
|
image_file,
|
||||||
expected_file_size)
|
expected_file_size)
|
||||||
|
|
||||||
self.assertEqual(expected_location, location)
|
self.assertEqual(expected_location, loc)
|
||||||
self.assertEqual(expected_file_size, size)
|
self.assertEqual(expected_file_size, size)
|
||||||
self.assertEqual(expected_checksum, checksum)
|
self.assertEqual(expected_checksum, checksum)
|
||||||
|
|
||||||
uri = "file:///%s/%s" % (self.test_dir, expected_image_id)
|
uri = "file:///%s/%s" % (self.test_dir, expected_image_id)
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
(new_image_file, new_image_size) = self.store.get(loc)
|
(new_image_file, new_image_size) = self.store.get(loc)
|
||||||
new_image_contents = ""
|
new_image_contents = ""
|
||||||
new_image_file_size = 0
|
new_image_file_size = 0
|
||||||
@ -317,13 +318,13 @@ class TestStore(base.StoreBaseTest):
|
|||||||
file_contents = "*" * file_size
|
file_contents = "*" * file_size
|
||||||
image_file = StringIO.StringIO(file_contents)
|
image_file = StringIO.StringIO(file_contents)
|
||||||
|
|
||||||
location, size, checksum, _ = self.store.add(image_id,
|
loc, size, checksum, _ = self.store.add(image_id,
|
||||||
image_file,
|
image_file,
|
||||||
file_size)
|
file_size)
|
||||||
|
|
||||||
# Now check that we can delete it
|
# Now check that we can delete it
|
||||||
uri = "file:///%s/%s" % (self.test_dir, image_id)
|
uri = "file:///%s/%s" % (self.test_dir, image_id)
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
self.store.delete(loc)
|
self.store.delete(loc)
|
||||||
|
|
||||||
self.assertRaises(exceptions.NotFound, self.store.get, loc)
|
self.assertRaises(exceptions.NotFound, self.store.get, loc)
|
||||||
@ -333,7 +334,8 @@ class TestStore(base.StoreBaseTest):
|
|||||||
Test that trying to delete a file that doesn't exist
|
Test that trying to delete a file that doesn't exist
|
||||||
raises an error
|
raises an error
|
||||||
"""
|
"""
|
||||||
loc = get_location_from_uri("file:///tmp/glance-tests/non-existing")
|
loc = location.get_location_from_uri(
|
||||||
|
"file:///tmp/glance-tests/non-existing", conf=self.conf)
|
||||||
self.assertRaises(exceptions.NotFound,
|
self.assertRaises(exceptions.NotFound,
|
||||||
self.store.delete,
|
self.store.delete,
|
||||||
loc)
|
loc)
|
||||||
@ -398,15 +400,16 @@ class TestStore(base.StoreBaseTest):
|
|||||||
expected_image_id)
|
expected_image_id)
|
||||||
image_file = six.StringIO(expected_file_contents)
|
image_file = six.StringIO(expected_file_contents)
|
||||||
|
|
||||||
location, size, checksum, _ = self.store.add(expected_image_id,
|
loc, size, checksum, _ = self.store.add(expected_image_id,
|
||||||
image_file,
|
image_file,
|
||||||
expected_file_size)
|
expected_file_size)
|
||||||
|
|
||||||
self.assertEqual(expected_location, location)
|
self.assertEqual(expected_location, loc)
|
||||||
self.assertEqual(expected_file_size, size)
|
self.assertEqual(expected_file_size, size)
|
||||||
self.assertEqual(expected_checksum, checksum)
|
self.assertEqual(expected_checksum, checksum)
|
||||||
|
|
||||||
loc = get_location_from_uri(expected_location)
|
loc = location.get_location_from_uri(expected_location,
|
||||||
|
conf=self.conf)
|
||||||
(new_image_file, new_image_size) = self.store.get(loc)
|
(new_image_file, new_image_size) = self.store.get(loc)
|
||||||
new_image_contents = ""
|
new_image_contents = ""
|
||||||
new_image_file_size = 0
|
new_image_file_size = 0
|
||||||
|
@ -18,7 +18,7 @@ import mock
|
|||||||
from glance_store._drivers import http
|
from glance_store._drivers import http
|
||||||
from glance_store import delete_from_backend
|
from glance_store import delete_from_backend
|
||||||
from glance_store import exceptions
|
from glance_store import exceptions
|
||||||
from glance_store.location import get_location_from_uri
|
from glance_store import location
|
||||||
from glance_store.tests import base
|
from glance_store.tests import base
|
||||||
from glance_store.tests import utils
|
from glance_store.tests import utils
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ class TestHttpStore(base.StoreBaseTest):
|
|||||||
uri = "http://netloc/path/to/file.tar.gz"
|
uri = "http://netloc/path/to/file.tar.gz"
|
||||||
expected_returns = ['I ', 'am', ' a', ' t', 'ea', 'po', 't,', ' s',
|
expected_returns = ['I ', 'am', ' a', ' t', 'ea', 'po', 't,', ' s',
|
||||||
'ho', 'rt', ' a', 'nd', ' s', 'to', 'ut', '\n']
|
'ho', 'rt', ' a', 'nd', ' s', 'to', 'ut', '\n']
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
(image_file, image_size) = self.store.get(loc)
|
(image_file, image_size) = self.store.get(loc)
|
||||||
self.assertEqual(image_size, 31)
|
self.assertEqual(image_size, 31)
|
||||||
chunks = [c for c in image_file]
|
chunks = [c for c in image_file]
|
||||||
@ -69,7 +69,7 @@ class TestHttpStore(base.StoreBaseTest):
|
|||||||
expected_returns = ['I ', 'am', ' a', ' t', 'ea', 'po', 't,', ' s',
|
expected_returns = ['I ', 'am', ' a', ' t', 'ea', 'po', 't,', ' s',
|
||||||
'ho', 'rt', ' a', 'nd', ' s', 'to', 'ut', '\n']
|
'ho', 'rt', ' a', 'nd', ' s', 'to', 'ut', '\n']
|
||||||
|
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
(image_file, image_size) = self.store.get(loc)
|
(image_file, image_size) = self.store.get(loc)
|
||||||
self.assertEqual(image_size, 31)
|
self.assertEqual(image_size, 31)
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ class TestHttpStore(base.StoreBaseTest):
|
|||||||
self.response.side_effect = getresponse
|
self.response.side_effect = getresponse
|
||||||
|
|
||||||
uri = "http://netloc/path/to/file.tar.gz"
|
uri = "http://netloc/path/to/file.tar.gz"
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
self.assertRaises(exceptions.MaxRedirectsExceeded, self.store.get, loc)
|
self.assertRaises(exceptions.MaxRedirectsExceeded, self.store.get, loc)
|
||||||
|
|
||||||
def test_http_get_redirect_invalid(self):
|
def test_http_get_redirect_invalid(self):
|
||||||
@ -95,7 +95,7 @@ class TestHttpStore(base.StoreBaseTest):
|
|||||||
self.response.return_value = redirect_resp
|
self.response.return_value = redirect_resp
|
||||||
|
|
||||||
uri = "http://netloc/path/to/file.tar.gz"
|
uri = "http://netloc/path/to/file.tar.gz"
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
self.assertRaises(exceptions.BadStoreUri, self.store.get, loc)
|
self.assertRaises(exceptions.BadStoreUri, self.store.get, loc)
|
||||||
|
|
||||||
def test_http_get_not_found(self):
|
def test_http_get_not_found(self):
|
||||||
@ -103,12 +103,12 @@ class TestHttpStore(base.StoreBaseTest):
|
|||||||
self.response.return_value = fake
|
self.response.return_value = fake
|
||||||
|
|
||||||
uri = "http://netloc/path/to/file.tar.gz"
|
uri = "http://netloc/path/to/file.tar.gz"
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
self.assertRaises(exceptions.NotFound, self.store.get, loc)
|
self.assertRaises(exceptions.NotFound, self.store.get, loc)
|
||||||
|
|
||||||
def test_http_delete_raise_error(self):
|
def test_http_delete_raise_error(self):
|
||||||
uri = "https://netloc/path/to/file.tar.gz"
|
uri = "https://netloc/path/to/file.tar.gz"
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
self.assertRaises(NotImplementedError, self.store.delete, loc)
|
self.assertRaises(NotImplementedError, self.store.delete, loc)
|
||||||
self.assertRaises(exceptions.StoreDeleteNotSupported,
|
self.assertRaises(exceptions.StoreDeleteNotSupported,
|
||||||
delete_from_backend, uri, {})
|
delete_from_backend, uri, {})
|
||||||
|
@ -63,6 +63,7 @@ class OptsTestCase(base.StoreBaseTest):
|
|||||||
'cinder_catalog_info',
|
'cinder_catalog_info',
|
||||||
'cinder_endpoint_template',
|
'cinder_endpoint_template',
|
||||||
'cinder_http_retries',
|
'cinder_http_retries',
|
||||||
|
'default_swift_reference',
|
||||||
'filesystem_store_datadir',
|
'filesystem_store_datadir',
|
||||||
'filesystem_store_datadirs',
|
'filesystem_store_datadirs',
|
||||||
'filesystem_store_file_perm',
|
'filesystem_store_file_perm',
|
||||||
@ -86,11 +87,14 @@ class OptsTestCase(base.StoreBaseTest):
|
|||||||
'sheepdog_store_port',
|
'sheepdog_store_port',
|
||||||
'swift_enable_snet',
|
'swift_enable_snet',
|
||||||
'swift_store_admin_tenants',
|
'swift_store_admin_tenants',
|
||||||
|
'swift_store_auth_address',
|
||||||
'swift_store_auth_insecure',
|
'swift_store_auth_insecure',
|
||||||
'swift_store_auth_version',
|
'swift_store_auth_version',
|
||||||
|
'swift_store_config_file',
|
||||||
'swift_store_container',
|
'swift_store_container',
|
||||||
'swift_store_create_container_on_put',
|
'swift_store_create_container_on_put',
|
||||||
'swift_store_endpoint_type',
|
'swift_store_endpoint_type',
|
||||||
|
'swift_store_key',
|
||||||
'swift_store_large_object_chunk_size',
|
'swift_store_large_object_chunk_size',
|
||||||
'swift_store_large_object_size',
|
'swift_store_large_object_size',
|
||||||
'swift_store_multi_tenant',
|
'swift_store_multi_tenant',
|
||||||
@ -98,6 +102,7 @@ class OptsTestCase(base.StoreBaseTest):
|
|||||||
'swift_store_retry_get_count',
|
'swift_store_retry_get_count',
|
||||||
'swift_store_service_type',
|
'swift_store_service_type',
|
||||||
'swift_store_ssl_compression',
|
'swift_store_ssl_compression',
|
||||||
|
'swift_store_user',
|
||||||
'vmware_api_insecure',
|
'vmware_api_insecure',
|
||||||
'vmware_api_retry_count',
|
'vmware_api_retry_count',
|
||||||
'vmware_datacenter_path',
|
'vmware_datacenter_path',
|
||||||
|
@ -156,7 +156,8 @@ class TestStore(base.StoreBaseTest):
|
|||||||
self.called_commands_expected = []
|
self.called_commands_expected = []
|
||||||
self.store_specs = {'image': 'fake_image',
|
self.store_specs = {'image': 'fake_image',
|
||||||
'snapshot': 'fake_snapshot'}
|
'snapshot': 'fake_snapshot'}
|
||||||
self.location = rbd_store.StoreLocation(self.store_specs)
|
self.location = rbd_store.StoreLocation(self.store_specs,
|
||||||
|
self.conf)
|
||||||
# Provide enough data to get more than one chunk iteration.
|
# Provide enough data to get more than one chunk iteration.
|
||||||
self.data_len = 3 * 1024
|
self.data_len = 3 * 1024
|
||||||
self.data_iter = StringIO.StringIO('*' * self.data_len)
|
self.data_iter = StringIO.StringIO('*' * self.data_len)
|
||||||
@ -217,7 +218,8 @@ class TestStore(base.StoreBaseTest):
|
|||||||
|
|
||||||
self.store.delete(Location('test_rbd_store',
|
self.store.delete(Location('test_rbd_store',
|
||||||
rbd_store.StoreLocation,
|
rbd_store.StoreLocation,
|
||||||
self.location.get_uri()))
|
self.conf,
|
||||||
|
uri=self.location.get_uri()))
|
||||||
self.called_commands_expected = ['remove']
|
self.called_commands_expected = ['remove']
|
||||||
|
|
||||||
def test_delete_image(self):
|
def test_delete_image(self):
|
||||||
|
@ -22,12 +22,10 @@ import uuid
|
|||||||
import boto.s3.connection
|
import boto.s3.connection
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
from glance_store import exceptions
|
|
||||||
from glance_store.openstack.common import units
|
|
||||||
|
|
||||||
from glance_store._drivers import s3
|
from glance_store._drivers import s3
|
||||||
from glance_store.exceptions import UnsupportedBackend
|
from glance_store import exceptions
|
||||||
from glance_store.location import get_location_from_uri
|
from glance_store import location
|
||||||
|
from glance_store.openstack.common import units
|
||||||
from glance_store.tests import base
|
from glance_store.tests import base
|
||||||
|
|
||||||
|
|
||||||
@ -118,7 +116,7 @@ def fakers():
|
|||||||
def fake_connection_constructor(self, *args, **kwargs):
|
def fake_connection_constructor(self, *args, **kwargs):
|
||||||
host = kwargs.get('host')
|
host = kwargs.get('host')
|
||||||
if host.startswith('http://') or host.startswith('https://'):
|
if host.startswith('http://') or host.startswith('https://'):
|
||||||
raise UnsupportedBackend(host)
|
raise exceptions.UnsupportedBackend(host)
|
||||||
|
|
||||||
def fake_get_bucket(bucket_id):
|
def fake_get_bucket(bucket_id):
|
||||||
bucket = fixture_buckets.get(bucket_id)
|
bucket = fixture_buckets.get(bucket_id)
|
||||||
@ -169,8 +167,9 @@ class TestStore(base.StoreBaseTest):
|
|||||||
|
|
||||||
def test_get(self):
|
def test_get(self):
|
||||||
"""Test a "normal" retrieval of an image in chunks."""
|
"""Test a "normal" retrieval of an image in chunks."""
|
||||||
loc = get_location_from_uri(
|
loc = location.get_location_from_uri(
|
||||||
"s3://user:key@auth_address/glance/%s" % FAKE_UUID)
|
"s3://user:key@auth_address/glance/%s" % FAKE_UUID,
|
||||||
|
conf=self.conf)
|
||||||
(image_s3, image_size) = self.store.get(loc)
|
(image_s3, image_size) = self.store.get(loc)
|
||||||
|
|
||||||
self.assertEqual(image_size, FIVE_KB)
|
self.assertEqual(image_size, FIVE_KB)
|
||||||
@ -194,8 +193,9 @@ class TestStore(base.StoreBaseTest):
|
|||||||
with mock.patch.object(s3_connection, '__init__') as m:
|
with mock.patch.object(s3_connection, '__init__') as m:
|
||||||
m.side_effect = fake_S3Connection_init
|
m.side_effect = fake_S3Connection_init
|
||||||
|
|
||||||
loc = get_location_from_uri(
|
loc = location.get_location_from_uri(
|
||||||
"s3://user:key@auth_address/glance/%s" % FAKE_UUID)
|
"s3://user:key@auth_address/glance/%s" % FAKE_UUID,
|
||||||
|
conf=self.conf)
|
||||||
(image_s3, image_size) = self.store.get(loc)
|
(image_s3, image_size) = self.store.get(loc)
|
||||||
|
|
||||||
def test_get_calling_format_default(self):
|
def test_get_calling_format_default(self):
|
||||||
@ -209,8 +209,9 @@ class TestStore(base.StoreBaseTest):
|
|||||||
with mock.patch.object(s3_connection, '__init__') as m:
|
with mock.patch.object(s3_connection, '__init__') as m:
|
||||||
m.side_effect = fake_S3Connection_init
|
m.side_effect = fake_S3Connection_init
|
||||||
|
|
||||||
loc = get_location_from_uri(
|
loc = location.get_location_from_uri(
|
||||||
"s3://user:key@auth_address/glance/%s" % FAKE_UUID)
|
"s3://user:key@auth_address/glance/%s" % FAKE_UUID,
|
||||||
|
conf=self.conf)
|
||||||
(image_s3, image_size) = self.store.get(loc)
|
(image_s3, image_size) = self.store.get(loc)
|
||||||
|
|
||||||
def test_get_non_existing(self):
|
def test_get_non_existing(self):
|
||||||
@ -219,11 +220,11 @@ class TestStore(base.StoreBaseTest):
|
|||||||
raises an error
|
raises an error
|
||||||
"""
|
"""
|
||||||
uri = "s3://user:key@auth_address/badbucket/%s" % FAKE_UUID
|
uri = "s3://user:key@auth_address/badbucket/%s" % FAKE_UUID
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
self.assertRaises(exceptions.NotFound, self.store.get, loc)
|
self.assertRaises(exceptions.NotFound, self.store.get, loc)
|
||||||
|
|
||||||
uri = "s3://user:key@auth_address/glance/noexist"
|
uri = "s3://user:key@auth_address/glance/noexist"
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
self.assertRaises(exceptions.NotFound, self.store.get, loc)
|
self.assertRaises(exceptions.NotFound, self.store.get, loc)
|
||||||
|
|
||||||
def test_add(self):
|
def test_add(self):
|
||||||
@ -240,15 +241,16 @@ class TestStore(base.StoreBaseTest):
|
|||||||
expected_image_id)
|
expected_image_id)
|
||||||
image_s3 = StringIO.StringIO(expected_s3_contents)
|
image_s3 = StringIO.StringIO(expected_s3_contents)
|
||||||
|
|
||||||
location, size, checksum, _ = self.store.add(expected_image_id,
|
loc, size, checksum, _ = self.store.add(expected_image_id,
|
||||||
image_s3,
|
image_s3,
|
||||||
expected_s3_size)
|
expected_s3_size)
|
||||||
|
|
||||||
self.assertEqual(expected_location, location)
|
self.assertEqual(expected_location, loc)
|
||||||
self.assertEqual(expected_s3_size, size)
|
self.assertEqual(expected_s3_size, size)
|
||||||
self.assertEqual(expected_checksum, checksum)
|
self.assertEqual(expected_checksum, checksum)
|
||||||
|
|
||||||
loc = get_location_from_uri(expected_location)
|
loc = location.get_location_from_uri(expected_location,
|
||||||
|
conf=self.conf)
|
||||||
(new_image_s3, new_image_size) = self.store.get(loc)
|
(new_image_s3, new_image_size) = self.store.get(loc)
|
||||||
new_image_contents = StringIO.StringIO()
|
new_image_contents = StringIO.StringIO()
|
||||||
for chunk in new_image_s3:
|
for chunk in new_image_s3:
|
||||||
@ -291,15 +293,16 @@ class TestStore(base.StoreBaseTest):
|
|||||||
self.config(**new_conf)
|
self.config(**new_conf)
|
||||||
self.store = s3.Store(self.conf)
|
self.store = s3.Store(self.conf)
|
||||||
self.store.configure()
|
self.store.configure()
|
||||||
location, size, checksum, _ = self.store.add(expected_image_id,
|
loc, size, checksum, _ = self.store.add(expected_image_id,
|
||||||
image_s3,
|
image_s3,
|
||||||
expected_s3_size)
|
expected_s3_size)
|
||||||
|
|
||||||
self.assertEqual(expected_location, location)
|
self.assertEqual(expected_location, loc)
|
||||||
self.assertEqual(expected_s3_size, size)
|
self.assertEqual(expected_s3_size, size)
|
||||||
self.assertEqual(expected_checksum, checksum)
|
self.assertEqual(expected_checksum, checksum)
|
||||||
|
|
||||||
loc = get_location_from_uri(expected_location)
|
loc = location.get_location_from_uri(expected_location,
|
||||||
|
conf=self.conf)
|
||||||
(new_image_s3, new_image_size) = self.store.get(loc)
|
(new_image_s3, new_image_size) = self.store.get(loc)
|
||||||
new_image_contents = new_image_s3.getvalue()
|
new_image_contents = new_image_s3.getvalue()
|
||||||
new_image_s3_size = len(new_image_s3)
|
new_image_s3_size = len(new_image_s3)
|
||||||
@ -353,7 +356,7 @@ class TestStore(base.StoreBaseTest):
|
|||||||
Test we can delete an existing image in the s3 store
|
Test we can delete an existing image in the s3 store
|
||||||
"""
|
"""
|
||||||
uri = "s3://user:key@auth_address/glance/%s" % FAKE_UUID
|
uri = "s3://user:key@auth_address/glance/%s" % FAKE_UUID
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
self.store.delete(loc)
|
self.store.delete(loc)
|
||||||
|
|
||||||
self.assertRaises(exceptions.NotFound, self.store.get, loc)
|
self.assertRaises(exceptions.NotFound, self.store.get, loc)
|
||||||
@ -364,7 +367,7 @@ class TestStore(base.StoreBaseTest):
|
|||||||
raises an error
|
raises an error
|
||||||
"""
|
"""
|
||||||
uri = "s3://user:key@auth_address/glance/noexist"
|
uri = "s3://user:key@auth_address/glance/noexist"
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
self.assertRaises(exceptions.NotFound, self.store.delete, loc)
|
self.assertRaises(exceptions.NotFound, self.store.delete, loc)
|
||||||
|
|
||||||
def _do_test_get_s3_location(self, host, loc):
|
def _do_test_get_s3_location(self, host, loc):
|
||||||
|
@ -29,13 +29,12 @@ import six
|
|||||||
import swiftclient
|
import swiftclient
|
||||||
|
|
||||||
from glance_store._drivers.swift import store as swift
|
from glance_store._drivers.swift import store as swift
|
||||||
from glance_store._drivers.swift import utils as sutils
|
|
||||||
from glance_store import backend
|
from glance_store import backend
|
||||||
from glance_store import BackendException
|
from glance_store import BackendException
|
||||||
from glance_store.common import auth
|
from glance_store.common import auth
|
||||||
from glance_store.common import utils
|
from glance_store.common import utils
|
||||||
from glance_store import exceptions
|
from glance_store import exceptions
|
||||||
from glance_store.location import get_location_from_uri
|
from glance_store import location
|
||||||
from glance_store.openstack.common import context
|
from glance_store.openstack.common import context
|
||||||
from glance_store.openstack.common import units
|
from glance_store.openstack.common import units
|
||||||
from glance_store.tests import base
|
from glance_store.tests import base
|
||||||
@ -234,7 +233,7 @@ class SwiftTests(object):
|
|||||||
"""
|
"""
|
||||||
uri = "swift://%s:key@auth_address/glance/%s" % (
|
uri = "swift://%s:key@auth_address/glance/%s" % (
|
||||||
self.swift_store_user, FAKE_UUID)
|
self.swift_store_user, FAKE_UUID)
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
image_size = self.store.get_size(loc)
|
image_size = self.store.get_size(loc)
|
||||||
self.assertEqual(image_size, 5120)
|
self.assertEqual(image_size, 5120)
|
||||||
|
|
||||||
@ -272,7 +271,7 @@ class SwiftTests(object):
|
|||||||
"""Test a "normal" retrieval of an image in chunks."""
|
"""Test a "normal" retrieval of an image in chunks."""
|
||||||
uri = "swift://%s:key@auth_address/glance/%s" % (
|
uri = "swift://%s:key@auth_address/glance/%s" % (
|
||||||
self.swift_store_user, FAKE_UUID)
|
self.swift_store_user, FAKE_UUID)
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
(image_swift, image_size) = self.store.get(loc)
|
(image_swift, image_size) = self.store.get(loc)
|
||||||
self.assertEqual(image_size, 5120)
|
self.assertEqual(image_size, 5120)
|
||||||
|
|
||||||
@ -290,7 +289,7 @@ class SwiftTests(object):
|
|||||||
"""
|
"""
|
||||||
uri = "swift://%s:key@auth_address/glance/%s" % (
|
uri = "swift://%s:key@auth_address/glance/%s" % (
|
||||||
self.swift_store_user, FAKE_UUID)
|
self.swift_store_user, FAKE_UUID)
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
ctxt = context.RequestContext()
|
ctxt = context.RequestContext()
|
||||||
(image_swift, image_size) = self.store.get(loc, context=ctxt)
|
(image_swift, image_size) = self.store.get(loc, context=ctxt)
|
||||||
resp_full = ''.join([chunk for chunk in image_swift.wrapped])
|
resp_full = ''.join([chunk for chunk in image_swift.wrapped])
|
||||||
@ -314,9 +313,9 @@ class SwiftTests(object):
|
|||||||
specified either via a Location header with swift+http:// or using
|
specified either via a Location header with swift+http:// or using
|
||||||
http:// in the swift_store_auth_address config value
|
http:// in the swift_store_auth_address config value
|
||||||
"""
|
"""
|
||||||
loc = get_location_from_uri("swift+http://%s:key@auth_address/"
|
loc = location.get_location_from_uri(
|
||||||
"glance/%s" %
|
"swift+http://%s:key@auth_address/glance/%s" %
|
||||||
(self.swift_store_user, FAKE_UUID))
|
(self.swift_store_user, FAKE_UUID), conf=self.conf)
|
||||||
|
|
||||||
ctxt = context.RequestContext()
|
ctxt = context.RequestContext()
|
||||||
(image_swift, image_size) = self.store.get(loc, context=ctxt)
|
(image_swift, image_size) = self.store.get(loc, context=ctxt)
|
||||||
@ -334,8 +333,9 @@ class SwiftTests(object):
|
|||||||
Test that trying to retrieve a swift that doesn't exist
|
Test that trying to retrieve a swift that doesn't exist
|
||||||
raises an error
|
raises an error
|
||||||
"""
|
"""
|
||||||
loc = get_location_from_uri("swift://%s:key@authurl/glance/noexist" % (
|
loc = location.get_location_from_uri(
|
||||||
self.swift_store_user))
|
"swift://%s:key@authurl/glance/noexist" % (self.swift_store_user),
|
||||||
|
conf=self.conf)
|
||||||
self.assertRaises(exceptions.NotFound,
|
self.assertRaises(exceptions.NotFound,
|
||||||
self.store.get,
|
self.store.get,
|
||||||
loc)
|
loc)
|
||||||
@ -359,17 +359,17 @@ class SwiftTests(object):
|
|||||||
global SWIFT_PUT_OBJECT_CALLS
|
global SWIFT_PUT_OBJECT_CALLS
|
||||||
SWIFT_PUT_OBJECT_CALLS = 0
|
SWIFT_PUT_OBJECT_CALLS = 0
|
||||||
|
|
||||||
location, size, checksum, _ = self.store.add(expected_image_id,
|
loc, size, checksum, _ = self.store.add(expected_image_id,
|
||||||
image_swift,
|
image_swift,
|
||||||
expected_swift_size)
|
expected_swift_size)
|
||||||
|
|
||||||
self.assertEqual(expected_location, location)
|
self.assertEqual(expected_location, loc)
|
||||||
self.assertEqual(expected_swift_size, size)
|
self.assertEqual(expected_swift_size, size)
|
||||||
self.assertEqual(expected_checksum, checksum)
|
self.assertEqual(expected_checksum, checksum)
|
||||||
# Expecting a single object to be created on Swift i.e. no chunking.
|
# Expecting a single object to be created on Swift i.e. no chunking.
|
||||||
self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 1)
|
self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 1)
|
||||||
|
|
||||||
loc = get_location_from_uri(expected_location)
|
loc = location.get_location_from_uri(expected_location, conf=self.conf)
|
||||||
(new_image_swift, new_image_size) = self.store.get(loc)
|
(new_image_swift, new_image_size) = self.store.get(loc)
|
||||||
new_image_contents = ''.join([chunk for chunk in new_image_swift])
|
new_image_contents = ''.join([chunk for chunk in new_image_swift])
|
||||||
new_image_swift_size = len(new_image_swift)
|
new_image_swift_size = len(new_image_swift)
|
||||||
@ -435,15 +435,16 @@ class SwiftTests(object):
|
|||||||
reload(swift)
|
reload(swift)
|
||||||
self.store = Store(self.conf)
|
self.store = Store(self.conf)
|
||||||
self.store.configure()
|
self.store.configure()
|
||||||
location, size, checksum, _ = self.store.add(image_id, image_swift,
|
loc, size, checksum, _ = self.store.add(image_id, image_swift,
|
||||||
expected_swift_size)
|
expected_swift_size)
|
||||||
|
|
||||||
self.assertEqual(expected_location, location)
|
self.assertEqual(expected_location, loc)
|
||||||
self.assertEqual(expected_swift_size, size)
|
self.assertEqual(expected_swift_size, size)
|
||||||
self.assertEqual(expected_checksum, checksum)
|
self.assertEqual(expected_checksum, checksum)
|
||||||
self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 1)
|
self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 1)
|
||||||
|
|
||||||
loc = get_location_from_uri(expected_location)
|
loc = location.get_location_from_uri(expected_location,
|
||||||
|
conf=self.conf)
|
||||||
(new_image_swift, new_image_size) = self.store.get(loc)
|
(new_image_swift, new_image_size) = self.store.get(loc)
|
||||||
new_image_contents = ''.join([chunk for chunk in new_image_swift])
|
new_image_contents = ''.join([chunk for chunk in new_image_swift])
|
||||||
new_image_swift_size = len(new_image_swift)
|
new_image_swift_size = len(new_image_swift)
|
||||||
@ -510,16 +511,16 @@ class SwiftTests(object):
|
|||||||
reload(swift)
|
reload(swift)
|
||||||
self.store = Store(self.conf)
|
self.store = Store(self.conf)
|
||||||
self.store.configure()
|
self.store.configure()
|
||||||
location, size, checksum, _ = self.store.add(expected_image_id,
|
loc, size, checksum, _ = self.store.add(expected_image_id,
|
||||||
image_swift,
|
image_swift,
|
||||||
expected_swift_size)
|
expected_swift_size)
|
||||||
|
|
||||||
self.assertEqual(expected_location, location)
|
self.assertEqual(expected_location, loc)
|
||||||
self.assertEqual(expected_swift_size, size)
|
self.assertEqual(expected_swift_size, size)
|
||||||
self.assertEqual(expected_checksum, checksum)
|
self.assertEqual(expected_checksum, checksum)
|
||||||
self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 1)
|
self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 1)
|
||||||
|
|
||||||
loc = get_location_from_uri(expected_location)
|
loc = location.get_location_from_uri(expected_location, conf=self.conf)
|
||||||
(new_image_swift, new_image_size) = self.store.get(loc)
|
(new_image_swift, new_image_size) = self.store.get(loc)
|
||||||
new_image_contents = ''.join([chunk for chunk in new_image_swift])
|
new_image_contents = ''.join([chunk for chunk in new_image_swift])
|
||||||
new_image_swift_size = len(new_image_swift)
|
new_image_swift_size = len(new_image_swift)
|
||||||
@ -555,21 +556,21 @@ class SwiftTests(object):
|
|||||||
try:
|
try:
|
||||||
self.store.large_object_size = 1024
|
self.store.large_object_size = 1024
|
||||||
self.store.large_object_chunk_size = 1024
|
self.store.large_object_chunk_size = 1024
|
||||||
location, size, checksum, _ = self.store.add(expected_image_id,
|
loc, size, checksum, _ = self.store.add(expected_image_id,
|
||||||
image_swift,
|
image_swift,
|
||||||
expected_swift_size)
|
expected_swift_size)
|
||||||
finally:
|
finally:
|
||||||
self.store.large_object_chunk_size = orig_temp_size
|
self.store.large_object_chunk_size = orig_temp_size
|
||||||
self.store.large_object_size = orig_max_size
|
self.store.large_object_size = orig_max_size
|
||||||
|
|
||||||
self.assertEqual(expected_location, location)
|
self.assertEqual(expected_location, loc)
|
||||||
self.assertEqual(expected_swift_size, size)
|
self.assertEqual(expected_swift_size, size)
|
||||||
self.assertEqual(expected_checksum, checksum)
|
self.assertEqual(expected_checksum, checksum)
|
||||||
# Expecting 6 objects to be created on Swift -- 5 chunks and 1
|
# Expecting 6 objects to be created on Swift -- 5 chunks and 1
|
||||||
# manifest.
|
# manifest.
|
||||||
self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 6)
|
self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 6)
|
||||||
|
|
||||||
loc = get_location_from_uri(expected_location)
|
loc = location.get_location_from_uri(expected_location, conf=self.conf)
|
||||||
(new_image_swift, new_image_size) = self.store.get(loc)
|
(new_image_swift, new_image_size) = self.store.get(loc)
|
||||||
new_image_contents = ''.join([chunk for chunk in new_image_swift])
|
new_image_contents = ''.join([chunk for chunk in new_image_swift])
|
||||||
new_image_swift_size = len(new_image_contents)
|
new_image_swift_size = len(new_image_contents)
|
||||||
@ -613,14 +614,14 @@ class SwiftTests(object):
|
|||||||
MAX_SWIFT_OBJECT_SIZE = 1024
|
MAX_SWIFT_OBJECT_SIZE = 1024
|
||||||
self.store.large_object_size = 1024
|
self.store.large_object_size = 1024
|
||||||
self.store.large_object_chunk_size = 1024
|
self.store.large_object_chunk_size = 1024
|
||||||
location, size, checksum, _ = self.store.add(expected_image_id,
|
loc, size, checksum, _ = self.store.add(expected_image_id,
|
||||||
image_swift, 0)
|
image_swift, 0)
|
||||||
finally:
|
finally:
|
||||||
self.store.large_object_chunk_size = orig_temp_size
|
self.store.large_object_chunk_size = orig_temp_size
|
||||||
self.store.large_object_size = orig_max_size
|
self.store.large_object_size = orig_max_size
|
||||||
MAX_SWIFT_OBJECT_SIZE = orig_max_swift_object_size
|
MAX_SWIFT_OBJECT_SIZE = orig_max_swift_object_size
|
||||||
|
|
||||||
self.assertEqual(expected_location, location)
|
self.assertEqual(expected_location, loc)
|
||||||
self.assertEqual(expected_swift_size, size)
|
self.assertEqual(expected_swift_size, size)
|
||||||
self.assertEqual(expected_checksum, checksum)
|
self.assertEqual(expected_checksum, checksum)
|
||||||
# Expecting 7 calls to put_object -- 5 chunks, a zero chunk which is
|
# Expecting 7 calls to put_object -- 5 chunks, a zero chunk which is
|
||||||
@ -629,7 +630,7 @@ class SwiftTests(object):
|
|||||||
# in that case).
|
# in that case).
|
||||||
self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 7)
|
self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 7)
|
||||||
|
|
||||||
loc = get_location_from_uri(expected_location)
|
loc = location.get_location_from_uri(expected_location, conf=self.conf)
|
||||||
(new_image_swift, new_image_size) = self.store.get(loc)
|
(new_image_swift, new_image_size) = self.store.get(loc)
|
||||||
new_image_contents = ''.join([chunk for chunk in new_image_swift])
|
new_image_contents = ''.join([chunk for chunk in new_image_swift])
|
||||||
new_image_swift_size = len(new_image_contents)
|
new_image_swift_size = len(new_image_contents)
|
||||||
@ -642,6 +643,7 @@ class SwiftTests(object):
|
|||||||
Tests that adding an image with an existing identifier
|
Tests that adding an image with an existing identifier
|
||||||
raises an appropriate exception
|
raises an appropriate exception
|
||||||
"""
|
"""
|
||||||
|
self.store = Store(self.conf)
|
||||||
self.store.configure()
|
self.store.configure()
|
||||||
image_swift = six.StringIO("nevergonnamakeit")
|
image_swift = six.StringIO("nevergonnamakeit")
|
||||||
self.assertRaises(exceptions.Duplicate,
|
self.assertRaises(exceptions.Duplicate,
|
||||||
@ -664,10 +666,10 @@ class SwiftTests(object):
|
|||||||
"""
|
"""
|
||||||
Tests that options without a valid credentials disables the add method
|
Tests that options without a valid credentials disables the add method
|
||||||
"""
|
"""
|
||||||
swift.SWIFT_STORE_REF_PARAMS = {'ref1': {'auth_address':
|
|
||||||
'authurl.com', 'user': '',
|
|
||||||
'key': ''}}
|
|
||||||
self.store = Store(self.conf)
|
self.store = Store(self.conf)
|
||||||
|
self.store.ref_params = {'ref1': {'auth_address':
|
||||||
|
'authurl.com', 'user': '',
|
||||||
|
'key': ''}}
|
||||||
self.store.configure()
|
self.store.configure()
|
||||||
self.assertEqual(self.store.add, self.store.add_disabled)
|
self.assertEqual(self.store.add, self.store.add_disabled)
|
||||||
|
|
||||||
@ -675,11 +677,10 @@ class SwiftTests(object):
|
|||||||
"""
|
"""
|
||||||
Tests that options without auth address disables the add method
|
Tests that options without auth address disables the add method
|
||||||
"""
|
"""
|
||||||
swift.SWIFT_STORE_REF_PARAMS = {'ref1': {'auth_address':
|
|
||||||
'', 'user': 'user1',
|
|
||||||
'key': 'key1'}}
|
|
||||||
|
|
||||||
self.store = Store(self.conf)
|
self.store = Store(self.conf)
|
||||||
|
self.store.ref_params = {'ref1': {'auth_address':
|
||||||
|
'', 'user': 'user1',
|
||||||
|
'key': 'key1'}}
|
||||||
self.store.configure()
|
self.store.configure()
|
||||||
self.assertEqual(self.store.add, self.store.add_disabled)
|
self.assertEqual(self.store.add, self.store.add_disabled)
|
||||||
|
|
||||||
@ -689,7 +690,7 @@ class SwiftTests(object):
|
|||||||
"""
|
"""
|
||||||
uri = "swift://%s:key@authurl/glance/%s" % (
|
uri = "swift://%s:key@authurl/glance/%s" % (
|
||||||
self.swift_store_user, FAKE_UUID)
|
self.swift_store_user, FAKE_UUID)
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
self.store.delete(loc)
|
self.store.delete(loc)
|
||||||
|
|
||||||
self.assertRaises(exceptions.NotFound, self.store.get, loc)
|
self.assertRaises(exceptions.NotFound, self.store.get, loc)
|
||||||
@ -699,7 +700,7 @@ class SwiftTests(object):
|
|||||||
Test we can delete an existing image in the swift store
|
Test we can delete an existing image in the swift store
|
||||||
"""
|
"""
|
||||||
uri = "swift+config://ref1/glance/%s" % (FAKE_UUID)
|
uri = "swift+config://ref1/glance/%s" % (FAKE_UUID)
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
self.store.delete(loc)
|
self.store.delete(loc)
|
||||||
|
|
||||||
self.assertRaises(exceptions.NotFound, self.store.get, loc)
|
self.assertRaises(exceptions.NotFound, self.store.get, loc)
|
||||||
@ -709,8 +710,9 @@ class SwiftTests(object):
|
|||||||
Test that trying to delete a swift that doesn't exist
|
Test that trying to delete a swift that doesn't exist
|
||||||
raises an error
|
raises an error
|
||||||
"""
|
"""
|
||||||
loc = get_location_from_uri("swift://%s:key@authurl/glance/noexist" % (
|
loc = location.get_location_from_uri(
|
||||||
self.swift_store_user))
|
"swift://%s:key@authurl/glance/noexist" % (self.swift_store_user),
|
||||||
|
conf=self.conf)
|
||||||
self.assertRaises(exceptions.NotFound, self.store.delete, loc)
|
self.assertRaises(exceptions.NotFound, self.store.delete, loc)
|
||||||
|
|
||||||
def test_read_acl_public(self):
|
def test_read_acl_public(self):
|
||||||
@ -721,7 +723,7 @@ class SwiftTests(object):
|
|||||||
store = Store(self.conf)
|
store = Store(self.conf)
|
||||||
store.configure()
|
store.configure()
|
||||||
uri = "swift+http://storeurl/glance/%s" % FAKE_UUID
|
uri = "swift+http://storeurl/glance/%s" % FAKE_UUID
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
ctxt = context.RequestContext()
|
ctxt = context.RequestContext()
|
||||||
store.set_acls(loc, public=True, context=ctxt)
|
store.set_acls(loc, public=True, context=ctxt)
|
||||||
container_headers = swiftclient.client.head_container('x', 'y',
|
container_headers = swiftclient.client.head_container('x', 'y',
|
||||||
@ -737,7 +739,7 @@ class SwiftTests(object):
|
|||||||
store = Store(self.conf)
|
store = Store(self.conf)
|
||||||
store.configure()
|
store.configure()
|
||||||
uri = "swift+http://storeurl/glance/%s" % FAKE_UUID
|
uri = "swift+http://storeurl/glance/%s" % FAKE_UUID
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
read_tenants = ['matt', 'mark']
|
read_tenants = ['matt', 'mark']
|
||||||
ctxt = context.RequestContext()
|
ctxt = context.RequestContext()
|
||||||
store.set_acls(loc, read_tenants=read_tenants, context=ctxt)
|
store.set_acls(loc, read_tenants=read_tenants, context=ctxt)
|
||||||
@ -754,7 +756,7 @@ class SwiftTests(object):
|
|||||||
store = Store(self.conf)
|
store = Store(self.conf)
|
||||||
store.configure()
|
store.configure()
|
||||||
uri = "swift+http://storeurl/glance/%s" % FAKE_UUID
|
uri = "swift+http://storeurl/glance/%s" % FAKE_UUID
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
read_tenants = ['frank', 'jim']
|
read_tenants = ['frank', 'jim']
|
||||||
ctxt = context.RequestContext()
|
ctxt = context.RequestContext()
|
||||||
store.set_acls(loc, write_tenants=read_tenants, context=ctxt)
|
store.set_acls(loc, write_tenants=read_tenants, context=ctxt)
|
||||||
@ -790,7 +792,6 @@ class TestStoreAuthV1(base.StoreBaseTest, SwiftTests):
|
|||||||
self.config(**conf)
|
self.config(**conf)
|
||||||
self.store.configure()
|
self.store.configure()
|
||||||
self.register_store_schemes(self.store)
|
self.register_store_schemes(self.store)
|
||||||
swift.SWIFT_STORE_REF_PARAMS = sutils.SwiftParams().params
|
|
||||||
self.addCleanup(self.conf.reset)
|
self.addCleanup(self.conf.reset)
|
||||||
|
|
||||||
|
|
||||||
@ -804,7 +805,7 @@ class TestStoreAuthV2(TestStoreAuthV1):
|
|||||||
|
|
||||||
def test_v2_with_no_tenant(self):
|
def test_v2_with_no_tenant(self):
|
||||||
uri = "swift://failme:key@auth_address/glance/%s" % (FAKE_UUID)
|
uri = "swift://failme:key@auth_address/glance/%s" % (FAKE_UUID)
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
self.assertRaises(exceptions.BadStoreUri,
|
self.assertRaises(exceptions.BadStoreUri,
|
||||||
self.store.get,
|
self.store.get,
|
||||||
loc)
|
loc)
|
||||||
@ -813,7 +814,7 @@ class TestStoreAuthV2(TestStoreAuthV1):
|
|||||||
conf = self.getConfig()
|
conf = self.getConfig()
|
||||||
conf['swift_store_multi_tenant'] = True
|
conf['swift_store_multi_tenant'] = True
|
||||||
uri = "swift://auth_address/glance/%s" % (FAKE_UUID)
|
uri = "swift://auth_address/glance/%s" % (FAKE_UUID)
|
||||||
loc = get_location_from_uri(uri)
|
loc = location.get_location_from_uri(uri, conf=self.conf)
|
||||||
self.assertEqual('swift', loc.store_name)
|
self.assertEqual('swift', loc.store_name)
|
||||||
|
|
||||||
|
|
||||||
@ -853,7 +854,7 @@ class TestSingleTenantStoreConnections(base.StoreBaseTest):
|
|||||||
'key': 'key1',
|
'key': 'key1',
|
||||||
'container': 'cont',
|
'container': 'cont',
|
||||||
'obj': 'object'}
|
'obj': 'object'}
|
||||||
self.location = swift.StoreLocation(specs)
|
self.location = swift.StoreLocation(specs, self.conf)
|
||||||
self.addCleanup(self.conf.reset)
|
self.addCleanup(self.conf.reset)
|
||||||
|
|
||||||
def test_basic_connection(self):
|
def test_basic_connection(self):
|
||||||
@ -969,7 +970,7 @@ class TestMultiTenantStoreConnections(base.StoreBaseTest):
|
|||||||
'auth_or_store_url': 'example.com',
|
'auth_or_store_url': 'example.com',
|
||||||
'container': 'cont',
|
'container': 'cont',
|
||||||
'obj': 'object'}
|
'obj': 'object'}
|
||||||
self.location = swift.StoreLocation(specs)
|
self.location = swift.StoreLocation(specs, self.conf)
|
||||||
self.addCleanup(self.conf.reset)
|
self.addCleanup(self.conf.reset)
|
||||||
|
|
||||||
def test_basic_connection(self):
|
def test_basic_connection(self):
|
||||||
@ -1047,7 +1048,6 @@ class TestCreatingLocations(base.StoreBaseTest):
|
|||||||
default_swift_reference='ref2',
|
default_swift_reference='ref2',
|
||||||
swift_store_config_file=self.swift_config_file)
|
swift_store_config_file=self.swift_config_file)
|
||||||
|
|
||||||
swift.SWIFT_STORE_REF_PARAMS = sutils.SwiftParams().params
|
|
||||||
store = swift.SingleTenantStore(self.conf)
|
store = swift.SingleTenantStore(self.conf)
|
||||||
store.configure()
|
store.configure()
|
||||||
location = store.create_location('image-id')
|
location = store.create_location('image-id')
|
||||||
|
87
tests/unit/test_swift_store_utils.py
Normal file
87
tests/unit/test_swift_store_utils.py
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
# Copyright 2014 OpenStack Foundation
|
||||||
|
# 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 fixtures
|
||||||
|
|
||||||
|
from glance_store._drivers.swift import utils as sutils
|
||||||
|
from glance_store import exceptions
|
||||||
|
from glance_store.tests import base
|
||||||
|
|
||||||
|
|
||||||
|
class TestSwiftParams(base.StoreBaseTest):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestSwiftParams, self).setUp()
|
||||||
|
conf_file = "glance-swift.conf"
|
||||||
|
test_dir = self.useFixture(fixtures.TempDir()).path
|
||||||
|
self.swift_config_file = self.copy_data_file(conf_file, test_dir)
|
||||||
|
self.config(swift_store_config_file=self.swift_config_file)
|
||||||
|
|
||||||
|
def test_multiple_swift_account_enabled(self):
|
||||||
|
self.config(swift_store_config_file="glance-swift.conf")
|
||||||
|
self.assertTrue(
|
||||||
|
sutils.is_multiple_swift_store_accounts_enabled(self.conf))
|
||||||
|
|
||||||
|
def test_multiple_swift_account_disabled(self):
|
||||||
|
self.config(swift_store_config_file=None)
|
||||||
|
self.assertFalse(
|
||||||
|
sutils.is_multiple_swift_store_accounts_enabled(self.conf))
|
||||||
|
|
||||||
|
def test_swift_config_file_doesnt_exist(self):
|
||||||
|
self.config(swift_store_config_file='fake-file.conf')
|
||||||
|
self.assertRaises(exceptions.BadStoreConfiguration,
|
||||||
|
sutils.SwiftParams, self.conf)
|
||||||
|
|
||||||
|
def test_swift_config_uses_default_values_multiple_account_disabled(self):
|
||||||
|
default_user = 'user_default'
|
||||||
|
default_key = 'key_default'
|
||||||
|
default_auth_address = 'auth@default.com'
|
||||||
|
default_account_reference = 'ref_default'
|
||||||
|
conf = {'swift_store_config_file': None,
|
||||||
|
'swift_store_user': default_user,
|
||||||
|
'swift_store_key': default_key,
|
||||||
|
'swift_store_auth_address': default_auth_address,
|
||||||
|
'default_swift_reference': default_account_reference}
|
||||||
|
self.config(**conf)
|
||||||
|
swift_params = sutils.SwiftParams(self.conf).params
|
||||||
|
self.assertEqual(1, len(swift_params.keys()))
|
||||||
|
self.assertEqual(default_user,
|
||||||
|
swift_params[default_account_reference]['user']
|
||||||
|
)
|
||||||
|
self.assertEqual(default_key,
|
||||||
|
swift_params[default_account_reference]['key']
|
||||||
|
)
|
||||||
|
self.assertEqual(default_auth_address,
|
||||||
|
swift_params[default_account_reference]
|
||||||
|
['auth_address']
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_swift_store_config_validates_for_creds_auth_address(self):
|
||||||
|
swift_params = sutils.SwiftParams(self.conf).params
|
||||||
|
self.assertEqual('tenant:user1',
|
||||||
|
swift_params['ref1']['user']
|
||||||
|
)
|
||||||
|
self.assertEqual('key1',
|
||||||
|
swift_params['ref1']['key']
|
||||||
|
)
|
||||||
|
self.assertEqual('example.com',
|
||||||
|
swift_params['ref1']['auth_address'])
|
||||||
|
self.assertEqual('user2',
|
||||||
|
swift_params['ref2']['user'])
|
||||||
|
self.assertEqual('key2',
|
||||||
|
swift_params['ref2']['key'])
|
||||||
|
self.assertEqual('http://example.com',
|
||||||
|
swift_params['ref2']['auth_address']
|
||||||
|
)
|
@ -24,7 +24,7 @@ import six
|
|||||||
import glance_store._drivers.vmware_datastore as vm_store
|
import glance_store._drivers.vmware_datastore as vm_store
|
||||||
from glance_store import backend
|
from glance_store import backend
|
||||||
from glance_store import exceptions
|
from glance_store import exceptions
|
||||||
from glance_store.location import get_location_from_uri
|
from glance_store import location
|
||||||
from glance_store.openstack.common import units
|
from glance_store.openstack.common import units
|
||||||
from glance_store.tests import base
|
from glance_store.tests import base
|
||||||
from glance_store.tests import utils
|
from glance_store.tests import utils
|
||||||
@ -135,9 +135,9 @@ class TestStore(base.StoreBaseTest):
|
|||||||
expected_image_size = 31
|
expected_image_size = 31
|
||||||
expected_returns = ['I ', 'am', ' a', ' t', 'ea', 'po', 't,', ' s',
|
expected_returns = ['I ', 'am', ' a', ' t', 'ea', 'po', 't,', ' s',
|
||||||
'ho', 'rt', ' a', 'nd', ' s', 'to', 'ut', '\n']
|
'ho', 'rt', ' a', 'nd', ' s', 'to', 'ut', '\n']
|
||||||
loc = get_location_from_uri(
|
loc = location.get_location_from_uri(
|
||||||
"vsphere://127.0.0.1/folder/openstack_glance/%s"
|
"vsphere://127.0.0.1/folder/openstack_glance/%s"
|
||||||
"?dsName=ds1&dcPath=dc1" % FAKE_UUID)
|
"?dsName=ds1&dcPath=dc1" % FAKE_UUID, conf=self.conf)
|
||||||
with mock.patch('httplib.HTTPConnection') as HttpConn:
|
with mock.patch('httplib.HTTPConnection') as HttpConn:
|
||||||
HttpConn.return_value = FakeHTTPConnection()
|
HttpConn.return_value = FakeHTTPConnection()
|
||||||
(image_file, image_size) = self.store.get(loc)
|
(image_file, image_size) = self.store.get(loc)
|
||||||
@ -150,8 +150,9 @@ class TestStore(base.StoreBaseTest):
|
|||||||
Test that trying to retrieve an image that doesn't exist
|
Test that trying to retrieve an image that doesn't exist
|
||||||
raises an error
|
raises an error
|
||||||
"""
|
"""
|
||||||
loc = get_location_from_uri("vsphere://127.0.0.1/folder/openstack_glan"
|
loc = location.get_location_from_uri(
|
||||||
"ce/%s?dsName=ds1&dcPath=dc1" % FAKE_UUID)
|
"vsphere://127.0.0.1/folder/openstack_glan"
|
||||||
|
"ce/%s?dsName=ds1&dcPath=dc1" % FAKE_UUID, conf=self.conf)
|
||||||
with mock.patch('httplib.HTTPConnection') as HttpConn:
|
with mock.patch('httplib.HTTPConnection') as HttpConn:
|
||||||
HttpConn.return_value = FakeHTTPConnection(status=404)
|
HttpConn.return_value = FakeHTTPConnection(status=404)
|
||||||
self.assertRaises(exceptions.NotFound, self.store.get, loc)
|
self.assertRaises(exceptions.NotFound, self.store.get, loc)
|
||||||
@ -216,9 +217,9 @@ class TestStore(base.StoreBaseTest):
|
|||||||
|
|
||||||
def test_delete(self):
|
def test_delete(self):
|
||||||
"""Test we can delete an existing image in the VMware store."""
|
"""Test we can delete an existing image in the VMware store."""
|
||||||
loc = get_location_from_uri(
|
loc = location.get_location_from_uri(
|
||||||
"vsphere://127.0.0.1/folder/openstack_glance/%s?"
|
"vsphere://127.0.0.1/folder/openstack_glance/%s?"
|
||||||
"dsName=ds1&dcPath=dc1" % FAKE_UUID)
|
"dsName=ds1&dcPath=dc1" % FAKE_UUID, conf=self.conf)
|
||||||
with mock.patch('httplib.HTTPConnection') as HttpConn:
|
with mock.patch('httplib.HTTPConnection') as HttpConn:
|
||||||
HttpConn.return_value = FakeHTTPConnection()
|
HttpConn.return_value = FakeHTTPConnection()
|
||||||
vm_store.Store._service_content = mock.Mock()
|
vm_store.Store._service_content = mock.Mock()
|
||||||
@ -231,9 +232,9 @@ class TestStore(base.StoreBaseTest):
|
|||||||
"""
|
"""
|
||||||
Test we can get the size of an existing image in the VMware store
|
Test we can get the size of an existing image in the VMware store
|
||||||
"""
|
"""
|
||||||
loc = get_location_from_uri(
|
loc = location.get_location_from_uri(
|
||||||
"vsphere://127.0.0.1/folder/openstack_glance/%s"
|
"vsphere://127.0.0.1/folder/openstack_glance/%s"
|
||||||
"?dsName=ds1&dcPath=dc1" % FAKE_UUID)
|
"?dsName=ds1&dcPath=dc1" % FAKE_UUID, conf=self.conf)
|
||||||
with mock.patch('httplib.HTTPConnection') as HttpConn:
|
with mock.patch('httplib.HTTPConnection') as HttpConn:
|
||||||
HttpConn.return_value = FakeHTTPConnection()
|
HttpConn.return_value = FakeHTTPConnection()
|
||||||
image_size = self.store.get_size(loc)
|
image_size = self.store.get_size(loc)
|
||||||
@ -244,8 +245,9 @@ class TestStore(base.StoreBaseTest):
|
|||||||
Test that trying to retrieve an image size that doesn't exist
|
Test that trying to retrieve an image size that doesn't exist
|
||||||
raises an error
|
raises an error
|
||||||
"""
|
"""
|
||||||
loc = get_location_from_uri("vsphere://127.0.0.1/folder/openstack_glan"
|
loc = location.get_location_from_uri(
|
||||||
"ce/%s?dsName=ds1&dcPath=dc1" % FAKE_UUID)
|
"vsphere://127.0.0.1/folder/openstack_glan"
|
||||||
|
"ce/%s?dsName=ds1&dcPath=dc1" % FAKE_UUID, conf=self.conf)
|
||||||
with mock.patch('httplib.HTTPConnection') as HttpConn:
|
with mock.patch('httplib.HTTPConnection') as HttpConn:
|
||||||
HttpConn.return_value = FakeHTTPConnection(status=404)
|
HttpConn.return_value = FakeHTTPConnection(status=404)
|
||||||
self.assertRaises(exceptions.NotFound, self.store.get_size, loc)
|
self.assertRaises(exceptions.NotFound, self.store.get_size, loc)
|
||||||
|
Loading…
Reference in New Issue
Block a user