Update "download-frozen-image-v2.sh" such that redirects are optional
If the registry responds directly with blob contents, use them, otherwise follow the redirect without Authorization headers (which likely aren't valid for the server being redirected to). This preserves the basic structure of the previous output with up to one additional progress bar per-layer (for the redirect request and then the following blob request). Signed-off-by: Tianon Gravi <admwiggin@gmail.com>
This commit is contained in:
parent
5c38e4c16a
commit
4bbdc0b8f7
1 changed files with 41 additions and 17 deletions
|
@ -44,16 +44,41 @@ if [ "$(go env GOHOSTOS)" = 'windows' ]; then
|
|||
fi
|
||||
fi
|
||||
|
||||
fetch_blob() {
|
||||
url=$1
|
||||
token=$2
|
||||
dest=$3
|
||||
echo "Attempting to download blob $url"
|
||||
target=$(curl -sS -v -H "Authorization: Bearer $token" "$url" 2>&1 | grep "Location:" | sed 's/< Location: \(.*\)\r/\1/')
|
||||
# curl blob (exclude auth token)
|
||||
curl -fsS --progress "${target}" -o "$dest"
|
||||
}
|
||||
registryBase='https://registry-1.docker.io'
|
||||
authBase='https://auth.docker.io'
|
||||
authService='registry.docker.io'
|
||||
|
||||
# https://github.com/moby/moby/issues/33700
|
||||
fetch_blob() {
|
||||
local token="$1"; shift
|
||||
local image="$1"; shift
|
||||
local digest="$1"; shift
|
||||
local targetFile="$1"; shift
|
||||
local curlArgs=( "$@" )
|
||||
|
||||
local curlHeaders="$(
|
||||
curl -S "${curlArgs[@]}" \
|
||||
-H "Authorization: Bearer $token" \
|
||||
"$registryBase/v2/$image/blobs/$digest" \
|
||||
-o "$targetFile" \
|
||||
-D-
|
||||
)"
|
||||
curlHeaders="$(echo "$curlHeaders" | tr -d '\r')"
|
||||
if [ "$(echo "$curlHeaders" | awk 'NR == 1 { print $2; exit }')" != '200' ]; then
|
||||
rm -f "$targetFile"
|
||||
|
||||
local blobRedirect="$(echo "$curlHeaders" | awk -F ': ' 'tolower($1) == "location" { print $2; exit }')"
|
||||
if [ -z "$blobRedirect" ]; then
|
||||
echo >&2 "error: failed fetching '$image' blob '$digest'"
|
||||
echo "$curlHeaders" | head -1 >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
curl -fSL "${curlArgs[@]}" \
|
||||
"$blobRedirect" \
|
||||
-o "$targetFile"
|
||||
fi
|
||||
}
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
imageTag="$1"
|
||||
|
@ -70,14 +95,14 @@ while [ $# -gt 0 ]; do
|
|||
|
||||
imageFile="${image//\//_}" # "/" can't be in filenames :)
|
||||
|
||||
token="$(curl -fsSL "https://auth.docker.io/token?service=registry.docker.io&scope=repository:$image:pull" | jq --raw-output '.token')"
|
||||
token="$(curl -fsSL "$authBase/token?service=$authService&scope=repository:$image:pull" | jq --raw-output '.token')"
|
||||
|
||||
manifestJson="$(
|
||||
curl -fsSL \
|
||||
-H "Authorization: Bearer $token" \
|
||||
-H 'Accept: application/vnd.docker.distribution.manifest.v2+json' \
|
||||
-H 'Accept: application/vnd.docker.distribution.manifest.v1+json' \
|
||||
"https://registry-1.docker.io/v2/$image/manifests/$digest"
|
||||
"$registryBase/v2/$image/manifests/$digest"
|
||||
)"
|
||||
if [ "${manifestJson:0:1}" != '{' ]; then
|
||||
echo >&2 "error: /v2/$image/manifests/$digest returned something unexpected:"
|
||||
|
@ -98,7 +123,7 @@ while [ $# -gt 0 ]; do
|
|||
imageId="${configDigest#*:}" # strip off "sha256:"
|
||||
|
||||
configFile="$imageId.json"
|
||||
fetch_blob "https://registry-1.docker.io/v2/$image/blobs/$configDigest" $token "$dir/$configFile"
|
||||
fetch_blob "$token" "$image" "$configDigest" "$dir/$configFile" -s
|
||||
|
||||
layersFs="$(echo "$manifestJson" | jq --raw-output --compact-output '.layers[]')"
|
||||
IFS="$newlineIFS"
|
||||
|
@ -165,8 +190,8 @@ while [ $# -gt 0 ]; do
|
|||
echo "skipping existing ${layerId:0:12}"
|
||||
continue
|
||||
fi
|
||||
token="$(curl -fsSL "https://auth.docker.io/token?service=registry.docker.io&scope=repository:$image:pull" | jq --raw-output '.token')"
|
||||
fetch_blob "https://registry-1.docker.io/v2/$image/blobs/$layerDigest" $token "$dir/$layerTar"
|
||||
token="$(curl -fsSL "$authBase/token?service=$authService&scope=repository:$image:pull" | jq --raw-output '.token')"
|
||||
fetch_blob "$token" "$image" "$layerDigest" "$dir/$layerTar" --progress
|
||||
;;
|
||||
|
||||
*)
|
||||
|
@ -235,9 +260,8 @@ while [ $# -gt 0 ]; do
|
|||
echo "skipping existing ${layerId:0:12}"
|
||||
continue
|
||||
fi
|
||||
token="$(curl -fsSL "https://auth.docker.io/token?service=registry.docker.io&scope=repository:$image:pull" | jq --raw-output '.token')"
|
||||
# find redirect using token:
|
||||
fetch_blob "https://registry-1.docker.io/v2/$image/blobs/$imageLayer" $token "$dir/$layerId/layer.tar"
|
||||
token="$(curl -fsSL "$authBase/token?service=$authService&scope=repository:$image:pull" | jq --raw-output '.token')"
|
||||
fetch_blob "$token" "$image" "$imageLayer" "$dir/$layerId/layer.tar" --progress
|
||||
done
|
||||
;;
|
||||
|
||||
|
|
Loading…
Reference in a new issue