Skip to content

Instantly share code, notes, and snippets.

@seanslma
Created February 4, 2025 23:29
Show Gist options
  • Save seanslma/76f9733001cd301a716d9788568bde1e to your computer and use it in GitHub Desktop.
Save seanslma/76f9733001cd301a716d9788568bde1e to your computer and use it in GitHub Desktop.
Delete digests in specified registry repos
#!/bin/bash
# This script removes all tags in specified namespaces from local registry
# after this script run, run the following script to free the space:
# bin/registry garbage-collect /etc/docker/registry/config.yml
#
# Examples (dryrun and execution):
# ./delete_registry_repos.sh -r http://registry.local:5000 -n dev
# ./delete_registry_repos.sh -r https://registry.example.com -n dev,pr -d
#
# You can set the default value in the script so no input for -r -n
# Function to delete repo tags
delete_registry_repos() {
echo "Cleaning repositories: ${registry}/${namespaces}"
IFS=',' read -r -a included_namespaces <<< "${namespaces}";
# fetch the list of repositories
local repos=$(curl -s "${registry}/v2/_catalog" | jq -r '.repositories[]')
# keep repos that belong to allowed namespaces
local included_repos=() # initialize an empty list
for repo in $repos; do
namespace=$(echo "$repo" | cut -d'/' -f1)
if [[ " ${included_namespaces[@]} " =~ " ${namespace} " ]]; then
included_repos+=("$repo")
fi
done
# loop over the list of included repositories
for repo in "${included_repos[0]}"; do
echo "$repo"
local repo_url="${registry}/v2/${repo}"
# step 1: get all tags for the repository
local tags=$(curl -s -k -u "$user:$pass" "${repo_url}/tags/list" | jq -r 'if .tags then .tags[] else empty end')
#tags=$(curl -k -s -u $user:$password "$tagurl" | awk -F: '{print $3}' | sed -e 's/[][]//g' -e 's/\"//g' -e 's/ //g' -e 's/,/\n/g' | tr '}' '\n' | tr '{' '\n')
# step 2: loop through tags and delete images
for tag in $tags; do
# get the digest for the tag
local digest=$(curl -s -k -I -u "$user:$pass" -H "${v2_json_header}" \
"${repo_url}/manifests/${tag}" | \
grep -i "docker-content-digest" | \
awk -F': ' '{print $2}' | sed 's/[\r\n]//g')
if [ -z "$digest" ]; then
echo " failed to get digest for tag: $tag"
else
# delete the image with the digest
if [ "$delete" = true ]; then
curl -s -k -u "$user:$pass" -X DELETE "${repo_url}/manifests/$digest"
echo " deleted: ${tag}"
else
echo " ${tag}"
fi
fi
done
done
echo "Finished"
}
HELPMSG="
Basic usage
$0 -r {registry_url} -n {comma-separated-namespaces}
Options avaliable
-h help on how to use the command
-r (required) registry url
-n (required) namespaces
-u user
-p password
-d delete the manifests, otherwise dryrun to only show info
Examples
$0 -r http://registry.local:5000 -n dev
$0 -r https://registry.example.com -n dev,pr -d
"
v2_json_header="Accept: application/vnd.docker.distribution.manifest.v2+json"
# Initialize variables
registry="https://registry.example.com"
namespaces="my-namespace1,my-namespace2"
user=""
pass=""
delete=false
while getopts "hr:n:u:p:d" opt; do
case "$opt" in
h) echo "$HELPMSG"; exit 0 ;;
r) registry="$OPTARG" ;;
n) namespaces="$OPTARG" ;;
u) user="$OPTARG" ;;
p) password="$OPTARG" ;;
d) delete=true ;;
\?) echo "Invalid option: -$OPTARG" >&2; exit 1 ;;
esac
done
# Required params
if [ -z "$registry" ]; then echo "Error: Registry (-r) required"; echo "$HELPMSG"; exit 1; fi
if [ -z "$namespaces" ]; then echo "Error: Namespaces (-n) required"; echo "$HELPMSG"; exit 1; fi
delete_registry_repos
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment