Ejemplo n.º 1
0
 def get(self, context, image_id, data):
     """Get image and metadata."""
     try:
         with open(self._path_to(image_id)) as metadata_file:
             metadata = json.load(metadata_file)
         with open(self._path_to(image_id, 'image')) as image_file:
             shutil.copyfileobj(image_file, data)
     except (IOError, ValueError):
         raise exception.ImageNotFound(image_id=image_id)
     return metadata
Ejemplo n.º 2
0
def _translate_image_exception(image_id, exc_value):
    if isinstance(exc_value,
                  (glanceclient.exc.Forbidden, glanceclient.exc.Unauthorized)):
        return exception.ImageNotAuthorized(image_id=image_id)
    if isinstance(exc_value, glanceclient.exc.NotFound):
        return exception.ImageNotFound(image_id=image_id)
    if isinstance(exc_value, glanceclient.exc.BadRequest):
        return exception.ImageBadRequest(image_id=image_id,
                                         response=six.text_type(exc_value))
    return exc_value
Ejemplo n.º 3
0
 def fake_show(meh, context, id):
     if id:
         return {'id': id, 'min_disk': None, 'min_ram': None,
                 'name': 'fake_name',
                 'status': 'active',
                 'properties': {'kernel_id': 'fake_kernel_id',
                                'ramdisk_id': 'fake_ramdisk_id',
                                'something_else': 'meow'}}
     else:
         raise exception.ImageNotFound(image_id=id)
Ejemplo n.º 4
0
def _translate_image_exception(image_id, exc_type, exc_value):
    if exc_type in (glance_exception.Forbidden,
                    glance_exception.NotAuthenticated,
                    glance_exception.MissingCredentialError):
        return exception.ImageNotAuthorized(image_id=image_id)
    if exc_type is glance_exception.NotFound:
        return exception.ImageNotFound(image_id=image_id)
    if exc_type is glance_exception.Invalid:
        return exception.Invalid(exc_value)
    return exc_value
Ejemplo n.º 5
0
    def show(self,
             context,
             image_id,
             include_locations=False,
             show_deleted=True):
        """Returns a dict with image data for the given opaque image id.

        :param context: The context object to pass to image client
        :param image_id: The UUID of the image
        :param include_locations: (Optional) include locations in the returned
                                  dict of information if the image service API
                                  supports it. If the image service API does
                                  not support the locations attribute, it will
                                  still be included in the returned dict, as an
                                  empty list.
        :param show_deleted: (Optional) show the image even the status of
                             image is deleted.
        """
        version = 1
        if include_locations:
            version = 2
        try:
            image = self._client.call(context, version, 'get', image_id)
        except Exception:
            _reraise_translated_image_exception(image_id)

        if not show_deleted and getattr(image, 'deleted', False):
            raise exception.ImageNotFound(image_id=image_id)

        if not _is_image_available(context, image):
            raise exception.ImageNotFound(image_id=image_id)

        image = _translate_from_glance(image,
                                       include_locations=include_locations)
        if include_locations:
            locations = image.get('locations', None) or []
            du = image.get('direct_url', None)
            if du:
                locations.append({'url': du, 'metadata': {}})
            image['locations'] = locations

        return image
Ejemplo n.º 6
0
    def delete(self, context, image_id):
        """Delete the given image.

        :raises: ImageNotFound if the image does not exist.
        :raises: NotAuthorized if the user is not an owner.

        """
        try:
            self._client.call(context, 1, 'delete', image_id)
        except glanceclient.exc.NotFound:
            raise exception.ImageNotFound(image_id=image_id)
        return True
Ejemplo n.º 7
0
    def show(self, context, image_id):
        """Get data about specified image.

        Returns a dict containing image data for the given opaque image id.

        """
        image = self.images.get(str(image_id))
        if image:
            return copy.deepcopy(image)
        LOG.warn('Unable to find image id %s.  Have images: %s', image_id,
                 self.images)
        raise exception.ImageNotFound(image_id=image_id)
Ejemplo n.º 8
0
 def describe_image_attribute(self, context, image_id, attribute, **kwargs):
     if attribute != 'launchPermission':
         raise exception.ApiError(
             _('attribute not supported: %s') % attribute)
     try:
         image = self._get_image(context, image_id)
     except exception.NotFound:
         raise exception.ImageNotFound(image_id=image_id)
     result = {'imageId': image_id, 'launchPermission': []}
     if image['is_public']:
         result['launchPermission'].append({'group': 'all'})
     return result
Ejemplo n.º 9
0
    def show(self, context, image_id):
        """Returns a dict with image data for the given opaque image id."""
        try:
            image = self._client.call(context, 1, 'get', image_id)
        except Exception:
            _reraise_translated_image_exception(image_id)

        if not _is_image_available(context, image):
            raise exception.ImageNotFound(image_id=image_id)

        base_image_meta = _translate_from_glance(image)
        return base_image_meta
Ejemplo n.º 10
0
    def delete(self, context, image_id):
        """Delete the given image.

        :raises: ImageNotFound if the image does not exist.

        """
        # NOTE(vish): show is to check if image is available
        self.show(context, image_id)
        try:
            shutil.rmtree(self._path_to(image_id, None))
        except (IOError, ValueError):
            raise exception.ImageNotFound(image_id=image_id)
Ejemplo n.º 11
0
    def get(self, context, image_id, data):
        """Calls out to Glance for metadata and data and writes data."""
        try:
            image_meta, image_chunks = self.client.get_image(image_id)
        except glance_exception.NotFound:
            raise exception.ImageNotFound(image_id=image_id)

        for chunk in image_chunks:
            data.write(chunk)

        base_image_meta = self._translate_to_base(image_meta)
        return base_image_meta
Ejemplo n.º 12
0
    def test_get_image_meta_no_image(self):
        e = exception.ImageNotFound(image_id='fake-image')
        self.mock_image_api.get.side_effect = e

        image_meta = compute_utils.get_image_metadata(
            self.ctx, self.mock_image_api, 'fake-image', self.instance_obj)

        self.image['properties'] = 'DONTCARE'
        # NOTE(danms): The trip through system_metadata will stringify things
        for key in self.image:
            self.image[key] = str(self.image[key])
        self.assertThat(self.image, matchers.DictMatches(image_meta))
Ejemplo n.º 13
0
    def get_location(self, context, image_id):
        """Returns the direct url representing the backend storage location,
        or None if this attribute is not shown by Glance."""
        try:
            client = GlanceClientWrapper()
            image_meta = client.call(context, 2, 'get', image_id)
        except Exception:
            _reraise_translated_image_exception(image_id)

        if not self._is_image_available(context, image_meta):
            raise exception.ImageNotFound(image_id=image_id)

        return getattr(image_meta, 'direct_url', None)
Ejemplo n.º 14
0
 def show_by_name(self, context, name):
     """Returns a dict containing image data for the given name."""
     # NOTE(vish): Not very efficient, but the local image service
     #             is for testing so it should be fine.
     images = self.detail(context)
     image = None
     for cantidate in images:
         if name == cantidate.get('name'):
             image = cantidate
             break
     if image is None:
         raise exception.ImageNotFound(image_id=name)
     return image
Ejemplo n.º 15
0
    def test_get_image_meta_no_image_no_image_system_meta(self):
        e = exception.ImageNotFound(image_id='fake-image')
        self.mock_image_api.get.side_effect = e

        for k in self.instance['system_metadata'].keys():
            if k.startswith('image_'):
                del self.instance['system_metadata'][k]

        image_meta = compute_utils.get_image_metadata(
            self.ctx, self.mock_image_api, 'fake-image', self.instance_obj)

        expected = {'properties': 'DONTCARE'}
        self.assertThat(expected, matchers.DictMatches(image_meta))
Ejemplo n.º 16
0
    def delete(self, context, image_id):
        """Delete the given image.

        :raises: ImageNotFound if the image does not exist.

        """
        # NOTE(vish): show is to check if image is available
        self.show(context, image_id)
        try:
            result = self.client.delete_image(image_id)
        except glance_exception.NotFound:
            raise exception.ImageNotFound(image_id=image_id)
        return result
Ejemplo n.º 17
0
        def return_image_meta(*args, **kwargs):
            image_meta_table = {
                '2': {'id': 2, 'status': 'active', 'container_format': 'ari'},
                '155d900f-4e14-4e4c-a73d-069cbf4541e6':
                     {'id': 3, 'status': 'active', 'container_format': 'raw',
                      'properties': {'kernel_id': 1, 'ramdisk_id': 2}},
            }
            image_id = args[2]
            try:
                image_meta = image_meta_table[str(image_id)]
            except KeyError:
                raise exception.ImageNotFound(image_id=image_id)

            return image_meta
Ejemplo n.º 18
0
 def describe_images(self, context, image_id=None, **kwargs):
     # NOTE: image_id is a list!
     if image_id:
         images = []
         for ec2_id in image_id:
             try:
                 image = self._get_image(context, ec2_id)
             except exception.NotFound:
                 raise exception.ImageNotFound(image_id=ec2_id)
             images.append(image)
     else:
         images = self.image_service.detail(context)
     images = [self._format_image(i) for i in images]
     return {'imagesSet': images}
Ejemplo n.º 19
0
    def update(self, context, image_id, image_meta, data=None):
        """Replace the contents of the given image with the new data.

        :raises: ImageNotFound if the image does not exist.

        """
        # NOTE(vish): show is to check if image is available
        self.show(context, image_id)
        try:
            image_meta = self.client.update_image(image_id, image_meta, data)
        except glance_exception.NotFound:
            raise exception.ImageNotFound(image_id=image_id)

        base_image_meta = self._translate_to_base(image_meta)
        return base_image_meta
Ejemplo n.º 20
0
 def _store(self, context, image_id, metadata, data=None):
     metadata['id'] = image_id
     try:
         if data:
             location = self._path_to(image_id, 'image')
             with open(location, 'w') as image_file:
                 shutil.copyfileobj(data, image_file)
             # NOTE(vish): update metadata similarly to glance
             metadata['status'] = 'active'
             metadata['location'] = location
         with open(self._path_to(image_id), 'w') as metadata_file:
             json.dump(metadata, metadata_file)
     except (IOError, ValueError):
         raise exception.ImageNotFound(image_id=image_id)
     return metadata
Ejemplo n.º 21
0
    def test_get_image_meta_no_image_no_image_system_meta(self):
        e = exception.ImageNotFound(image_id='fake-image')
        self.mock_image_api.get.side_effect = e

        for k in self.instance_obj.system_metadata.keys():
            if k.startswith('image_'):
                del self.instance_obj.system_metadata[k]

        with mock.patch('nova.objects.Flavor.get_by_flavor_id') as get:
            get.return_value = objects.Flavor(extra_specs={})
            image_meta = compute_utils.get_image_metadata(
                self.ctx, self.mock_image_api, 'fake-image', self.instance_obj)

        expected = {'properties': 'DONTCARE'}
        self.assertThat(expected, matchers.DictMatches(image_meta))
Ejemplo n.º 22
0
def _get_locations(client, context, image_id):
    """Returns the direct url representing the backend storage location,
    or None if this attribute is not shown by Glance.
    """
    try:
        image_meta = client.call(context, 2, 'get', image_id)
    except Exception:
        _reraise_translated_image_exception(image_id)

    if not _is_image_available(context, image_meta):
        raise exception.ImageNotFound(image_id=image_id)

    locations = getattr(image_meta, 'locations', [])
    du = getattr(image_meta, 'direct_url', None)
    if du:
        locations.append({'url': du, 'metadata': {}})
    return locations
Ejemplo n.º 23
0
    def delete(self, context, image_id):
        """Delete the given image.

        :raises: ImageNotFound if the image does not exist.
        :raises: NotAuthorized if the user is not an owner.
        :raises: ImageNotAuthorized if the user is not authorized.
        :raises: ImageDeleteConflict if the image is conflicted to delete.

        """
        try:
            self._client.call(context, 2, 'delete', image_id)
        except glanceclient.exc.NotFound:
            raise exception.ImageNotFound(image_id=image_id)
        except glanceclient.exc.HTTPForbidden:
            raise exception.ImageNotAuthorized(image_id=image_id)
        except glanceclient.exc.HTTPConflict as exc:
            raise exception.ImageDeleteConflict(reason=six.text_type(exc))
        return True
Ejemplo n.º 24
0
    def update(self, context, image_id, metadata, data=None,
               purge_props=False):
        """Replace the contents of the given image with the new data.

        :raises: ImageNotFound if the image does not exist.

        """
        if not self.images.get(image_id):
            raise exception.ImageNotFound(image_id=image_id)
        if purge_props:
            self.images[image_id] = copy.deepcopy(metadata)
        else:
            image = self.images[image_id]
            try:
                image['properties'].update(metadata.pop('properties'))
            except KeyError:
                pass
            image.update(metadata)
        return self.images[image_id]
    def test_resize_with_image_exceptions(self):
        body = dict(resize=dict(flavorRef="http://localhost/3"))
        self.resize_called = 0
        image_id = 'fake_image_id'

        exceptions = [
            (exception.ImageNotAuthorized(image_id=image_id),
             webob.exc.HTTPUnauthorized),
            (exception.ImageNotFound(image_id=image_id),
             webob.exc.HTTPBadRequest),
            (exception.Invalid, webob.exc.HTTPBadRequest),
            (exception.NoValidHost(reason='Bad host'),
             webob.exc.HTTPBadRequest),
            (exception.AutoDiskConfigDisabledByImage(image=image_id),
             webob.exc.HTTPBadRequest),
        ]

        raised, expected = map(iter, zip(*exceptions))

        def _fake_resize(obj, context, instance, flavor_id):
            self.resize_called += 1
            raise raised.next()

        self.stubs.Set(compute_api.API, 'resize', _fake_resize)

        for call_no in range(len(exceptions)):
            req = fakes.HTTPRequestV3.blank(self.url)
            next_exception = expected.next()
            actual = self.assertRaises(next_exception,
                                       self.controller._action_resize,
                                       req,
                                       FAKE_UUID,
                                       body=body)
            if (isinstance(exceptions[call_no][0], exception.NoValidHost)):
                self.assertEqual(actual.explanation,
                                 'No valid host was found. Bad host')
            elif (isinstance(exceptions[call_no][0],
                             exception.AutoDiskConfigDisabledByImage)):
                self.assertEqual(
                    actual.explanation,
                    'Requested image fake_image_id has automatic'
                    ' disk resize disabled.')
            self.assertEqual(self.resize_called, call_no + 1)
Ejemplo n.º 26
0
    def get(self, context, image_id, data):
        """Calls out to Glance for metadata and data and writes data."""
        num_retries = FLAGS.glance_num_retries
        for count in xrange(1 + num_retries):
            client = self._get_client(context)
            try:
                image_meta, image_chunks = client.get_image(image_id)
                break
            except glance_exception.NotFound:
                raise exception.ImageNotFound(image_id=image_id)
            except Exception:
                if count == num_retries:
                    raise
            time.sleep(1)

        for chunk in image_chunks:
            data.write(chunk)

        base_image_meta = self._translate_from_glance(image_meta)
        return base_image_meta
Ejemplo n.º 27
0
    def upload_image(self, context, session, instance, image_id, vdi_uuids):
        params = {'vdi_uuids': vdi_uuids}
        props = params['properties'] = {}
        props['auto_disk_config'] = instance['auto_disk_config']
        props['os_type'] = instance.get(
            'os_type', None) or (CONF.xenserver.default_os_type)

        compression_level = vm_utils.get_compression_level()
        if compression_level:
            props['xenapi_image_compression_level'] = compression_level

        auto_disk_config = utils.get_auto_disk_config_from_instance(instance)
        if utils.is_auto_disk_config_disabled(auto_disk_config):
            props["auto_disk_config"] = "disabled"

        try:
            self._call_glance_plugin(context, instance, session,
                                     host_glance.upload_vhd, image_id, params)
        except xenapi_exception.PluginRetriesExceeded:
            raise exception.CouldNotUploadImage(image_id=image_id)
        except xenapi_exception.PluginImageNotFound:
            raise exception.ImageNotFound(image_id=image_id)
Ejemplo n.º 28
0
    def update(self, context, image_id, metadata, data=None, headers=None):
        """Replace the contents of the given image with the new data.

        :raises: ImageNotFound if the image does not exist.

        """
        if not self.images.get(image_id):
            raise exception.ImageNotFound(image_id=image_id)
        try:
            purge = headers['x-glance-registry-purge-props']
        except Exception:
            purge = True
        if purge:
            self.images[image_id] = copy.deepcopy(metadata)
        else:
            image = self.images[image_id]
            try:
                image['properties'].update(metadata.pop('properties'))
            except Exception:
                pass
            image.update(metadata)
        return self.images[image_id]
Ejemplo n.º 29
0
    def modify_image_attribute(self, context, image_id, attribute,
                               operation_type, **kwargs):
        # TODO(devcamcar): Support users and groups other than 'all'.
        if attribute != 'launchPermission':
            raise exception.ApiError(
                _('attribute not supported: %s') % attribute)
        if not 'user_group' in kwargs:
            raise exception.ApiError(_('user or group not specified'))
        if len(kwargs['user_group']) != 1 and kwargs['user_group'][0] != 'all':
            raise exception.ApiError(_('only group "all" is supported'))
        if not operation_type in ['add', 'remove']:
            raise exception.ApiError(_('operation_type must be add or remove'))
        LOG.audit(_("Updating image %s publicity"), image_id, context=context)

        try:
            image = self._get_image(context, image_id)
        except exception.NotFound:
            raise exception.ImageNotFound(image_id=image_id)
        internal_id = image['id']
        del (image['id'])

        image['is_public'] = (operation_type == 'add')
        return self.image_service.update(context, internal_id, image)
Ejemplo n.º 30
0
 def fake_show(ctx, image_id):
     raise exception.ImageNotFound(image_id='fake-image')