Example #1
0
 def test_get_glance_image_service(self, glance_service_mock, session_mock):
     image_href = 'image-uuid'
     self.context.auth_token = 'fake'
     image_service.get_image_service(image_href, context=self.context)
     glance_service_mock.assert_called_once_with(mock.ANY, None, 1,
                                                 self.context)
     self.assertFalse(session_mock.called)
Example #2
0
 def test_get_glance_image_service(self, glance_service_mock, token_mock):
     image_href = 'image-uuid'
     self.context.auth_token = 'fake'
     image_service.get_image_service(image_href, context=self.context)
     glance_service_mock.assert_called_once_with(mock.ANY, None, 1,
                                                 self.context)
     self.assertFalse(token_mock.called)
Example #3
0
 def test_get_glance_image_service_default_v1(self, glance_service_mock,
                                              session_mock):
     self.config(glance_api_version=1, group='glance')
     image_href = 'image-uuid'
     self.context.auth_token = 'fake'
     image_service.get_image_service(image_href, context=self.context)
     glance_service_mock.assert_called_once_with(mock.ANY, None, 1,
                                                 self.context)
     self.assertFalse(session_mock.called)
Example #4
0
 def test_get_glance_image_service_default_v1(self, glance_service_mock,
                                              session_mock):
     self.config(glance_api_version=1, group='glance')
     image_href = 'image-uuid'
     self.context.auth_token = 'fake'
     image_service.get_image_service(image_href, context=self.context)
     glance_service_mock.assert_called_once_with(mock.ANY, None, 1,
                                                 self.context)
     self.assertFalse(session_mock.called)
Example #5
0
 def test_get_glance_image_service_no_token(self, glance_service_mock,
                                            token_mock):
     image_href = 'image-uuid'
     self.context.auth_token = None
     token_mock.return_value = 'admin-token'
     image_service.get_image_service(image_href, context=self.context)
     glance_service_mock.assert_called_once_with(mock.ANY, None, 1,
                                                 self.context)
     token_mock.assert_called_once_with()
     self.assertEqual('admin-token', self.context.auth_token)
Example #6
0
 def test_get_glance_image_service_no_token(self, glance_service_mock,
                                            token_mock):
     image_href = 'image-uuid'
     self.context.auth_token = None
     token_mock.return_value = 'admin-token'
     image_service.get_image_service(image_href, context=self.context)
     glance_service_mock.assert_called_once_with(mock.ANY, None, 1,
                                                 self.context)
     token_mock.assert_called_once_with()
     self.assertEqual('admin-token', self.context.auth_token)
Example #7
0
 def test_get_glance_image_service_token_not_needed(self,
                                                    glance_service_mock,
                                                    session_mock):
     image_href = 'image-uuid'
     self.context.auth_token = None
     self.config(auth_strategy='noauth', group='glance')
     image_service.get_image_service(image_href, context=self.context)
     glance_service_mock.assert_called_once_with(mock.ANY, None, 1,
                                                 self.context)
     self.assertFalse(session_mock.called)
     self.assertIsNone(self.context.auth_token)
Example #8
0
 def test_get_glance_image_service_token_not_needed(self,
                                                    glance_service_mock,
                                                    token_mock):
     image_href = 'image-uuid'
     self.context.auth_token = None
     self.config(auth_strategy='noauth', group='glance')
     image_service.get_image_service(image_href, context=self.context)
     glance_service_mock.assert_called_once_with(mock.ANY, None, 1,
                                                 self.context)
     self.assertFalse(token_mock.called)
     self.assertIsNone(self.context.auth_token)
Example #9
0
def _delete_master_path_if_stale(master_path, href, ctx):
    """Delete image from cache if it is not up to date with href contents.

    :param master_path: path to an image in master cache
    :param href: image href
    :param ctx: context to use
    :returns: True if master_path is up to date with href contents,
        False if master_path was stale and was deleted or it didn't exist
    """
    if service_utils.is_glance_image(href):
        # Glance image contents cannot be updated without changing image's UUID
        return os.path.exists(master_path)
    if os.path.exists(master_path):
        img_service = image_service.get_image_service(href, context=ctx)
        img_mtime = img_service.show(href).get('updated_at')
        if not img_mtime:
            # This means that href is not a glance image and doesn't have an
            # updated_at attribute
            LOG.warning("Image service couldn't determine last "
                        "modification time of %(href)s, considering "
                        "cached image up to date.", {'href': href})
            return True
        master_mtime = utils.unix_file_modification_datetime(master_path)
        if img_mtime <= master_mtime:
            return True
        # Delete image from cache as it is outdated
        LOG.info('Image %(href)s was last modified at %(remote_time)s. '
                 'Deleting the cached copy "%(cached_file)s since it was '
                 'last modified at %(local_time)s and may be outdated.',
                 {'href': href, 'remote_time': img_mtime,
                  'local_time': master_mtime, 'cached_file': master_path})

        os.unlink(master_path)
    return False
Example #10
0
def _delete_master_path_if_stale(master_path, href, ctx):
    """Delete image from cache if it is not up to date with href contents.

    :param master_path: path to an image in master cache
    :param href: image href
    :param ctx: context to use
    :returns: True if master_path is up to date with href contents,
        False if master_path was stale and was deleted or it didn't exist
    """
    if service_utils.is_glance_image(href):
        # Glance image contents cannot be updated without changing image's UUID
        return os.path.exists(master_path)
    if os.path.exists(master_path):
        img_service = image_service.get_image_service(href, context=ctx)
        img_mtime = img_service.show(href).get('updated_at')
        if not img_mtime:
            # This means that href is not a glance image and doesn't have an
            # updated_at attribute
            LOG.warn(_LW("Image service couldn't determine last "
                         "modification time of %(href)s, considering "
                         "cached image up to date."), {'href': href})
            return True
        master_mtime = utils.unix_file_modification_datetime(master_path)
        if img_mtime <= master_mtime:
            return True
        # Delete image from cache as it is outdated
        LOG.info(_LI('Image %(href)s was last modified at %(remote_time)s. '
                     'Deleting the cached copy "%(cached_file)s since it was '
                     'last modified at %(local_time)s and may be outdated.'),
                 {'href': href, 'remote_time': img_mtime,
                  'local_time': master_mtime, 'cached_file': master_path})

        os.unlink(master_path)
    return False
Example #11
0
def fetch_into(context, image_href, image_file):
    # TODO(vish): Improve context handling and add owner and auth data
    #             when it is added to glance.  Right now there is no
    #             auth checking in glance, so we assume that access was
    #             checked before we got here.
    image_service = service.get_image_service(image_href, context=context)
    LOG.debug("Using %(image_service)s to download image %(image_href)s.", {
        'image_service': image_service.__class__,
        'image_href': image_href
    })

    image_service.download(image_href, image_file)
Example #12
0
def validate_image_properties(ctx, deploy_info, properties):
    """Validate the image.

    For Glance images it checks that the image exists in Glance and its
    properties or deployment info contain the properties passed. If it's not a
    Glance image, it checks that deployment info contains needed properties.

    :param ctx: security context
    :param deploy_info: the deploy_info to be validated
    :param properties: the list of image meta-properties to be validated.
    :raises: InvalidParameterValue if:
        * connection to glance failed;
        * authorization for accessing image failed;
        * HEAD request to image URL failed or returned response code != 200;
        * HEAD request response does not contain Content-Length header;
        * the protocol specified in image URL is not supported.
    :raises: MissingParameterValue if the image doesn't contain
        the mentioned properties.
    """
    image_href = deploy_info['image_source']
    try:
        img_service = image_service.get_image_service(image_href, context=ctx)
        image_props = img_service.show(image_href)['properties']
    except (exception.GlanceConnectionFailed, exception.ImageNotAuthorized,
            exception.Invalid):
        raise exception.InvalidParameterValue(
            _("Failed to connect to Glance to get the properties "
              "of the image %s") % image_href)
    except exception.ImageNotFound:
        raise exception.InvalidParameterValue(
            _("Image %s can not be found.") % image_href)
    except exception.ImageRefValidationFailed as e:
        raise exception.InvalidParameterValue(e)

    missing_props = []
    for prop in properties:
        if not (deploy_info.get(prop) or image_props.get(prop)):
            missing_props.append(prop)

    if missing_props:
        props = ', '.join(missing_props)
        raise exception.MissingParameterValue(
            _("Image %(image)s is missing the following properties: "
              "%(properties)s") % {
                  'image': image_href,
                  'properties': props
              })
Example #13
0
def fetch(context, image_href, path, force_raw=False):
    # TODO(vish): Improve context handling and add owner and auth data
    #             when it is added to glance.  Right now there is no
    #             auth checking in glance, so we assume that access was
    #             checked before we got here.
    image_service = service.get_image_service(image_href,
                                              context=context)
    LOG.debug("Using %(image_service)s to download image %(image_href)s." %
              {'image_service': image_service.__class__,
               'image_href': image_href})

    with fileutils.remove_path_on_error(path):
        with open(path, "wb") as image_file:
            image_service.download(image_href, image_file)

    if force_raw:
        image_to_raw(image_href, path, "%s.part" % path)
Example #14
0
def fetch(context, image_href, path, force_raw=False):
    # TODO(vish): Improve context handling and add owner and auth data
    #             when it is added to glance.  Right now there is no
    #             auth checking in glance, so we assume that access was
    #             checked before we got here.
    image_service = service.get_image_service(image_href, context=context)
    LOG.debug("Using %(image_service)s to download image %(image_href)s.", {
        'image_service': image_service.__class__,
        'image_href': image_href
    })

    with fileutils.remove_path_on_error(path):
        with open(path, "wb") as image_file:
            image_service.download(image_href, image_file)

    if force_raw:
        image_to_raw(image_href, path, "%s.part" % path)
Example #15
0
def validate_image_properties(ctx, deploy_info, properties):
    """Validate the image.

    For Glance images it checks that the image exists in Glance and its
    properties or deployment info contain the properties passed. If it's not a
    Glance image, it checks that deployment info contains needed properties.

    :param ctx: security context
    :param deploy_info: the deploy_info to be validated
    :param properties: the list of image meta-properties to be validated.
    :raises: InvalidParameterValue if:
        * connection to glance failed;
        * authorization for accessing image failed;
        * HEAD request to image URL failed or returned response code != 200;
        * HEAD request response does not contain Content-Length header;
        * the protocol specified in image URL is not supported.
    :raises: MissingParameterValue if the image doesn't contain
        the mentioned properties.
    """
    image_href = deploy_info['image_source']
    try:
        img_service = image_service.get_image_service(image_href, context=ctx)
        image_props = img_service.show(image_href)['properties']
    except (exception.GlanceConnectionFailed,
            exception.ImageNotAuthorized,
            exception.Invalid):
        raise exception.InvalidParameterValue(_(
            "Failed to connect to Glance to get the properties "
            "of the image %s") % image_href)
    except exception.ImageNotFound:
        raise exception.InvalidParameterValue(_(
            "Image %s can not be found.") % image_href)
    except exception.ImageRefValidationFailed as e:
        raise exception.InvalidParameterValue(e)

    missing_props = []
    for prop in properties:
        if not (deploy_info.get(prop) or image_props.get(prop)):
            missing_props.append(prop)

    if missing_props:
        props = ', '.join(missing_props)
        raise exception.MissingParameterValue(_(
            "Image %(image)s is missing the following properties: "
            "%(properties)s") % {'image': image_href, 'properties': props})
Example #16
0
def get_image_properties(context, image_href, properties="all"):
    """Returns the values of several properties of an image

    :param context: context
    :param image_href: href of the image
    :param properties: the properties whose values are required.
        This argument is optional, default value is "all", so if not specified
        all properties will be returned.
    :returns: a dict of the values of the properties. A property not on the
        glance metadata will have a value of None.
    """
    img_service = service.get_image_service(image_href, context=context)
    iproperties = img_service.show(image_href)['properties']

    if properties == "all":
        return iproperties

    return {p: iproperties.get(p) for p in properties}
Example #17
0
def get_image_properties(context, image_href, properties="all"):
    """Returns the values of several properties of an image

    :param context: context
    :param image_href: href of the image
    :param properties: the properties whose values are required.
        This argument is optional, default value is "all", so if not specified
        all properties will be returned.
    :returns: a dict of the values of the properties. A property not on the
        glance metadata will have a value of None.
    """
    img_service = service.get_image_service(image_href, context=context)
    iproperties = img_service.show(image_href)['properties']

    if properties == "all":
        return iproperties

    return {p: iproperties.get(p) for p in properties}
Example #18
0
 def test_get_glance_image_service_url(self, glance_service_mock):
     image_href = 'glance://image-uuid'
     image_service.get_image_service(image_href, context=self.context)
     glance_service_mock.assert_called_once_with(mock.ANY, None, 1,
                                                 self.context)
 def test_get_glance_image_service_url(self, glance_service_mock):
     image_href = 'glance://%s' % uuidutils.generate_uuid()
     image_service.get_image_service(image_href, context=self.context)
     glance_service_mock.assert_called_once_with(mock.ANY, None,
                                                 self.context)
Example #20
0
def download_size(context, image_href, image_service=None):
    if not image_service:
        image_service = service.get_image_service(image_href, context=context)
    return image_service.show(image_href)['size']
Example #21
0
def image_show(context, image_href, image_service=None):
    if image_service is None:
        image_service = service.get_image_service(image_href, context=context)
    return image_service.show(image_href)
Example #22
0
 def test_get_https_image_service(self, http_service_mock):
     image_href = 'https://127.0.0.1/image.qcow2'
     image_service.get_image_service(image_href)
     http_service_mock.assert_called_once_with()
Example #23
0
 def test_get_file_image_service(self, local_service_mock):
     image_href = 'file:///home/user/image.qcow2'
     image_service.get_image_service(image_href)
     local_service_mock.assert_called_once_with()
Example #24
0
 def test_get_glance_image_service_url(self, glance_service_mock):
     image_href = 'glance://image-uuid'
     image_service.get_image_service(image_href, context=self.context)
     glance_service_mock.assert_called_once_with(mock.ANY, None, 1,
                                                 self.context)
Example #25
0
def download_size(context, image_href, image_service=None):
    if not image_service:
        image_service = service.get_image_service(image_href, context=context)
    return image_service.show(image_href)["size"]
Example #26
0
def image_show(context, image_href, image_service=None):
    if image_service is None:
        image_service = service.get_image_service(image_href, context=context)
    return image_service.show(image_href)
Example #27
0
 def test_get_file_image_service(self, local_service_mock):
     image_href = 'file:///home/user/image.qcow2'
     image_service.get_image_service(image_href)
     local_service_mock.assert_called_once_with()
Example #28
0
 def test_get_https_image_service(self, http_service_mock):
     image_href = 'https://127.0.0.1/image.qcow2'
     image_service.get_image_service(image_href)
     http_service_mock.assert_called_once_with()
Example #29
0
 def test_get_glance_image_service_url(self, glance_service_mock):
     image_href = 'glance://%s' % uuidutils.generate_uuid()
     image_service.get_image_service(image_href, context=self.context)
     glance_service_mock.assert_called_once_with(mock.ANY, None,
                                                 self.context)
Example #30
0
 def test_get_glance_image_service_default_v1(self, glance_service_mock):
     self.config(glance_api_version=1, group='glance')
     image_href = uuidutils.generate_uuid()
     image_service.get_image_service(image_href, context=self.context)
     glance_service_mock.assert_called_once_with(mock.ANY, None, 1,
                                                 self.context)