Skip to content

Instantly share code, notes, and snippets.

@alexander-akhmetov
Created December 27, 2018 13:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexander-akhmetov/2fd728549deebae768305670319d8f29 to your computer and use it in GitHub Desktop.
Save alexander-akhmetov/2fd728549deebae768305670319d8f29 to your computer and use it in GitHub Desktop.
Downloads the first blob for a given image and tag from the public Docker Hub
#!/usr/bin/env python3
"""
Downloads the first blob for a given
image and tag from the public Docker Hub
"""
import argparse
import urllib.parse
import requests
DOCKERHUB_BASE_URL = 'https://registry.hub.docker.com/'
def get_auth_token(name):
"""Get token to make pull requests to Docker API"""
url = f'https://auth.docker.io/token?service=registry.docker.io&scope=repository:{name}:pull'
response = requests.get(url)
response.raise_for_status()
return response.json()['token']
def get_manifest(name, tag, token):
"""Get manifest for image 'name:tag'"""
url = _build_url(f'v2/{name}/manifests/{tag}')
response = requests.get(
url,
headers={'Authorization': f'Bearer {token}'},
)
response.raise_for_status()
return response.json()
def get_blob(name, digest, token):
"""Download a blob with specified digest"""
url = _build_url(f'/v2/{name}/blobs/{digest}')
response = requests.get(
url,
headers={'Authorization': f'Bearer {token}'},
)
response.raise_for_status()
return response.content
def _build_url(path):
return urllib.parse.urljoin(DOCKERHUB_BASE_URL, path)
if __name__ == '__main__':
default_name = 'elementsinteractive/flask-graphql-neo4j-app.dockerapp'
default_tag = '0.1.0'
parser = argparse.ArgumentParser(description='Downloads blob for a docker image')
parser.add_argument('--name', dest='name', default=default_name)
parser.add_argument('--tag', dest='tag', default=default_tag)
parser.add_argument('--output', dest='output', default='blob.tar.gz')
args = parser.parse_args()
print(f'Getting content for {args.name}:{args.tag}')
token = get_auth_token(args.name)
manifests = get_manifest(name=args.name, tag=args.tag, token=token)
digest = manifests['fsLayers'][0]['blobSum']
blob = get_blob(name=args.name, digest=digest, token=token)
with open(args.output, 'wb') as f:
f.write(blob)
print(f'File downloaded: {args.output}')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment