diff --git a/Dockerfile b/Dockerfile index c3d1c246bf..a7cbf468d6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -107,9 +107,6 @@ RUN go get golang.org/x/tools/cmd/cover # TODO replace FPM with some very minimal debhelper stuff RUN gem install --no-rdoc --no-ri fpm --version 1.3.2 -# Get the "busybox" image source so we can build locally instead of pulling -RUN git clone -b buildroot-2014.02 https://github.com/jpetazzo/docker-busybox.git /docker-busybox - # Install registry ENV REGISTRY_COMMIT c448e0416925a9876d5576e412703c9b8b865e19 RUN set -x \ @@ -145,6 +142,10 @@ ENV DOCKER_BUILDTAGS apparmor selinux btrfs_noversion # Let us use a .bashrc file RUN ln -sfv $PWD/.bashrc ~/.bashrc +# Get the "busybox" image so we can "docker load" locally instead of pulling +COPY contrib/download-frozen-image.sh /go/src/github.com/docker/docker/contrib/ +RUN ./contrib/download-frozen-image.sh /docker-busybox busybox@4986bf8c15363d1c5d15512d5266f8777bfba4974ac56e3270e7760f6f0a8125 + # Install man page generator COPY vendor /go/src/github.com/docker/docker/vendor # (copy vendor/ because go-md2man needs golang.org/x/net) diff --git a/contrib/download-frozen-image.sh b/contrib/download-frozen-image.sh new file mode 100755 index 0000000000..2e3eb98e54 --- /dev/null +++ b/contrib/download-frozen-image.sh @@ -0,0 +1,90 @@ +#!/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" | tr -d '\r' | awk -F ': *' '$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" diff --git a/project/make/.ensure-busybox b/project/make/.ensure-busybox index 24ba3052db..fef9a0135c 100644 --- a/project/make/.ensure-busybox +++ b/project/make/.ensure-busybox @@ -2,8 +2,19 @@ set -e if ! docker inspect busybox &> /dev/null; then - if [ -d /docker-busybox ]; then - ( set -x; docker build -t busybox /docker-busybox ) + hardCodedDir='/docker-busybox' + if [ -d "$hardCodedDir" ]; then + ( set -x; tar -cC "$hardCodedDir" . | docker load ) + elif [ -e Dockerfile ] && command -v curl > /dev/null; then + # testing for "curl" because "download-frozen-image.sh" is built around curl + dir="$DEST/busybox" + # extract the exact "download-frozen-image.sh" line from the Dockerfile itself for consistency + awk '$1 == "RUN" && $2 == "./contrib/download-frozen-image.sh" && /busybox@/ { + for (i = 2; i < NF; i++) + printf ( $i == "'"$hardCodedDir"'" ? "'"$dir"'" : $i ) " "; + print $NF; + }' Dockerfile | sh -x + ( set -x; tar -cC "$dir" . | docker load ) else ( set -x; docker pull busybox ) fi