github.com/lafolle/docker@v1.6.0/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  	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 }')"
    46  	
    47  	if [ -z "$imageId" ]; then
    48  		imageId="$(curl -sSL -H "Authorization: Token $token" "https://registry-1.docker.io/v1/repositories/$image/tags/$tag")"
    49  		imageId="${imageId//\"/}"
    50  	fi
    51  	
    52  	ancestryJson="$(curl -sSL -H "Authorization: Token $token" "https://registry-1.docker.io/v1/images/$imageId/ancestry")"
    53  	if [ "${ancestryJson:0:1}" != '[' ]; then
    54  		echo >&2 "error: /v1/images/$imageId/ancestry returned something unexpected:"
    55  		echo >&2 "  $ancestryJson"
    56  		exit 1
    57  	fi
    58  	
    59  	IFS=','
    60  	ancestry=( ${ancestryJson//[\[\] \"]/} )
    61  	unset IFS
    62  	
    63  	if [ -s "$dir/tags-$image.tmp" ]; then
    64  		echo -n ', ' >> "$dir/tags-$image.tmp"
    65  	else
    66  		images=( "${images[@]}" "$image" )
    67  	fi
    68  	echo -n '"'"$tag"'": "'"$imageId"'"' >> "$dir/tags-$image.tmp"
    69  	
    70  	echo "Downloading '$imageTag' (${#ancestry[@]} layers)..."
    71  	for imageId in "${ancestry[@]}"; do
    72  		mkdir -p "$dir/$imageId"
    73  		echo '1.0' > "$dir/$imageId/VERSION"
    74  		
    75  		curl -sSL -H "Authorization: Token $token" "https://registry-1.docker.io/v1/images/$imageId/json" -o "$dir/$imageId/json"
    76  		
    77  		# TODO figure out why "-C -" doesn't work here
    78  		# "curl: (33) HTTP server doesn't seem to support byte ranges. Cannot resume."
    79  		# "HTTP/1.1 416 Requested Range Not Satisfiable"
    80  		if [ -f "$dir/$imageId/layer.tar" ]; then
    81  			# TODO hackpatch for no -C support :'(
    82  			echo "skipping existing ${imageId:0:12}"
    83  			continue
    84  		fi
    85  		curl -SL --progress -H "Authorization: Token $token" "https://registry-1.docker.io/v1/images/$imageId/layer" -o "$dir/$imageId/layer.tar" # -C -
    86  	done
    87  	echo
    88  done
    89  
    90  echo -n '{' > "$dir/repositories"
    91  firstImage=1
    92  for image in "${images[@]}"; do
    93  	[ "$firstImage" ] || echo -n ',' >> "$dir/repositories"
    94  	firstImage=
    95  	echo -n $'\n\t' >> "$dir/repositories"
    96  	echo -n '"'"$image"'": { '"$(cat "$dir/tags-$image.tmp")"' }' >> "$dir/repositories"
    97  done
    98  echo -n $'\n}\n' >> "$dir/repositories"
    99  
   100  rm -f "$dir"/tags-*.tmp
   101  
   102  echo "Download of images into '$dir' complete."
   103  echo "Use something like the following to load the result into a Docker daemon:"
   104  echo "  tar -cC '$dir' . | docker load"