Skip to content

Instantly share code, notes, and snippets.

@ben0x539
Created June 17, 2018 20:17
Show Gist options
  • Save ben0x539/97d39e0800c5210cca5f999aa9c09aeb to your computer and use it in GitHub Desktop.
Save ben0x539/97d39e0800c5210cca5f999aa9c09aeb to your computer and use it in GitHub Desktop.
pull manifest + layers from a docker image with curl with progress meter visible
#! /usr/bin/env bash
set -euo pipefail
api() {
local type endpoint registry image arg url
type=$1 endpoint=$2 registry=$3 image=$4 arg=$5
url="https://$registry/v2/$image/$endpoint/$arg"
curl --config - <<<"-u $ARTIFACTORY_CREDS" -H "Accept: $type" "$url"
}
get-manifest() {
local registry image label
IFS=$'\t' read -r registry image label < <(split-docker-url "$1" $'\t')
api application/vnd.docker.distribution.manifest.v2+json manifests "$registry" "$image" "$label"
}
get-blob() {
local registry image label
IFS=$'\t' read -r registry image label < <(split-docker-url "$1" $'\t')
api application/vnd.docker.image.rootfs.diff.tar.gzip blobs "$registry" "$image" "$2"
}
get-image() {
local image manifest layers
image=$1
echo >&2 "fetching manifest for $image"
manifest=$(get-manifest "$image")
counter=0
while IFS=$'\t' read -r size digest; do
counter=$((counter+1))
echo >&2 "fetching layer $counter, $digest, size $size"
get-blob "$image" "$digest" > "${digest#sha256:}.tar"
done < <(jq <<<"$manifest" --raw-output '.layers | .[] | "\(.size)\t\(.digest)"')
}
split-docker-url() {
local s sep image label registry
s=$1 sep=$2
registry=${s%%/*} s=${s#*/}
if [[ "$s" == "$registry" ]]; then echo >&2 "no registry?"; return 1; fi
label=${s##*:} s=${s%:*}
if [[ "$s" == "$label" ]]; then label=latest; fi
image=$s
echo "$registry$sep$image$sep$label$sep"
}
main() {
for image in "$@"; do
get-image "$image"
done
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment