Mini Shell
# 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 warnings
from openstack.cloud import exc
from openstack import exceptions
from openstack.image import _base_proxy
from openstack.image.v1 import image as _image
class Proxy(_base_proxy.BaseImageProxy):
def _create_image(self, **kwargs):
"""Create image resource from attributes
"""
return self._create(_image.Image, **kwargs)
def upload_image(self, **attrs):
"""Upload a new image from attributes
.. warning:
This method is deprecated - and also doesn't work very well.
Please stop using it immediately and switch to
`create_image`.
:param dict attrs: Keyword arguments which will be used to create
a :class:`~openstack.image.v1.image.Image`,
comprised of the properties on the Image class.
:returns: The results of image creation
:rtype: :class:`~openstack.image.v1.image.Image`
"""
warnings.warn("upload_image is deprecated. Use create_image instead.")
return self._create(_image.Image, **attrs)
def _upload_image(
self, name, filename, data, meta, wait, timeout,
use_import=False,
stores=None,
all_stores=None,
all_stores_must_succeed=None,
**image_kwargs,
):
if use_import:
raise exceptions.InvalidRequest(
"Glance v1 does not support image import")
if stores or all_stores or all_stores_must_succeed:
raise exceptions.InvalidRequest(
"Glance v1 does not support stores")
# NOTE(mordred) wait and timeout parameters are unused, but
# are present for ease at calling site.
if filename and not data:
image_data = open(filename, 'rb')
else:
image_data = data
image_kwargs['properties'].update(meta)
image_kwargs['name'] = name
# TODO(mordred) Convert this to use image Resource
image = self._connection._get_and_munchify(
'image',
self.post('/images', json=image_kwargs))
checksum = image_kwargs['properties'].get(self._IMAGE_MD5_KEY, '')
try:
# Let us all take a brief moment to be grateful that this
# is not actually how OpenStack APIs work anymore
headers = {
'x-glance-registry-purge-props': 'false',
}
if checksum:
headers['x-image-meta-checksum'] = checksum
image = self._connection._get_and_munchify(
'image',
self.put(
'/images/{id}'.format(id=image.id),
headers=headers, data=image_data))
except exc.OpenStackCloudHTTPError:
self.log.debug(
"Deleting failed upload of image %s", name)
try:
self.delete('/images/{id}'.format(id=image.id))
except exc.OpenStackCloudHTTPError:
# We're just trying to clean up - if it doesn't work - shrug
self.log.warning(
"Failed deleting image after we failed uploading it.",
exc_info=True)
raise
return self._connection._normalize_image(image)
def _update_image_properties(self, image, meta, properties):
properties.update(meta)
img_props = {}
for k, v in iter(properties.items()):
if image.properties.get(k, None) != v:
img_props['x-image-meta-{key}'.format(key=k)] = v
if not img_props:
return False
self.put(
'/images/{id}'.format(id=image.id), headers=img_props)
self._connection.list_images.invalidate(self._connection)
return True
def _existing_image(self, **kwargs):
return _image.Image.existing(connection=self._connection, **kwargs)
def delete_image(self, image, ignore_missing=True):
"""Delete an image
:param image: The value can be either the ID of an image or a
:class:`~openstack.image.v1.image.Image` instance.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be
raised when the image does not exist.
When set to ``True``, no exception will be set when
attempting to delete a nonexistent image.
:returns: ``None``
"""
self._delete(_image.Image, image, ignore_missing=ignore_missing)
def find_image(self, name_or_id, ignore_missing=True):
"""Find a single image
:param name_or_id: The name or ID of a image.
:param bool ignore_missing: When set to ``False``
:class:`~openstack.exceptions.ResourceNotFound` will be
raised when the resource does not exist.
When set to ``True``, None will be returned when
attempting to find a nonexistent resource.
:returns: One :class:`~openstack.image.v1.image.Image` or None
"""
return self._find(_image.Image, name_or_id,
ignore_missing=ignore_missing)
def get_image(self, image):
"""Get a single image
:param image: The value can be the ID of an image or a
:class:`~openstack.image.v1.image.Image` instance.
:returns: One :class:`~openstack.image.v1.image.Image`
:raises: :class:`~openstack.exceptions.ResourceNotFound`
when no resource can be found.
"""
return self._get(_image.Image, image)
def images(self, **query):
"""Return a generator of images
:param kwargs query: Optional query parameters to be sent to limit
the resources being returned.
:returns: A generator of image objects
:rtype: :class:`~openstack.image.v1.image.Image`
"""
return self._list(_image.Image, base_path='/images/detail', **query)
def update_image(self, image, **attrs):
"""Update a image
:param image: Either the ID of a image or a
:class:`~openstack.image.v1.image.Image` instance.
:attrs kwargs: The attributes to update on the image represented
by ``value``.
:returns: The updated image
:rtype: :class:`~openstack.image.v1.image.Image`
"""
return self._update(_image.Image, image, **attrs)
def download_image(self, image, stream=False, output=None,
chunk_size=1024):
"""Download an image
This will download an image to memory when ``stream=False``, or allow
streaming downloads using an iterator when ``stream=True``.
For examples of working with streamed responses, see
:ref:`download_image-stream-true`.
:param image: The value can be either the ID of an image or a
:class:`~openstack.image.v2.image.Image` instance.
:param bool stream: When ``True``, return a :class:`requests.Response`
instance allowing you to iterate over the
response data stream instead of storing its entire
contents in memory. See
:meth:`requests.Response.iter_content` for more
details. *NOTE*: If you do not consume
the entirety of the response you must explicitly
call :meth:`requests.Response.close` or otherwise
risk inefficiencies with the ``requests``
library's handling of connections.
When ``False``, return the entire
contents of the response.
:param output: Either a file object or a path to store data into.
:param int chunk_size: size in bytes to read from the wire and buffer
at one time. Defaults to 1024
:returns: When output is not given - the bytes comprising the given
Image when stream is False, otherwise a :class:`requests.Response`
instance. When output is given - a
:class:`~openstack.image.v2.image.Image` instance.
"""
image = self._get_resource(_image.Image, image)
return image.download(
self, stream=stream, output=output, chunk_size=chunk_size)
Zerion Mini Shell 1.0