Ejemplo n.º 1
0
    def download_blob(self,
                      artifact_id,
                      blob_property,
                      position=None,
                      type_name=None,
                      type_version=None,
                      do_checksum=True):
        """Get blob data.

        :param artifact_id: ID of the artifact to download a blob
        :param blob_property: blob property name
        :param position: if blob_property is a list then the
        position must be specified
        :param do_checksum: Enable/disable checksum validation.
        """
        type_name, type_version = self._check_type_params(
            type_name, type_version)
        url = '/v3/artifacts/%s/v%s/%s/%s' % (type_name, type_version,
                                              artifact_id, blob_property)
        if position:
            url += '/%s' % position

        url += '/download'

        resp, body = self.http_client.get(url)
        checksum = resp.headers.get('content-md5', None)
        content_length = int(resp.headers.get('content-length', 0))

        if checksum is not None and do_checksum:
            body = utils.integrity_iter(body, checksum)

        return utils.IterableWithLength(body, content_length)
Ejemplo n.º 2
0
    def test_iterable_closes(self):
        # Regression test for bug 1461678.
        def _iterate(i):
            for chunk in i:
                raise (IOError)

        data = six.moves.StringIO('somestring')
        data.close = mock.Mock()
        i = utils.IterableWithLength(data, 10)
        self.assertRaises(IOError, _iterate, i)
        data.close.assert_called_with()
Ejemplo n.º 3
0
    def test_image_download(self):
        args = self._make_args(
            {'id': 'IMG-01', 'file': 'test', 'progress': True})

        with mock.patch.object(self.gc.images, 'data') as mocked_data:
            def _data():
                for c in 'abcedf':
                    yield c
            mocked_data.return_value = utils.IterableWithLength(_data(), 5)

            test_shell.do_image_download(self.gc, args)
            mocked_data.assert_called_once_with('IMG-01')
Ejemplo n.º 4
0
    def data(self, image_id, do_checksum=True):
        """Retrieve data of an image.

        :param image_id:    ID of the image to download.
        :param do_checksum: Enable/disable checksum validation.
        """
        url = '/v2/images/%s/file' % image_id
        resp, body = self.http_client.get(url)
        checksum = resp.headers.get('content-md5', None)
        content_length = int(resp.headers.get('content-length', 0))

        if do_checksum and checksum is not None:
            body = utils.integrity_iter(body, checksum)

        return utils.IterableWithLength(body, content_length)
Ejemplo n.º 5
0
 def test_iter_iterator_display_progress_bar(self):
     size = 100
     # create fake response object to return request-id with iterator
     resp = requests.Response()
     resp.headers['x-openstack-request-id'] = 'req-1234'
     iterator_with_len = utils.IterableWithLength(iter('X' * 100), size)
     requestid_proxy = utils.RequestIdProxy((iterator_with_len, resp))
     saved_stdout = sys.stdout
     try:
         sys.stdout = output = test_utils.FakeTTYStdout()
         # Consume iterator.
         data = list(
             progressbar.VerboseIteratorWrapper(requestid_proxy, size))
         self.assertEqual(['X'] * 100, data)
         self.assertEqual('[%s>] 100%%\n' % ('=' * 29), output.getvalue())
     finally:
         sys.stdout = saved_stdout
Ejemplo n.º 6
0
    def data(self, image, do_checksum=True, **kwargs):
        """Get the raw data for a specific image.

        :param image: image object or id to look up
        :param do_checksum: Enable/disable checksum validation
        :rtype: iterable containing image data
        """
        image_id = base.getid(image)
        resp, body = self.client.get('/v1/images/%s' %
                                     urlparse.quote(str(image_id)))
        content_length = int(resp.headers.get('content-length', 0))
        checksum = resp.headers.get('x-image-meta-checksum', None)
        if do_checksum and checksum is not None:
            body = utils.integrity_iter(body, checksum)
        return_request_id = kwargs.get('return_req_id', None)
        if return_request_id is not None:
            return_request_id.append(resp.headers.get(OS_REQ_ID_HDR, None))

        return utils.IterableWithLength(body, content_length)
Ejemplo n.º 7
0
    def data(self, image_id, do_checksum=True):
        """Retrieve data of an image.

        :param image_id:    ID of the image to download.
        :param do_checksum: Enable/disable checksum validation.
        :returns: An iterable body or None
        """
        url = '/v2/images/%s/file' % image_id
        resp, body = self.http_client.get(url)
        if resp.status_code == codes.no_content:
            LOG.error(
                "Got no content from url: %s. "
                "Request returned failure status %s.", url, resp.status_code)
            return None, resp

        checksum = resp.headers.get('content-md5', None)
        content_length = int(resp.headers.get('content-length', 0))

        if do_checksum and checksum is not None:
            body = utils.integrity_iter(body, checksum)

        return utils.IterableWithLength(body, content_length), resp
Ejemplo n.º 8
0
 def data(image):
     return glance_utils.IterableWithLength(iter("abc"), 3)
Ejemplo n.º 9
0
    def data(self, image_id, do_checksum=True, allow_md5_fallback=False):
        """Retrieve data of an image.

        When do_checksum is enabled, validation proceeds as follows:

        1. if the image has a 'os_hash_value' property, the algorithm
           specified in the image's 'os_hash_algo' property will be used
           to validate against the 'os_hash_value' value.  If the
           specified hash algorithm is not available AND allow_md5_fallback
           is True, then continue to step #2
        2. else if the image has a checksum property, MD5 is used to
           validate against the 'checksum' value.  (If MD5 is not available
           to the client, the download fails.)
        3. else if the download response has a 'content-md5' header, MD5
           is used to validate against the header value.  (If MD5 is not
           available to the client, the download fails.)
        4. if none of 1-3 obtain, the data is **not validated** (this is
           compatible with legacy behavior)

        :param image_id:    ID of the image to download
        :param do_checksum: Enable/disable checksum validation
        :param allow_md5_fallback:
            Use the MD5 checksum for validation if the algorithm specified by
            the image's 'os_hash_algo' property is not available
        :returns: An iterable body or ``None``
        """
        if do_checksum:
            # doing this first to prevent race condition if image record
            # is deleted during the image download
            url = '/v2/images/%s' % image_id
            resp, image_meta = self.http_client.get(url)
            meta_checksum = image_meta.get('checksum', None)
            meta_hash_value = image_meta.get('os_hash_value', None)
            meta_hash_algo = image_meta.get('os_hash_algo', None)

        url = '/v2/images/%s/file' % image_id
        resp, body = self.http_client.get(url)
        if resp.status_code == codes.no_content:
            return None, resp

        checksum = resp.headers.get('content-md5', None)
        content_length = int(resp.headers.get('content-length', 0))

        check_md5sum = do_checksum
        if do_checksum and meta_hash_value is not None:
            try:
                hasher = hashlib.new(str(meta_hash_algo))
                body = utils.serious_integrity_iter(body,
                                                    hasher,
                                                    meta_hash_value)
                check_md5sum = False
            except ValueError as ve:
                if (str(ve).startswith('unsupported hash type') and
                        allow_md5_fallback):
                    check_md5sum = True
                else:
                    raise

        if do_checksum and check_md5sum:
            if meta_checksum is not None:
                body = utils.integrity_iter(body, meta_checksum)
            elif checksum is not None:
                body = utils.integrity_iter(body, checksum)
            else:
                # NOTE(rosmaita): this preserves legacy behavior to return the
                # image data when checksumming is requested but there's no
                # 'content-md5' header in the response.  Just want to make it
                # clear that we're doing this on purpose.
                pass

        return utils.IterableWithLength(body, content_length), resp