Last active
August 18, 2021 09:00
-
-
Save allex/3aab7875e033815227dd313a79465e18 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# helper for cleanup docker registry (based on api v2) | |
# by @allex_wang | |
# GistID: 3aab7875e033815227dd313a79465e18 | |
# requires: [jq] | |
set -eu | |
scriptName=$(basename "$0") | |
REGISTRY=127.0.0.1:5000 | |
REG_USER= | |
help() { | |
cat <<-HELP | |
${scriptName} [OPTIONS] -u=allex:passwd --registry=192.168.0.219:5000 | |
Cleanup docker registry remnants (Based on registry api v2) | |
Options: | |
-r | --registry Registry endpoint service (default: $REGISTRY) | |
-u | --user Registry auth user/passwd pairs (eg. allex:123456) | |
-h | --help Display this help and exit | |
HELP | |
} | |
die() { | |
[ "${1-}" ] && echo >&2 "${1}" | |
exit "${2-1}" | |
} | |
while [ $# -gt 0 ]; do | |
OPT=$1 | |
[ "$OPT" = "--" ] && break | |
[ "$OPT" = "${OPT#-*}" ] && { | |
args+=("$OPT") | |
shift | |
continue | |
} | |
if [ "${OPT##=*}" = "$OPT" ]; then | |
OPTARG="${2-}" | |
if [ "${OPTARG##-*}" = "${OPTARG}" ]; then | |
shift | |
else | |
OPTARG= | |
fi | |
else | |
OPT=$(echo "$1" | awk -F= '{print $1}') | |
OPTARG=$(echo "$1" | awk -F= '{print $2}') | |
fi | |
case $OPT in | |
-h | --help) | |
help | |
exit | |
;; | |
-r | --registry) REGISTRY=$OPTARG ;; | |
-u | --user) REG_USER=$OPTARG ;; | |
*) | |
echo "ERROR: unknown parameter \"$OPT\"" | |
help | |
exit 1 | |
;; | |
esac | |
shift | |
done | |
# Registry | |
if [ -z "$REGISTRY" ]; then | |
echo -n "Enter registry: " | |
read -r REGISTRY | |
fi | |
# Registry User:Passwd | |
if [ -z "$REG_USER" ]; then | |
read -rp "Enter authorization for registry ${REGISTRY}: " REG_USER | |
[ -n "$REG_USER" ] || die "abort." | |
if [ "${REG_USER#*:}" = "${REG_USER}" ]; then | |
read -sp "Enter host password for user '$REG_USER': " | |
[ -n "$REPLY" ] || die "abort." | |
REG_USER=$REG_USER:$REPLY | |
fi | |
fi | |
api() { | |
a=$1 | |
shift | |
curl --user "${REG_USER}" -s http://${REGISTRY}/v2/$a "$@" | |
} | |
c_id=$(docker ps | awk 'match($2, /registry:.*/) {print $1}') | |
[ -n "$c_id" ] || exit 1 | |
del_reg_storage() { | |
local target=$1 | |
echo "delete repository $target" | |
docker exec -i "$c_id" rm -rf "/var/lib/registry/docker/registry/v2/repositories/$target" | |
} | |
cleanup_tag() { | |
repo="$1" | |
tag="$2" | |
echo "=> check $repo:$tag..." | |
digests="$(api "$repo/manifests/$tag" -H "Accept: application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json, application/vnd.docker.distribution.manifest.list.v2+json" | jq -r '.manifests[].digest' 2>/dev/null)" | |
( | |
set +e | |
cat <<-EOF | (while read -r t; do (api "$repo/manifests/$t" | grep "MANIFEST_UNKNOWN") && exit 2; done) | |
$digests | |
EOF | |
if [ $? -eq 2 ]; then | |
cat <<-EOF | (while read -r t; do (api "$repo/manifests/$t" -X DELETE; del_reg_storage "$repo/_manifests/versions/${t/:\/}"); done) | |
$digests | |
EOF | |
del_reg_storage "$repo/_manifests/tags/$tag" | |
(exit 2) | |
fi | |
) | |
return $? | |
} | |
# return false (with no-zero exit code) if repo tags not valid | |
check_tags() { | |
local repo=$1 | |
if api $repo/tags/list | egrep '"tags":null|"NAME_UNKNOWN"' &>/dev/null; then | |
return 1 | |
fi | |
return 0 | |
} | |
cleanup() { | |
repositories=($(api "_catalog" | jq -r ".repositories|.[]")) | |
for i in "${repositories[@]}"; do | |
if ! check_tags $i; then | |
del_reg_storage "$i" | |
else ( | |
set +eE | |
api $i/tags/list | jq -r ".tags|.[]" | (while read -a t; do (cleanup_tag "$i" "$t"); done) | |
if ! check_tags $i; then | |
del_reg_storage "$i" | |
fi | |
); fi | |
done | |
} | |
echo "cleanup registry..." | |
cleanup | |
echo "garbage-collect registry..." | |
docker exec "$c_id" registry garbage-collect /etc/docker/registry/config.yml &>/dev/null | |
echo "restart registry..." | |
docker restart $c_id &>/dev/null | |
echo "done!" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment