#!/usr/bin/env python # coding: utf-8 # In[1]: import requests import yaml # In[2]: with open(os.path.expanduser('~/dev/jpy/hub/binderhub-deploy/secret.yaml')) as f: cfg = yaml.load(f) # Load the token from binderhub-deploy yaml # In[3]: secret = cfg['binder']['registry']['password'] # Request token using basic auth # In[ ]: # In[ ]: image_name = 'binder-testing/sylvaincorlay-fly-binder' image_tag = '0c72d2e311ff441aded6994b4aad035a681e0cbc' # In[47]: def check_exists_requests(image, tag, registry='https://gcr.io'): if '://' not in registry: registry = 'https://' + registry auth_request = requests.get('{}/v2/token'.format(registry), params={'service': 'gcr.io', 'scope': 'repository:{}:pull'.format(image)}, auth=('_json_key', secret), allow_redirects=False) auth_request.raise_for_status() token = auth_request.json()['token'] r = requests.get( '{}/v2/{}/manifests/{}'.format(registry, image, tag), headers={'Authorization': 'Bearer {}'.format(token)}, ) if r.status_code == 404: # 404 means it doesn't exist and we should build it return False elif r.status_code == 200: # 200 means it does and we don't need return True else: r.raise_for_status() # if we got here, something unexpected happened raise RuntimeError("Failed to check for {}:{}: {}".format( image, tag, r, )) # In[79]: import json from tornado import gen from tornado.httputil import url_concat from tornado.httpclient import AsyncHTTPClient, HTTPRequest, HTTPError from tornado.ioloop import IOLoop loop = IOLoop() client = AsyncHTTPClient(io_loop=loop) @gen.coroutine def check_exists(image, tag, registry='https://gcr.io'): if '://' not in registry: registry = 'https://' + registry # first, get a token to perform the manifest request auth_req = HTTPRequest( url_concat('{}/v2/token'.format(registry), { 'service': 'gcr.io', 'scope': 'repository:{}:pull'.format(image), }), auth_username='_json_key', auth_password=secret, ) auth_resp = yield client.fetch(auth_req) token = json.loads(auth_resp.body.decode('utf-8', 'replace'))['token'] req = HTTPRequest( '{}/v2/{}/manifests/{}'.format(registry, image, tag), headers={'Authorization': 'Bearer {}'.format(token)}, ) try: resp = yield client.fetch(req) except HTTPError as e: if e.code == 404: # 404 means it doesn't exist return False else: raise else: return True loop.run_sync(lambda : check_exists(image_name, image_tag)) # In[80]: loop.run_sync(lambda : check_exists(image_name, image_tag)) # In[81]: loop.run_sync(lambda : check_exists(image_name, image_tag + 'x'))