import requests
import yaml
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
secret = cfg['binder']['registry']['password']
Request token using basic auth
image_name = 'binder-testing/sylvaincorlay-fly-binder'
image_tag = '0c72d2e311ff441aded6994b4aad035a681e0cbc'
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,
))
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))
True
loop.run_sync(lambda : check_exists(image_name, image_tag))
True
loop.run_sync(lambda : check_exists(image_name, image_tag + 'x'))
False