From 4a030fdc9df7596a1f336df86a7d3fd5c2744ed8 Mon Sep 17 00:00:00 2001 From: Jonathan Westerholt Date: Tue, 7 Aug 2018 20:32:09 +0200 Subject: [PATCH] add support for manifest lists and fix double deletions --- Dockerfile | 2 +- docker-registry-cleanup.sh | 28 ++++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 48bc4c7..1730e45 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ FROM alpine:3.6 -RUN apk add --no-cache curl bash +RUN apk add --no-cache curl bash jq ADD docker-registry-cleanup.sh /docker-registry-cleanup.sh CMD /docker-registry-cleanup.sh diff --git a/docker-registry-cleanup.sh b/docker-registry-cleanup.sh index b83f107..6d75b2a 100755 --- a/docker-registry-cleanup.sh +++ b/docker-registry-cleanup.sh @@ -4,6 +4,7 @@ : ${REGISTRY_DIR:=/registry} REPO_DIR=${REGISTRY_DIR}/docker/registry/v2/repositories +BLOB_DIR=${REGISTRY_DIR}/docker/registry/v2/blobs if [ "${DRY_RUN}" == "true" ]; then echo "Running in dry-run mode. Will not make any changes" @@ -35,8 +36,31 @@ fi cd ${REPO_DIR} - -MANIFESTS_WITHOUT_TAGS=$(comm -23 <(find . -type f -name "link" | grep "_manifests/revisions/sha256" | grep -v "\/signatures\/sha256\/" | awk -F/ '{print $(NF-1)}' | sort) <(for f in $(find . -type f -name "link" | grep "_manifests/tags/.*/current/link"); do cat ${f} | sed 's/^sha256://g'; echo; done | sort)) +ALL_MANIFESTS=$(find ${repo_dir} -type f -name "link" | grep "_manifests/revisions/sha256" | \ + grep -v "\/signatures\/sha256\/" | \ + awk -F/ '{print $(NF-1)}' | sort | uniq) +LINKED_MANIFESTS=$(for f in $(find ${repo_dir} -type f -name "link" | \ + grep "_manifests/tags/.*/current/link"); do\ + cat ${f} | sed 's/^sha256://g'; echo; \ + done | sort | uniq) +LIST_MANIFESTS="" + +for manifest in ${LINKED_MANIFESTS}; do + # check if manifest is a manifest list and add references to real manifest + manifest_data=$(cat ${BLOB_DIR}/sha256/${manifest:0:2}/${manifest}/data) + manifest_media_type=$(echo ${manifest_data} | jq -r '.mediaType') + if [ "${manifest_media_type}" == "application/vnd.docker.distribution.manifest.list.v2+json" ] ; then + # we have a manifest list and fetch the referenced manifests + additional_manifests=$(echo ${manifest_data} | jq -r '.["manifests"] | .[].digest' | cut -d: -f2) + LIST_MANIFESTS=$(printf "%s\n%s\n" ${LIST_MANIFESTS} ${additional_manifests}) + fi +done + +LIST_MANIFESTS=$(echo "$LIST_MANIFESTS" | sort | uniq) + +LINKED_MANIFESTS=$(printf "%s\n%s" "${LINKED_MANIFESTS}" "${LIST_MANIFESTS}") + +MANIFESTS_WITHOUT_TAGS=$(comm -23 <(echo "${ALL_MANIFESTS}") <(echo "${LINKED_MANIFESTS}")) CURRENT_COUNT=0 FAILED_COUNT=0