Add multi-store support

Added multi-store support. User can now use '--backend'
option to pass desired store while creating, uploading or
importing image to speific store backend.

Added new command 'stores-info' which will return available
stores information to the user.

Related to blueprint multi-store
Change-Id: I7370094fc4ed47205b5a86a18b22aaa7b9457e5b
This commit is contained in:
Abhishek Kekane
2018-05-30 09:38:37 +00:00
parent 71abbfca2a
commit 71bfd7bfad
3 changed files with 113 additions and 11 deletions
+25 -4
View File
@@ -218,16 +218,21 @@ class Controller(object):
return utils.IterableWithLength(body, content_length), resp
@utils.add_req_id_to_object()
def upload(self, image_id, image_data, image_size=None, u_url=None):
def upload(self, image_id, image_data, image_size=None, u_url=None,
backend=None):
"""Upload the data for an image.
:param image_id: ID of the image to upload data for.
:param image_data: File-like object supplying the data to upload.
:param image_size: Unused - present for backwards compatibility
:param u_url: Upload url to upload the data to.
:param backend: Backend store to upload image to.
"""
url = u_url or '/v2/images/%s/file' % image_id
hdrs = {'Content-Type': 'application/octet-stream'}
if backend is not None:
hdrs['x-image-meta-store'] = backend
body = image_data
resp, body = self.http_client.put(url, headers=hdrs, data=body)
return (resp, body), resp
@@ -239,6 +244,13 @@ class Controller(object):
resp, body = self.http_client.get(url)
return body, resp
@utils.add_req_id_to_object()
def get_stores_info(self):
"""Get available stores info from discovery endpoint."""
url = '/v2/info/stores'
resp, body = self.http_client.get(url)
return body, resp
@utils.add_req_id_to_object()
def stage(self, image_id, image_data, image_size=None):
"""Upload the data to image staging.
@@ -254,17 +266,22 @@ class Controller(object):
return body, resp
@utils.add_req_id_to_object()
def image_import(self, image_id, method='glance-direct', uri=None):
def image_import(self, image_id, method='glance-direct', uri=None,
backend=None):
"""Import Image via method."""
headers = {}
url = '/v2/images/%s/import' % image_id
data = {'method': {'name': method}}
if backend is not None:
headers['x-image-meta-store'] = backend
if uri:
if method == 'web-download':
data['method']['uri'] = uri
else:
raise exc.HTTPBadRequest('URI is only supported with method: '
'"web-download"')
resp, body = self.http_client.post(url, data=data)
resp, body = self.http_client.post(url, data=data, headers=headers)
return body, resp
@utils.add_req_id_to_object()
@@ -277,7 +294,11 @@ class Controller(object):
@utils.add_req_id_to_object()
def create(self, **kwargs):
"""Create an image."""
headers = {}
url = '/v2/images'
backend = kwargs.pop('backend', None)
if backend is not None:
headers['x-image-meta-store'] = backend
image = self.model()
for (key, value) in kwargs.items():
@@ -286,7 +307,7 @@ class Controller(object):
except warlock.InvalidOperation as e:
raise TypeError(encodeutils.exception_to_unicode(e))
resp, body = self.http_client.post(url, data=image)
resp, body = self.http_client.post(url, headers=headers, data=image)
# NOTE(esheffield): remove 'self' for now until we have an elegant
# way to pass it into the model constructor without conflict
body.pop('self', None)