image: Add missing image import options
Add support for the following options: - remote_region - remote_image_id - remote_service_interface In addition, we now return the response to the user. Change-Id: I7ebb75896002ea8e0eca6617eb407e94050bce65 Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
parent
5106f2f49f
commit
433d97c40c
@ -50,7 +50,14 @@ class Proxy(_base_proxy.BaseImageProxy):
|
||||
return self._create(_image.Image, **kwargs)
|
||||
|
||||
def import_image(
|
||||
self, image, method='glance-direct', uri=None,
|
||||
self,
|
||||
image,
|
||||
method='glance-direct',
|
||||
*,
|
||||
uri=None,
|
||||
remote_region=None,
|
||||
remote_image_id=None,
|
||||
remote_service_interface=None,
|
||||
store=None,
|
||||
stores=None,
|
||||
all_stores=None,
|
||||
@ -67,12 +74,23 @@ class Proxy(_base_proxy.BaseImageProxy):
|
||||
The value can be the ID of a image or a
|
||||
:class:`~openstack.image.v2.image.Image` instance.
|
||||
:param method:
|
||||
Method to use for importing the image.
|
||||
A valid value is glance-direct or web-download.
|
||||
Method to use for importing the image. Not all deployments support
|
||||
all methods. One of: ``glance-direct`` (default), ``web-download``,
|
||||
``glance-download``, or ``copy-image``. Use of ``glance-direct``
|
||||
requires the image be first staged.
|
||||
:param uri:
|
||||
Required only if using the web-download import method.
|
||||
This url is where the data is made available to the Image
|
||||
service.
|
||||
:param remote_region:
|
||||
The remote glance region to download the image from when using
|
||||
glance-download.
|
||||
:param remote_image_id:
|
||||
The ID of the image to import from the remote glance when using
|
||||
glance-download.
|
||||
:param remote_service_interface:
|
||||
The remote glance service interface to use when using
|
||||
glance-download
|
||||
:param store:
|
||||
Used when enabled_backends is activated in glance. The value
|
||||
can be the id of a store or a
|
||||
@ -95,17 +113,19 @@ class Proxy(_base_proxy.BaseImageProxy):
|
||||
the stores where the data has been correctly uploaded.
|
||||
Default is True.
|
||||
|
||||
:returns: None
|
||||
:returns: The raw response from the request.
|
||||
"""
|
||||
image = self._get_resource(_image.Image, image)
|
||||
if all_stores and (store or stores):
|
||||
raise exceptions.InvalidRequest(
|
||||
"all_stores is mutually exclusive with "
|
||||
" store and stores")
|
||||
"store and stores"
|
||||
)
|
||||
if store is not None:
|
||||
if stores:
|
||||
raise exceptions.InvalidRequest(
|
||||
"store and stores are mutually exclusive")
|
||||
"store and stores are mutually exclusive"
|
||||
)
|
||||
store = self._get_resource(_si.Store, store)
|
||||
|
||||
stores = stores or []
|
||||
@ -119,10 +139,16 @@ class Proxy(_base_proxy.BaseImageProxy):
|
||||
if not all([image.container_format, image.disk_format]):
|
||||
raise exceptions.InvalidRequest(
|
||||
"Both container_format and disk_format are required for "
|
||||
" importing an image")
|
||||
"importing an image"
|
||||
)
|
||||
|
||||
image.import_image(
|
||||
self, method=method, uri=uri,
|
||||
return image.import_image(
|
||||
self,
|
||||
method=method,
|
||||
uri=uri,
|
||||
remote_region=remote_region,
|
||||
remote_image_id=remote_image_id,
|
||||
remote_service_interface=remote_service_interface,
|
||||
store=store,
|
||||
stores=stores,
|
||||
all_stores=all_stores,
|
||||
|
@ -298,44 +298,66 @@ class Image(resource.Resource, tag.TagMixin, _download.DownloadMixin):
|
||||
self._translate_response(response, has_body=False)
|
||||
return self
|
||||
|
||||
def import_image(self, session, method='glance-direct', uri=None,
|
||||
store=None, stores=None, all_stores=None,
|
||||
all_stores_must_succeed=None):
|
||||
def import_image(
|
||||
self,
|
||||
session,
|
||||
method='glance-direct',
|
||||
*,
|
||||
uri=None,
|
||||
remote_region=None,
|
||||
remote_image_id=None,
|
||||
remote_service_interface=None,
|
||||
store=None,
|
||||
stores=None,
|
||||
all_stores=None,
|
||||
all_stores_must_succeed=None,
|
||||
):
|
||||
"""Import Image via interoperable image import process"""
|
||||
if all_stores and (store or stores):
|
||||
raise exceptions.InvalidRequest(
|
||||
"all_stores is mutually exclusive with"
|
||||
" store and stores")
|
||||
'all_stores is mutually exclusive with store and stores'
|
||||
)
|
||||
if store and stores:
|
||||
raise exceptions.InvalidRequest(
|
||||
"store and stores are mutually exclusive."
|
||||
" Please just use stores.")
|
||||
'store and stores are mutually exclusive. stores should be '
|
||||
'preferred.'
|
||||
)
|
||||
if store:
|
||||
stores = [store]
|
||||
else:
|
||||
stores = stores or []
|
||||
|
||||
url = utils.urljoin(self.base_path, self.id, 'import')
|
||||
json = {'method': {'name': method}}
|
||||
data = {'method': {'name': method}}
|
||||
|
||||
if uri:
|
||||
if method == 'web-download':
|
||||
json['method']['uri'] = uri
|
||||
else:
|
||||
raise exceptions.InvalidRequest('URI is only supported with '
|
||||
'method: "web-download"')
|
||||
if method != 'web-download':
|
||||
raise exceptions.InvalidRequest(
|
||||
'URI is only supported with method: "web-download"'
|
||||
)
|
||||
data['method']['uri'] = uri
|
||||
|
||||
if remote_region and remote_image_id:
|
||||
if remote_service_interface:
|
||||
data['method']['glance_service_interface'] = \
|
||||
remote_service_interface
|
||||
data['method']['glance_region'] = remote_region
|
||||
data['method']['glance_image_id'] = remote_image_id
|
||||
|
||||
if all_stores is not None:
|
||||
json['all_stores'] = all_stores
|
||||
data['all_stores'] = all_stores
|
||||
if all_stores_must_succeed is not None:
|
||||
json['all_stores_must_succeed'] = all_stores_must_succeed
|
||||
data['all_stores_must_succeed'] = all_stores_must_succeed
|
||||
for s in stores:
|
||||
json.setdefault('stores', [])
|
||||
json['stores'].append(s.id)
|
||||
data.setdefault('stores', [])
|
||||
data['stores'].append(s.id)
|
||||
|
||||
headers = {}
|
||||
# Backward compat
|
||||
if store is not None:
|
||||
headers = {'X-Image-Meta-Store': store.id}
|
||||
session.post(url, json=json, headers=headers)
|
||||
|
||||
return session.post(url, json=data, headers=headers)
|
||||
|
||||
def _consume_header_attrs(self, attrs):
|
||||
self.image_import_methods = []
|
||||
|
@ -265,7 +265,7 @@ class TestImage(base.TestCase):
|
||||
def test_import_image(self):
|
||||
sot = image.Image(**EXAMPLE)
|
||||
json = {"method": {"name": "web-download", "uri": "such-a-good-uri"}}
|
||||
sot.import_image(self.sess, "web-download", "such-a-good-uri")
|
||||
sot.import_image(self.sess, "web-download", uri="such-a-good-uri")
|
||||
self.sess.post.assert_called_with(
|
||||
'images/IDENTIFIER/import',
|
||||
headers={},
|
||||
@ -293,7 +293,12 @@ class TestImage(base.TestCase):
|
||||
}
|
||||
store = mock.MagicMock()
|
||||
store.id = "ceph_1"
|
||||
sot.import_image(self.sess, "web-download", "such-a-good-uri", store)
|
||||
sot.import_image(
|
||||
self.sess,
|
||||
"web-download",
|
||||
uri="such-a-good-uri",
|
||||
store=store,
|
||||
)
|
||||
self.sess.post.assert_called_with(
|
||||
'images/IDENTIFIER/import',
|
||||
headers={'X-Image-Meta-Store': 'ceph_1'},
|
||||
@ -314,7 +319,7 @@ class TestImage(base.TestCase):
|
||||
sot.import_image(
|
||||
self.sess,
|
||||
"web-download",
|
||||
"such-a-good-uri",
|
||||
uri="such-a-good-uri",
|
||||
stores=[store],
|
||||
)
|
||||
self.sess.post.assert_called_with(
|
||||
@ -335,7 +340,7 @@ class TestImage(base.TestCase):
|
||||
sot.import_image(
|
||||
self.sess,
|
||||
"web-download",
|
||||
"such-a-good-uri",
|
||||
uri="such-a-good-uri",
|
||||
all_stores=True,
|
||||
)
|
||||
self.sess.post.assert_called_with(
|
||||
|
@ -64,12 +64,18 @@ class TestImage(TestImageProxy):
|
||||
self._verify(
|
||||
"openstack.image.v2.image.Image.import_image",
|
||||
self.proxy.import_image,
|
||||
method_args=[original_image, "method", "uri"],
|
||||
method_args=[original_image, "method"],
|
||||
method_kwargs={
|
||||
"uri": "uri",
|
||||
},
|
||||
expected_args=[self.proxy],
|
||||
expected_kwargs={
|
||||
"method": "method",
|
||||
"store": None,
|
||||
"uri": "uri",
|
||||
"remote_region": None,
|
||||
"remote_image_id": None,
|
||||
"remote_service_interface": None,
|
||||
"stores": [],
|
||||
"all_stores": None,
|
||||
"all_stores_must_succeed": None,
|
||||
|
@ -0,0 +1,12 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
The ``openstack.image.Image.import_image`` method and ``import_image``
|
||||
image proxy method now accept the following additional paramters:
|
||||
|
||||
- ``remote_region``
|
||||
- ``remote_image_id``
|
||||
- ``remote_service_interface``
|
||||
|
||||
These are required to support the ``glance-download`` image import
|
||||
method.
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
The signatures of the ``openstack.image.v2.import_image`` has changed. All
|
||||
arguments except ``image`` and ``method`` are now kwarg-only.
|
Loading…
Reference in New Issue
Block a user