summaryrefslogtreecommitdiff
path: root/nova/image
diff options
context:
space:
mode:
authorJay Pipes <jaypipes@gmail.com>2018-11-06 10:59:40 -0500
committerJay Pipes <jaypipes@gmail.com>2018-11-06 11:01:59 -0500
commit5c21a00e89539bbb271ccfa05e4a2ba1cddae58e (patch)
treebd3b8d5e45b65b6ed4d5f50cc585f2da2c91c5fc /nova/image
parent90b96170d3f269165f649e8b61739cf31ffb78b8 (diff)
downloadnova-5c21a00e89539bbb271ccfa05e4a2ba1cddae58e.tar.gz
prevent common kwargs from glance client failure
When creating a snapshot of a server using the nova API, failure occurs if the image contains the metadata property "version". This was due to the way that the GlanceClientWrapper.call() function signature was structured. This patch forces all client positional args to be passed as a named "args" argument to the call() function and all client named args to be pass as a named "kwargs" argument to the call() function. This eliminates any argument name-shadowing that previously caused issues. Closes-bug: #1717547 Change-Id: I3ed3303309fe2a25c0043fd206f36bada4b3b8f9
Diffstat (limited to 'nova/image')
-rw-r--r--nova/image/glance.py45
1 files changed, 30 insertions, 15 deletions
diff --git a/nova/image/glance.py b/nova/image/glance.py
index 8a38794799..facc71c108 100644
--- a/nova/image/glance.py
+++ b/nova/image/glance.py
@@ -161,21 +161,35 @@ class GlanceClientWrapper(object):
self.api_server = next(self.api_servers)
return _glanceclient_from_endpoint(context, self.api_server, version)
- def call(self, context, version, method, *args, **kwargs):
+ def call(self, context, version, method, controller=None, args=None,
+ kwargs=None):
"""Call a glance client method. If we get a connection error,
retry the request according to CONF.glance.num_retries.
+
+ :param context: RequestContext to use
+ :param version: Numeric version of the *Glance API* to use
+ :param method: string method name to execute on the glanceclient
+ :param controller: optional string name of the client controller to
+ use. Default (None) is to use the 'images'
+ controller
+ :param args: optional iterable of arguments to pass to the
+ glanceclient method, splatted as positional args
+ :param kwargs: optional dict of arguments to pass to the glanceclient,
+ splatted into named arguments
"""
+ args = args or []
+ kwargs = kwargs or {}
retry_excs = (glanceclient.exc.ServiceUnavailable,
glanceclient.exc.InvalidEndpoint,
glanceclient.exc.CommunicationError)
num_attempts = 1 + CONF.glance.num_retries
+ controller_name = controller or 'images'
for attempt in range(1, num_attempts + 1):
client = self.client or self._create_onetime_client(context,
version)
try:
- controller = getattr(client,
- kwargs.pop('controller', 'images'))
+ controller = getattr(client, controller_name)
result = getattr(controller, method)(*args, **kwargs)
if inspect.isgenerator(result):
# Convert generator results to a list, so that we can
@@ -239,7 +253,7 @@ class GlanceImageServiceV2(object):
image is deleted.
"""
try:
- image = self._client.call(context, 2, 'get', image_id)
+ image = self._client.call(context, 2, 'get', args=(image_id,))
except Exception:
_reraise_translated_image_exception(image_id)
@@ -274,7 +288,7 @@ class GlanceImageServiceV2(object):
"""Calls out to Glance for a list of detailed image information."""
params = _extract_query_params_v2(kwargs)
try:
- images = self._client.call(context, 2, 'list', **params)
+ images = self._client.call(context, 2, 'list', kwargs=params)
except Exception:
_reraise_translated_exception()
@@ -320,7 +334,8 @@ class GlanceImageServiceV2(object):
LOG.exception("Download image error")
try:
- image_chunks = self._client.call(context, 2, 'data', image_id)
+ image_chunks = self._client.call(
+ context, 2, 'data', args=(image_id,))
except Exception:
_reraise_translated_image_exception(image_id)
@@ -466,14 +481,14 @@ class GlanceImageServiceV2(object):
def _add_location(self, context, image_id, location):
# 'show_multiple_locations' must be enabled in glance api conf file.
try:
- return self._client.call(context, 2, 'add_location', image_id,
- location, {})
+ return self._client.call(
+ context, 2, 'add_location', args=(image_id, location))
except glanceclient.exc.HTTPBadRequest:
_reraise_translated_exception()
def _upload_data(self, context, image_id, data):
- self._client.call(context, 2, 'upload', image_id, data)
- return self._client.call(context, 2, 'get', image_id)
+ self._client.call(context, 2, 'upload', args=(image_id, data))
+ return self._client.call(context, 2, 'get', args=(image_id,))
def _get_image_create_disk_format_default(self, context):
"""Gets an acceptable default image disk_format based on the schema.
@@ -493,8 +508,8 @@ class GlanceImageServiceV2(object):
# Get the image schema - note we don't cache this value since it could
# change under us. This looks a bit funky, but what it's basically
# doing is calling glanceclient.v2.Client.schemas.get('image').
- image_schema = self._client.call(context, 2, 'get', 'image',
- controller='schemas')
+ image_schema = self._client.call(
+ context, 2, 'get', args=('image',), controller='schemas')
# get the disk_format schema property from the raw schema
disk_format_schema = (
image_schema.raw()['properties'].get('disk_format') if image_schema
@@ -534,7 +549,7 @@ class GlanceImageServiceV2(object):
location = sent_service_image_meta.pop('location', None)
image = self._client.call(
- context, 2, 'create', **sent_service_image_meta)
+ context, 2, 'create', kwargs=sent_service_image_meta)
image_id = image['id']
# Sending image location in a separate request.
@@ -578,7 +593,7 @@ class GlanceImageServiceV2(object):
location = sent_service_image_meta.pop('location', None)
image_id = sent_service_image_meta['image_id']
image = self._client.call(
- context, 2, 'update', **sent_service_image_meta)
+ context, 2, 'update', kwargs=sent_service_image_meta)
# Sending image location in a separate request.
if location:
@@ -601,7 +616,7 @@ class GlanceImageServiceV2(object):
"""
try:
- self._client.call(context, 2, 'delete', image_id)
+ self._client.call(context, 2, 'delete', args=(image_id,))
except glanceclient.exc.NotFound:
raise exception.ImageNotFound(image_id=image_id)
except glanceclient.exc.HTTPForbidden: