github.com/campoy/docker@v1.8.0-rc1/contrib/download-frozen-image.sh (about)

     1  #!/bin/bash
     2  set -e
     3  
     4  # hello-world                      latest              ef872312fe1b        3 months ago        910 B
     5  # hello-world                      latest              ef872312fe1bbc5e05aae626791a47ee9b032efa8f3bda39cc0be7b56bfe59b9   3 months ago        910 B
     6  
     7  # debian                           latest              f6fab3b798be        10 weeks ago        85.1 MB
     8  # debian                           latest              f6fab3b798be3174f45aa1eb731f8182705555f89c9026d8c1ef230cbf8301dd   10 weeks ago        85.1 MB
     9  
    10  if ! command -v curl &> /dev/null; then
    11  	echo >&2 'error: "curl" not found!'
    12  	exit 1
    13  fi
    14  
    15  usage() {
    16  	echo "usage: $0 dir image[:tag][@image-id] ..."
    17  	echo "   ie: $0 /tmp/hello-world hello-world"
    18  	echo "       $0 /tmp/debian-jessie debian:jessie"
    19  	echo "       $0 /tmp/old-hello-world hello-world@ef872312fe1bbc5e05aae626791a47ee9b032efa8f3bda39cc0be7b56bfe59b9"
    20  	echo "       $0 /tmp/old-debian debian:latest@f6fab3b798be3174f45aa1eb731f8182705555f89c9026d8c1ef230cbf8301dd"
    21  	[ -z "$1" ] || exit "$1"
    22  }
    23  
    24  dir="$1" # dir for building tar in
    25  shift || usage 1 >&2
    26  
    27  [ $# -gt 0 -a "$dir" ] || usage 2 >&2
    28  mkdir -p "$dir"
    29  
    30  # hacky workarounds for Bash 3 support (no associative arrays)
    31  images=()
    32  rm -f "$dir"/tags-*.tmp
    33  # repositories[busybox]='"latest": "...", "ubuntu-14.04": "..."'
    34  
    35  while [ $# -gt 0 ]; do
    36  	imageTag="$1"
    37  	shift
    38  	image="${imageTag%%[:@]*}"
    39  	tag="${imageTag#*:}"
    40  	imageId="${tag##*@}"
    41  	[ "$imageId" != "$tag" ] || imageId=
    42  	[ "$tag" != "$imageTag" ] || tag='latest'
    43  	tag="${tag%@*}"
    44  
    45  	imageFile="${image//\//_}" # "/" can't be in filenames :)
    46  
    47  	token="$(curl -sSL -o /dev/null -D- -H 'X-Docker-Token: true' "https://index.docker.io/v1/repositories/$image/images" | tr -d '\r' | awk -F ': *' '$1 == "X-Docker-Token" { print $2 }')"
    48  
    49  	if [ -z "$imageId" ]; then
    50  		imageId="$(curl -sSL -H "Authorization: Token $token" "https://registry-1.docker.io/v1/repositories/$image/tags/$tag")"
    51  		imageId="${imageId//\"/}"
    52  	fi
    53  
    54  	ancestryJson="$(curl -sSL -H "Authorization: Token $token" "https://registry-1.docker.io/v1/images/$imageId/ancestry")"
    55  	if [ "${ancestryJson:0:1}" != '[' ]; then
    56  		echo >&2 "error: /v1/images/$imageId/ancestry returned something unexpected:"
    57  		echo >&2 "  $ancestryJson"
    58  		exit 1
    59  	fi
    60  
    61  	IFS=','
    62  	ancestry=( ${ancestryJson//[\[\] \"]/} )
    63  	unset IFS
    64  
    65  	if [ -s "$dir/tags-$imageFile.tmp" ]; then
    66  		echo -n ', ' >> "$dir/tags-$imageFile.tmp"
    67  	else
    68  		images=( "${images[@]}" "$image" )
    69  	fi
    70  	echo -n '"'"$tag"'": "'"$imageId"'"' >> "$dir/tags-$imageFile.tmp"
    71  
    72  	echo "Downloading '$imageTag' (${#ancestry[@]} layers)..."
    73  	for imageId in "${ancestry[@]}"; do
    74  		mkdir -p "$dir/$imageId"
    75  		echo '1.0' > "$dir/$imageId/VERSION"
    76  
    77  		curl -sSL -H "Authorization: Token $token" "https://registry-1.docker.io/v1/images/$imageId/json" -o "$dir/$imageId/json"
    78  
    79  		# TODO figure out why "-C -" doesn't work here
    80  		# "curl: (33) HTTP server doesn't seem to support byte ranges. Cannot resume."
    81  		# "HTTP/1.1 416 Requested Range Not Satisfiable"
    82  		if [ -f "$dir/$imageId/layer.tar" ]; then
    83  			# TODO hackpatch for no -C support :'(
    84  			echo "skipping existing ${imageId:0:12}"
    85  			continue
    86  		fi
    87  		curl -SL --progress -H "Authorization: Token $token" "https://registry-1.docker.io/v1/images/$imageId/layer" -o "$dir/$imageId/layer.tar" # -C -
    88  	done
    89  	echo
    90  done
    91  
    92  echo -n '{' > "$dir/repositories"
    93  firstImage=1
    94  for image in "${images[@]}"; do
    95  	imageFile="${image//\//_}" # "/" can't be in filenames :)
    96  
    97  	[ "$firstImage" ] || echo -n ',' >> "$dir/repositories"
    98  	firstImage=
    99  	echo -n $'\n\t' >> "$dir/repositories"
   100  	echo -n '"'"$image"'": { '"$(cat "$dir/tags-$imageFile.tmp")"' }' >> "$dir/repositories"
   101  done
   102  echo -n $'\n}\n' >> "$dir/repositories"
   103  
   104  rm -f "$dir"/tags-*.tmp
   105  
   106  echo "Download of images into '$dir' complete."
   107  echo "Use something like the following to load the result into a Docker daemon:"
   108  echo "  tar -cC '$dir' . | docker load"