Created
February 4, 2025 23:29
-
-
Save seanslma/76f9733001cd301a716d9788568bde1e to your computer and use it in GitHub Desktop.
Delete digests in specified registry repos
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/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