def registry_get(self, api): url = "https://%s/v2/%s" % (self.registry, api) response = get( url, auth=(self.user, self.password), headers={ "Accept": 'application/vnd.docker.distribution.manifest.v2+json' }, verify=self.verify) if response.status_code == 401: challenge = response.headers['Www-Authenticate'] if challenge.startswith("Bearer "): challenge = challenge[7:] opts = urllib2.parse_keqv_list(urllib2.parse_http_list(challenge)) authresp = get( "{realm}?service={service}&scope={scope}".format(**opts), auth=(self.user, self.password), verify=self.verify) if authresp.ok: token = authresp.json()['token'] response = get(url, headers={'Authorization': 'Bearer %s' % token}, verify=self.verify) else: raise TaskError( "problem authenticating with docker registry: [%s] %s" % (authresp.status_code, authresp.content)) return response
def __init__(self, registry, namespace, user, password, verify=True): DockerBase.__init__(self) self.registry = registry self.namespace = namespace self.user = user self.password = password self.verify = verify self._run_login = bool(self.user) if not self.user: docker_config = os.path.join(os.environ.get("HOME"), ".docker/config.json") if os.path.exists(docker_config): with open(docker_config) as fd: cfg = json.load(fd) auths = cfg.get("auths", {}) auth = auths.get(self.registry, {}).get("auth") if auth: self.user, self.password = base64.decodestring( auth).split(":") if not self._run_login and not self.user: raise TaskError( "unable to locate docker credentials, please run `docker login %s`" % self.registry)
def remote_exists(self, name, version): img = image(self.registry, self.namespace, name, version) if img in self.image_cache: return self.image_cache[img] response = self.repo_get(name, "manifests/%s" % version) result = response.json() if 'signatures' in result and 'fsLayers' in result: self.image_cache[img] = True return True elif 'errors' in result and result['errors']: if result['errors'][0]['code'] == 'MANIFEST_UNKNOWN': self.image_cache[img] = False return False raise TaskError(response.content)
def remote_exists(self, name, version): self._login() img = self.image(name, version) if img in self.image_cache: return self.image_cache[img] response = self.repo_get(name, "manifests/%s" % version) result = response.json() # v1 and v2 manifest schemas look a bit different if 'fsLayers' in result or 'layers' in result: self.image_cache[img] = True return True elif 'errors' in result and result['errors']: if result['errors'][0]['code'] in ('MANIFEST_UNKNOWN', 'NAME_UNKNOWN'): self.image_cache[img] = False return False raise TaskError(response.content)