Fix v2 requests to non-bleeding edge servers
In the case where v2 requests are sent to a server which is not running head of tree which includes the v2 metadef code some 404 cases need to be handled to enable standard requests to complete. This patch aslo improves fetching schemas -- they are now only fetched as needed. Change-Id: I8c871f11b909337bd7df19b77e606772dbc634b2 Closes-bug: #1367326
This commit is contained in:
committed by
Stuart McLaren
parent
fde99a0a4d
commit
97b1506bdb
@@ -21,6 +21,7 @@ import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import threading
|
||||
import uuid
|
||||
|
||||
import six
|
||||
@@ -36,6 +37,8 @@ from glanceclient import exc
|
||||
from glanceclient.openstack.common import importutils
|
||||
from glanceclient.openstack.common import strutils
|
||||
|
||||
_memoized_property_lock = threading.Lock()
|
||||
|
||||
|
||||
# Decorator for cli-args
|
||||
def arg(*args, **kwargs):
|
||||
@@ -367,3 +370,18 @@ def integrity_iter(iter, checksum):
|
||||
raise IOError(errno.EPIPE,
|
||||
'Corrupt image download. Checksum was %s expected %s' %
|
||||
(md5sum, checksum))
|
||||
|
||||
|
||||
def memoized_property(fn):
|
||||
attr_name = '_lazy_once_' + fn.__name__
|
||||
|
||||
@property
|
||||
def _memoized_property(self):
|
||||
if hasattr(self, attr_name):
|
||||
return getattr(self, attr_name)
|
||||
else:
|
||||
with _memoized_property_lock:
|
||||
if not hasattr(self, attr_name):
|
||||
setattr(self, attr_name, fn(self))
|
||||
return getattr(self, attr_name)
|
||||
return _memoized_property
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import warlock
|
||||
|
||||
from glanceclient.common import http
|
||||
from glanceclient.common import utils
|
||||
@@ -38,50 +37,21 @@ class Client(object):
|
||||
self.http_client = http.HTTPClient(utils.strip_version(endpoint),
|
||||
*args, **kwargs)
|
||||
self.schemas = schemas.Controller(self.http_client)
|
||||
image_model = self._get_image_model()
|
||||
self.images = images.Controller(self.http_client,
|
||||
image_model)
|
||||
self.image_tags = image_tags.Controller(self.http_client, image_model)
|
||||
|
||||
self.images = images.Controller(self.http_client, self.schemas)
|
||||
self.image_tags = image_tags.Controller(self.http_client,
|
||||
self.schemas)
|
||||
self.image_members = image_members.Controller(self.http_client,
|
||||
self._get_member_model())
|
||||
self.schemas)
|
||||
|
||||
resource_type_model = self._get_metadefs_resource_type_model()
|
||||
self.metadefs_resource_type = (
|
||||
metadefs.ResourceTypeController(self.http_client,
|
||||
resource_type_model))
|
||||
metadefs.ResourceTypeController(self.http_client, self.schemas))
|
||||
|
||||
property_model = self._get_metadefs_property_model()
|
||||
self.metadefs_property = (
|
||||
metadefs.PropertyController(self.http_client, property_model))
|
||||
metadefs.PropertyController(self.http_client, self.schemas))
|
||||
|
||||
object_model = self._get_metadefs_object_model()
|
||||
self.metadefs_object = (
|
||||
metadefs.ObjectController(self.http_client, object_model))
|
||||
metadefs.ObjectController(self.http_client, self.schemas))
|
||||
|
||||
namespace_model = self._get_metadefs_namespace_model()
|
||||
self.metadefs_namespace = (
|
||||
metadefs.NamespaceController(self.http_client, namespace_model))
|
||||
|
||||
def _get_image_model(self):
|
||||
schema = self.schemas.get('image')
|
||||
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||
|
||||
def _get_member_model(self):
|
||||
schema = self.schemas.get('member')
|
||||
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||
|
||||
def _get_metadefs_namespace_model(self):
|
||||
schema = self.schemas.get('metadefs/namespace')
|
||||
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||
|
||||
def _get_metadefs_resource_type_model(self):
|
||||
schema = self.schemas.get('metadefs/resource_type')
|
||||
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||
|
||||
def _get_metadefs_property_model(self):
|
||||
schema = self.schemas.get('metadefs/property')
|
||||
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||
|
||||
def _get_metadefs_object_model(self):
|
||||
schema = self.schemas.get('metadefs/object')
|
||||
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||
metadefs.NamespaceController(self.http_client, self.schemas))
|
||||
|
||||
@@ -13,11 +13,21 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import warlock
|
||||
|
||||
from glanceclient.common import utils
|
||||
from glanceclient.v2 import schemas
|
||||
|
||||
|
||||
class Controller(object):
|
||||
def __init__(self, http_client, model):
|
||||
def __init__(self, http_client, schema_client):
|
||||
self.http_client = http_client
|
||||
self.model = model
|
||||
self.schema_client = schema_client
|
||||
|
||||
@utils.memoized_property
|
||||
def model(self):
|
||||
schema = self.schema_client.get('member')
|
||||
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||
|
||||
def list(self, image_id):
|
||||
url = '/v2/images/%s/members' % image_id
|
||||
|
||||
@@ -13,11 +13,21 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import warlock
|
||||
|
||||
from glanceclient.common import utils
|
||||
from glanceclient.v2 import schemas
|
||||
|
||||
|
||||
class Controller(object):
|
||||
def __init__(self, http_client, model):
|
||||
def __init__(self, http_client, schema_client):
|
||||
self.http_client = http_client
|
||||
self.model = model
|
||||
self.schema_client = schema_client
|
||||
|
||||
@utils.memoized_property
|
||||
def model(self):
|
||||
schema = self.schema_client.get('image')
|
||||
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||
|
||||
def update(self, image_id, tag_value):
|
||||
"""
|
||||
|
||||
@@ -21,14 +21,20 @@ import warlock
|
||||
from glanceclient.common import utils
|
||||
from glanceclient import exc
|
||||
from glanceclient.openstack.common import strutils
|
||||
from glanceclient.v2 import schemas
|
||||
|
||||
DEFAULT_PAGE_SIZE = 20
|
||||
|
||||
|
||||
class Controller(object):
|
||||
def __init__(self, http_client, model):
|
||||
def __init__(self, http_client, schema_client):
|
||||
self.http_client = http_client
|
||||
self.model = model
|
||||
self.schema_client = schema_client
|
||||
|
||||
@utils.memoized_property
|
||||
def model(self):
|
||||
schema = self.schema_client.get('image')
|
||||
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||
|
||||
def list(self, **kwargs):
|
||||
"""Retrieve a listing of Image objects
|
||||
|
||||
@@ -19,14 +19,20 @@ import warlock
|
||||
|
||||
from glanceclient.common import utils
|
||||
from glanceclient.openstack.common import strutils
|
||||
from glanceclient.v2 import schemas
|
||||
|
||||
DEFAULT_PAGE_SIZE = 20
|
||||
|
||||
|
||||
class NamespaceController(object):
|
||||
def __init__(self, http_client, model):
|
||||
def __init__(self, http_client, schema_client):
|
||||
self.http_client = http_client
|
||||
self.model = model
|
||||
self.schema_client = schema_client
|
||||
|
||||
@utils.memoized_property
|
||||
def model(self):
|
||||
schema = self.schema_client.get('metadefs/namespace')
|
||||
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||
|
||||
def create(self, **kwargs):
|
||||
"""Create a namespace.
|
||||
@@ -75,7 +81,7 @@ class NamespaceController(object):
|
||||
|
||||
url = '/v2/metadefs/namespaces/{0}{1}'.format(namespace, query_params)
|
||||
resp, body = self.http_client.get(url)
|
||||
#NOTE(bcwaldon): remove 'self' for now until we have an elegant
|
||||
# NOTE(bcwaldon): remove 'self' for now until we have an elegant
|
||||
# way to pass it into the model constructor without conflict
|
||||
body.pop('self', None)
|
||||
return self.model(**body)
|
||||
@@ -141,9 +147,14 @@ class NamespaceController(object):
|
||||
|
||||
|
||||
class ResourceTypeController(object):
|
||||
def __init__(self, http_client, model):
|
||||
def __init__(self, http_client, schema_client):
|
||||
self.http_client = http_client
|
||||
self.model = model
|
||||
self.schema_client = schema_client
|
||||
|
||||
@utils.memoized_property
|
||||
def model(self):
|
||||
schema = self.schema_client.get('metadefs/resource_type')
|
||||
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||
|
||||
def associate(self, namespace, **kwargs):
|
||||
"""Associate a resource type with a namespace."""
|
||||
@@ -184,9 +195,14 @@ class ResourceTypeController(object):
|
||||
|
||||
|
||||
class PropertyController(object):
|
||||
def __init__(self, http_client, model):
|
||||
def __init__(self, http_client, schema_client):
|
||||
self.http_client = http_client
|
||||
self.model = model
|
||||
self.schema_client = schema_client
|
||||
|
||||
@utils.memoized_property
|
||||
def model(self):
|
||||
schema = self.schema_client.get('metadefs/property')
|
||||
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||
|
||||
def create(self, namespace, **kwargs):
|
||||
"""Create a property.
|
||||
@@ -259,9 +275,14 @@ class PropertyController(object):
|
||||
|
||||
|
||||
class ObjectController(object):
|
||||
def __init__(self, http_client, model):
|
||||
def __init__(self, http_client, schema_client):
|
||||
self.http_client = http_client
|
||||
self.model = model
|
||||
self.schema_client = schema_client
|
||||
|
||||
@utils.memoized_property
|
||||
def model(self):
|
||||
schema = self.schema_client.get('metadefs/object')
|
||||
return warlock.model_factory(schema.raw(), schemas.SchemaBasedModel)
|
||||
|
||||
def create(self, namespace, **kwargs):
|
||||
"""Create an object.
|
||||
|
||||
Reference in New Issue
Block a user