Skip to content

Instantly share code, notes, and snippets.

@robkooper
Last active January 31, 2022 18:56
Show Gist options
  • Save robkooper/c1ca86848b4a071d516bfc4621d766ac to your computer and use it in GitHub Desktop.
Save robkooper/c1ca86848b4a071d516bfc4621d766ac to your computer and use it in GitHub Desktop.
pull layers of image. if you need to access a private image, add `-u "username:password"` to the login curl commands.
#!/bin/bash
# SERVER="https://harbor.example.com
# SERVICE="harbor-registry"
SERVER="https://registry.hub.docker.com"
SERVICE="registry.docker.io"
IMAGE="library/busybox"
TAG="latest"
# output folder
FOLDER="/tmp/${IMAGE}/${TAG}"
mkdir -p ${FOLDER}
# login
if [ "${SERVICE}" == "registry.docker.io" ]; then
RESULT=$(curl -s "https://auth.docker.io/token?service=${SERVICE}&scope=repository:${IMAGE}:pull")
elif [ "${SERVICE}" == "harbor-registry" ]; then
RESULT=$(curl -s "${SERVER}/service/token?service=${SERVICE}&scope=repository:${IMAGE}:pull")
else
echo "Error don't know about ${SERVICE}"
fi
TOKEN=$(echo "${RESULT}" | jq -r '.token')
# manifest
MANIFEST=$(curl -s -H "Authorization: Bearer ${TOKEN}" -H "Content-Type: application/json" ${SERVER}/v2/${IMAGE}/manifests/${TAG})
SCHEMA=$(echo ${MANIFEST} | jq -r '.schemaVersion')
echo ${MANIFEST} | jq . > ${FOLDER}/manifest.json
# fetch layers
if [ "${SCHEMA}" == "1" ]; then
LAYERS="$(echo ${MANIFEST} | jq -r '.fsLayers[] | @base64')"
else
LAYERS="$(echo ${MANIFEST} | jq -r '.layers[] | @base64')"
fi
# fetch each layer
for LAYER in $LAYERS; do
if [ "${SCHEMA}" == "1" ]; then
SIZE="NA"
DIGEST=$(echo ${LAYER} | base64 -d | jq -r ".blobSum")
else
SIZE=$(echo ${LAYER} | base64 -d | jq -r '.size')
DIGEST=$(echo ${LAYER} | base64 -d | jq -r '.digest')
fi
echo "Fetching ${SIZE} bytes for layer ${DIGEST}"
curl -s -o ${FOLDER}/${DIGEST} -H "Authorization: Bearer ${TOKEN}" ${SERVER}/v2/${IMAGE}/blobs/${DIGEST} || (
echo "ERROR FETCHING LAYER ${DIGEST}, ERROR CODE=$?"
echo " output in ${FOLDER}/${DIGEST}"
echo " file size = $(stat --format='%s' ${FOLDER}/${DIGEST}) expected size = ${SIZE}"
)
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment