本文整理汇总了Python中nectar.downloaders.threaded.HTTPThreadedDownloader.download_one方法的典型用法代码示例。如果您正苦于以下问题:Python HTTPThreadedDownloader.download_one方法的具体用法?Python HTTPThreadedDownloader.download_one怎么用?Python HTTPThreadedDownloader.download_one使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类nectar.downloaders.threaded.HTTPThreadedDownloader
的用法示例。
在下文中一共展示了HTTPThreadedDownloader.download_one方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: V2Repository
# 需要导入模块: from nectar.downloaders.threaded import HTTPThreadedDownloader [as 别名]
# 或者: from nectar.downloaders.threaded.HTTPThreadedDownloader import download_one [as 别名]
#.........这里部分代码省略.........
:return: True if the v2 API is found, else False
:rtype: bool
"""
_logger.debug('Determining if the registry URL can do v2 of the Docker API.')
try:
headers, body = self._get_path(self.API_VERSION_CHECK_PATH)
except IOError:
return False
try:
version = headers['Docker-Distribution-API-Version']
if version != "registry/2.0":
return False
_logger.debug(_('The docker registry is using API version: %(v)s') % {'v': version})
except KeyError:
# If the Docker-Distribution-API-Version header isn't present, we will assume that this
# is a valid Docker 2.0 API server so that simple file-based webservers can serve as our
# remote feed.
pass
return True
def create_blob_download_request(self, digest):
"""
Return a DownloadRequest instance for the given blob digest.
It is desirable to download the blob files with a separate
downloader (for progress tracking, etc), so we just create the download
requests here and let them get processed elsewhere.
:param digest: digest of the docker blob you wish to download
:type digest: basestring
:return: a download request instance
:rtype: nectar.request.DownloadRequest
"""
path = self.LAYER_PATH.format(name=self.name, digest=digest)
url = urlparse.urljoin(self.registry_url, path)
req = DownloadRequest(url, os.path.join(self.working_dir, digest))
return req
def get_manifest(self, reference):
"""
Get the manifest and its digest for the given reference.
:param reference: The reference (tag or digest) of the Manifest you wish to retrieve.
:type reference: basestring
:return: A 2-tuple of the digest and the manifest, both basestrings
:rtype: tuple
"""
path = self.MANIFEST_PATH.format(name=self.name, reference=reference)
headers, manifest = self._get_path(path)
digest_header = 'docker-content-digest'
if digest_header in headers:
expected_digest = headers[digest_header]
# The digest is formatted as algorithm:sum, so let's ask our hasher to use the same
# algorithm as we received in the headers.
digest = models.Manifest.calculate_digest(manifest, expected_digest.split(':')[0])
if digest != expected_digest:
msg = _('The Manifest digest does not match the expected value. The remote '
'feed announced a digest of {e}, but the downloaded digest was {d}.')
msg = msg.format(e=expected_digest, d=digest)
raise IOError(msg)
else:
digest = models.Manifest.digest(manifest)
return digest, manifest
def get_tags(self):
"""
Get a list of the available tags in the repository.
:return: A list of basestrings of the available tags in the repository.
:rtype: list
"""
path = self.TAGS_PATH.format(name=self.name)
headers, tags = self._get_path(path)
return json.loads(tags)['tags']
def _get_path(self, path):
"""
Retrieve a single path within the upstream registry, and return a 2-tuple of the headers and
the response body.
:param path: a full http path to retrieve that will be urljoin'd to the upstream registry
url.
:type path: basestring
:return: (headers, response body)
:rtype: tuple
"""
url = urlparse.urljoin(self.registry_url, path)
_logger.debug(_('Retrieving {0}'.format(url)))
request = DownloadRequest(url, StringIO())
report = self.downloader.download_one(request)
if report.state == report.DOWNLOAD_FAILED:
raise IOError(report.error_msg)
return report.headers, report.destination.getvalue()
示例2: Repository
# 需要导入模块: from nectar.downloaders.threaded import HTTPThreadedDownloader [as 别名]
# 或者: from nectar.downloaders.threaded.HTTPThreadedDownloader import download_one [as 别名]
class Repository(object):
IMAGES_PATH = '/v1/repositories/%s/images'
TAGS_PATH = '/v1/repositories/%s/tags'
ANCESTRY_PATH = '/v1/images/%s/ancestry'
DOCKER_TOKEN_HEADER = 'x-docker-token'
DOCKER_ENDPOINT_HEADER = 'x-docker-endpoints'
def __init__(self, name, download_config, registry_url, working_dir):
"""
:param name: name of a docker repository
:type name: basestring
:param download_config: download configuration object
:type download_config: nectar.config.DownloaderConfig
:param registry_url: URL for the docker registry
:type registry_url: basestring
:param working_dir: full path to the directory where files should
be saved
:type working_dir: basestring
"""
self.name = name
self.download_config = download_config
self.registry_url = registry_url
self.listener = AggregatingEventListener()
self.downloader = HTTPThreadedDownloader(self.download_config, self.listener)
self.working_dir = working_dir
self.token = None
self.endpoint = None
def _get_single_path(self, path):
"""
Retrieve a single path within the upstream registry, and return its
body after deserializing it as json
:param path: a full http path to retrieve that will be urljoin'd to the
upstream registry url.
:type path: basestring
:return: whatever gets deserialized out of the response body's json
"""
# if talking to docker hub, we'll get an endpoint specified, and then we'll have to get
# tags from that endpoint instead of talking to the original feed URL.
if self.endpoint:
# we assume the same scheme that the registry URL used
registry_url_parts = urlparse.urlsplit(self.registry_url)
parts = urlparse.SplitResult(scheme=registry_url_parts.scheme, netloc=self.endpoint,
path=path, query=None, fragment=None)
url = urlparse.urlunsplit(parts)
else:
url = urlparse.urljoin(self.registry_url, path)
request = DownloadRequest(url, StringIO())
if path.endswith('/images'):
# this is required by the docker index and indicates that it should
# return an auth token
if request.headers is None:
request.headers = {}
request.headers[self.DOCKER_TOKEN_HEADER] = 'true'
# endpoints require auth
if self.endpoint:
self.add_auth_header(request)
report = self.downloader.download_one(request)
if report.state == report.DOWNLOAD_FAILED:
raise IOError(report.error_msg)
self._parse_response_headers(report.headers)
return json.loads(report.destination.getvalue())
def _parse_response_headers(self, headers):
"""
Some responses can include header information that we need later. This
grabs those values and stores them for later use.
:param headers: dictionary-like object where keys are HTTP header names
and values are their values.
:type headers: dict
"""
# this is used for authorization on an endpoint
if self.DOCKER_TOKEN_HEADER in headers:
self.token = headers[self.DOCKER_TOKEN_HEADER]
# this tells us what host to use when accessing image files
if self.DOCKER_ENDPOINT_HEADER in headers:
self.endpoint = headers[self.DOCKER_ENDPOINT_HEADER]
def get_image_ids(self):
"""
Get a list of all images in the upstream repository. This is
conceptually a little ambiguous, as there can be images in a repo that
are neither tagged nor in the ancestry for a tagged image.
:return: list of image IDs in the repo
:rtype: list
:raises pulp_exceptions.PulpCodedException: if fetching the IDs fails
"""
path = self.IMAGES_PATH % self.name
_logger.debug('retrieving image ids from remote registry')
try:
raw_data = self._get_single_path(path)
#.........这里部分代码省略.........
示例3: V2Repository
# 需要导入模块: from nectar.downloaders.threaded import HTTPThreadedDownloader [as 别名]
# 或者: from nectar.downloaders.threaded.HTTPThreadedDownloader import download_one [as 别名]
#.........这里部分代码省略.........
def get_manifest(self, reference):
"""
Get the manifest and its digest for the given reference.
:param reference: The reference (tag or digest) of the Manifest you wish to retrieve.
:type reference: basestring
:return: A 2-tuple of the digest and the manifest, both basestrings
:rtype: tuple
"""
path = self.MANIFEST_PATH.format(name=self.name, reference=reference)
headers, manifest = self._get_path(path)
digest_header = 'docker-content-digest'
if digest_header in headers:
expected_digest = headers[digest_header]
# The digest is formatted as algorithm:sum, so let's ask our hasher to use the same
# algorithm as we received in the headers.
digest = models.Manifest.calculate_digest(manifest, expected_digest.split(':')[0])
if digest != expected_digest:
msg = _('The Manifest digest does not match the expected value. The remote '
'feed announced a digest of {e}, but the downloaded digest was {d}.')
msg = msg.format(e=expected_digest, d=digest)
raise IOError(msg)
else:
digest = models.Manifest.calculate_digest(manifest)
return digest, manifest
def get_tags(self):
"""
Get a list of the available tags in the repository.
:return: A list of basestrings of the available tags in the repository.
:rtype: list
"""
path = self.TAGS_PATH.format(name=self.name)
_logger.debug('retrieving tags from remote registry')
try:
headers, tags = self._get_path(path)
except IOError as e:
raise pulp_exceptions.PulpCodedException(error_code=error_codes.DKR1007,
repo=self.name,
registry=self.registry_url,
reason=str(e))
return json.loads(tags)['tags']
def _get_path(self, path):
"""
Retrieve a single path within the upstream registry, and return a 2-tuple of the headers and
the response body.
:param path: a full http path to retrieve that will be urljoin'd to the upstream registry
url.
:type path: basestring
:return: (headers, response body)
:rtype: tuple
"""
url = urlparse.urljoin(self.registry_url, path)
_logger.debug(_('Retrieving {0}'.format(url)))
request = DownloadRequest(url, StringIO())
if self.token:
request.headers = token_util.update_auth_header(request.headers, self.token)
report = self.downloader.download_one(request)
# If the download was unauthorized, attempt to get a token and try again
if report.state == report.DOWNLOAD_FAILED:
if report.error_report.get('response_code') == httplib.UNAUTHORIZED:
_logger.debug(_('Download unauthorized, attempting to retrieve a token.'))
self.token = token_util.request_token(self.token_downloader, request,
report.headers)
request.headers = token_util.update_auth_header(request.headers, self.token)
report = self.downloader.download_one(request)
if report.state == report.DOWNLOAD_FAILED:
self._raise_path_error(report)
return report.headers, report.destination.getvalue()
@staticmethod
def _raise_path_error(report):
"""
Raise an exception with an appropriate error message.
Specifically because docker hub responds with a 401 for repositories that don't exist, pulp
cannot disambiguate Unauthorized vs. Not Found. This function tries to make an error message
that is clear on that point.
:param report: download report
:type report: nectar.report.DownloadReport
:raises IOError: always, with an appropriate message based on the report
"""
if report.error_report.get('response_code') == httplib.UNAUTHORIZED:
# docker hub returns 401 for repos that don't exist, so we cannot disambiguate.
raise IOError(_('Unauthorized or Not Found'))
else:
raise IOError(report.error_msg)