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)
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()
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')
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)
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
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)
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
def data(image): return glance_utils.IterableWithLength(iter("abc"), 3)
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