Skip to content

Instantly share code, notes, and snippets.

@tianon
Last active August 29, 2015 14:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tianon/fbe8524bc0eb5e8ab5c2 to your computer and use it in GitHub Desktop.
Save tianon/fbe8524bc0eb5e8ab5c2 to your computer and use it in GitHub Desktop.
#!/bin/bash
set -e
# hello-world latest ef872312fe1b 3 months ago 910 B
# hello-world latest ef872312fe1bbc5e05aae626791a47ee9b032efa8f3bda39cc0be7b56bfe59b9 3 months ago 910 B
# debian latest f6fab3b798be 10 weeks ago 85.1 MB
# debian latest f6fab3b798be3174f45aa1eb731f8182705555f89c9026d8c1ef230cbf8301dd 10 weeks ago 85.1 MB
usage() {
echo "usage: $0 dir image[:tag][@image-id] ..."
echo " ie: $0 /tmp/hello-world hello-world"
echo " $0 /tmp/debian-jessie debian:jessie"
echo " $0 /tmp/old-hello-world hello-world@ef872312fe1bbc5e05aae626791a47ee9b032efa8f3bda39cc0be7b56bfe59b9"
echo " $0 /tmp/old-debian debian:latest@f6fab3b798be3174f45aa1eb731f8182705555f89c9026d8c1ef230cbf8301dd"
[ -z "$1" ] || exit "$1"
}
dir="$1" # dir for building tar in
shift || usage 1 >&2
[ $# -gt 0 -a "$dir" ] || usage 2 >&2
mkdir -p "$dir"
declare -A repositories=()
while [ $# -gt 0 ]; do
imageTag="$1"
shift
image="${imageTag%%[:@]*}"
tag="${imageTag#*:}"
imageId="${tag##*@}"
[ "$imageId" != "$tag" ] || imageId=
[ "$tag" != "$imageTag" ] || tag='latest'
tag="${tag%@*}"
token="$(curl -sSL -o /dev/null -D- -H 'X-Docker-Token: true' "https://index.docker.io/v1/repositories/$image/images" | awk -F ':[[:space:]]*|\r' '$1 == "X-Docker-Token" { print $2 }')"
if [ -z "$imageId" ]; then
imageId="$(curl -sSL -H "Authorization: Token $token" "https://registry-1.docker.io/v1/repositories/$image/tags/$tag")"
imageId="${imageId//\"/}"
fi
ancestryJson="$(curl -sSL -H "Authorization: Token $token" "https://registry-1.docker.io/v1/images/$imageId/ancestry")"
if [ "${ancestryJson:0:1}" != '[' ]; then
echo >&2 "error: /v1/images/$imageId/ancestry returned something unexpected:"
echo >&2 " $ancestryJson"
exit 1
fi
IFS=','
ancestry=( ${ancestryJson//[\[\] \"]/} )
unset IFS
[ -z "${repositories[$image]}" ] || repositories[$image]+=', '
repositories[$image]+='"'"$tag"'": "'"$imageId"'"'
echo "Downloading '$imageTag' (${#ancestry[@]} layers)..."
for imageId in "${ancestry[@]}"; do
mkdir -p "$dir/$imageId"
echo '1.0' > "$dir/$imageId/VERSION"
curl -sSL -H "Authorization: Token $token" "https://registry-1.docker.io/v1/images/$imageId/json" -o "$dir/$imageId/json" -C -
# TODO figure out why "-C -" doesn't work here
# "curl: (33) HTTP server doesn't seem to support byte ranges. Cannot resume."
# "HTTP/1.1 416 Requested Range Not Satisfiable"
if [ -f "$dir/$imageId/layer.tar" ]; then
# TODO hackpatch for no -C support :'(
echo "skipping existing ${imageId:0:12}"
continue
fi
curl -SL --progress -H "Authorization: Token $token" "https://registry-1.docker.io/v1/images/$imageId/layer" -o "$dir/$imageId/layer.tar" # -C -
done
echo
done
echo -n '{' > "$dir/repositories"
firstImage=1
for image in "${!repositories[@]}"; do
[ "$firstImage" ] || echo -n ',' >> "$dir/repositories"
firstImage=
echo -n $'\n\t' >> "$dir/repositories"
echo -n '"'"$image"'": { '"${repositories[$image]}"' }' >> "$dir/repositories"
done
echo -n $'\n}\n' >> "$dir/repositories"
echo "Download of images into '$dir' complete."
echo "Use something like the following to load the result into a Docker daemon:"
echo " tar -cC '$dir' . | docker load"
$ docker images hello-world
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
$ rm -rf temp && mkdir temp
$ ./download-frozen-image.sh temp/ hello-world
Downloading 'hello-world' (3 layers)...
######################################################################## 100.0%
######################################################################## 100.0%
######################################################################## 100.0%
Download of images into 'temp/' complete.
Use something like the following to load the result into a Docker daemon:
tar -cC 'temp/' . | docker load
$ tar -cC 'temp/' . | docker load
$ docker images hello-world
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
hello-world latest e45a5af57b00 2 weeks ago 910 B
$ docker run --rm hello-world
Hello from Docker.
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(Assuming it was not already locally available.)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
For more examples and ideas, visit:
http://docs.docker.com/userguide/
$ docker pull hello-world
hello-world:latest: The image you are pulling has been verified
511136ea3c5a: Already exists
31cbccb51277: Already exists
e45a5af57b00: Already exists
Status: Image is up to date for hello-world:latest
$ rm -rf temp && mkdir temp
$ ./download-frozen-image.sh temp $(bashbrew list debian)
Downloading 'debian:8.0' (3 layers)...
######################################################################## 100.0%
######################################################################## 100.0%
######################################################################## 100.0%
Downloading 'debian:8' (3 layers)...
skipping existing 58052b122b60
skipping existing bce696e097dc
skipping existing 511136ea3c5a
Downloading 'debian:jessie' (3 layers)...
skipping existing 58052b122b60
skipping existing bce696e097dc
skipping existing 511136ea3c5a
Downloading 'debian:oldstable' (3 layers)...
######################################################################## 100.0%
######################################################################## 100.0%
skipping existing 511136ea3c5a
Downloading 'debian:sid' (3 layers)...
######################################################################## 100.0%
######################################################################## 100.0%
skipping existing 511136ea3c5a
Downloading 'debian:6.0.10' (3 layers)...
######################################################################## 100.0%
######################################################################## 100.0%
skipping existing 511136ea3c5a
Downloading 'debian:6.0' (3 layers)...
skipping existing 3af93ba75125
skipping existing 0c232c0d0179
skipping existing 511136ea3c5a
Downloading 'debian:6' (3 layers)...
skipping existing 3af93ba75125
skipping existing 0c232c0d0179
skipping existing 511136ea3c5a
Downloading 'debian:squeeze' (3 layers)...
skipping existing 3af93ba75125
skipping existing 0c232c0d0179
skipping existing 511136ea3c5a
Downloading 'debian:stable' (3 layers)...
######################################################################## 100.0%
######################################################################## 100.0%
skipping existing 511136ea3c5a
Downloading 'debian:testing' (3 layers)...
######################################################################## 100.0%
######################################################################## 100.0%
skipping existing 511136ea3c5a
Downloading 'debian:unstable' (3 layers)...
######################################################################## 100.0%
######################################################################## 100.0%
skipping existing 511136ea3c5a
Downloading 'debian:7.8' (3 layers)...
######################################################################## 100.0%
######################################################################## 100.0%
skipping existing 511136ea3c5a
Downloading 'debian:7' (3 layers)...
skipping existing 4d6ce913b130
skipping existing d0a18d3b84de
skipping existing 511136ea3c5a
Downloading 'debian:wheezy' (3 layers)...
skipping existing 4d6ce913b130
skipping existing d0a18d3b84de
skipping existing 511136ea3c5a
Downloading 'debian:latest' (3 layers)...
skipping existing 4d6ce913b130
skipping existing d0a18d3b84de
skipping existing 511136ea3c5a
Downloading 'debian:rc-buggy' (4 layers)...
######################################################################## 100.0%
skipping existing 118c682d4e7e
skipping existing 7cfbedb09b9e
skipping existing 511136ea3c5a
Downloading 'debian:experimental' (4 layers)...
######################################################################## 100.0%
skipping existing 7b55004282c2
skipping existing 9f6f3369c683
skipping existing 511136ea3c5a
Download of images into 'temp' complete.
Use something like the following to load the result into a Docker daemon:
tar -cC 'temp' . | docker load
$ tar -cC 'temp' . | docker load
$ docker images debian
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
debian experimental a29efd117e8b 4 days ago 122.9 MB
debian rc-buggy a4868f1cbf49 4 days ago 122.9 MB
debian 7.8 4d6ce913b130 4 days ago 84.98 MB
debian wheezy 4d6ce913b130 4 days ago 84.98 MB
debian 7 4d6ce913b130 4 days ago 84.98 MB
debian latest 4d6ce913b130 4 days ago 84.98 MB
debian unstable 7b55004282c2 4 days ago 122.9 MB
debian testing 357efdf9810d 4 days ago 122.8 MB
debian stable 2b4d950d5143 4 days ago 84.98 MB
debian 6.0 3af93ba75125 4 days ago 76.61 MB
debian 6.0.10 3af93ba75125 4 days ago 76.61 MB
debian 6 3af93ba75125 4 days ago 76.61 MB
debian squeeze 3af93ba75125 4 days ago 76.61 MB
debian sid 118c682d4e7e 4 days ago 122.9 MB
debian oldstable 06725edcbde9 4 days ago 76.61 MB
debian jessie 58052b122b60 4 days ago 122.8 MB
debian 8.0 58052b122b60 4 days ago 122.8 MB
debian 8 58052b122b60 4 days ago 122.8 MB
$ du -hs temp/
331M temp/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment