Skip to content

Instantly share code, notes, and snippets.

@lautitoti
Last active October 20, 2023 15:09
Show Gist options
  • Save lautitoti/4f03e530129e628c82b9d8310e5f7aae to your computer and use it in GitHub Desktop.
Save lautitoti/4f03e530129e628c82b9d8310e5f7aae to your computer and use it in GitHub Desktop.
Script to delete images in a private docker registry, older than a year.
import requests
import json
from datetime import datetime, timedelta
def get_tags_older_than_a_year(registry, image, user, password):
url = f"https://{registry}/v2/{image}/tags/list"
response = requests.get(url, auth=(user, password))
if response.status_code == 200:
tags = response.json().get('tags', [])
if tags:
for tag in tags:
manifest_url = f"https://{registry}/v2/{image}/manifests/{tag}"
response = requests.head(manifest_url, auth=(user, password),
headers={"Accept": "application/vnd.docker.distribution.manifest.v1+json"})
if response.status_code == 200:
created_time_str = response.headers['Last-Modified']
created_time = datetime.strptime(created_time_str, '%a, %d %b %Y %H:%M:%S %Z')
if datetime.now() - created_time > timedelta(days=365):
print(f"Tag {tag} of image {image} is older than a year. Deleting...")
# Uncomment the following line to actually delete the tag
requests.delete(manifest_url, auth=(user, password))
else:
print(f"Error getting manifest for tag {tag} of image {image}: {response.status_code}")
else:
print(f"No tags found for image {image}.")
else:
print(f"Error getting tags for image {image}: {response.status_code}")
def main():
registry = input("Specify private image registry url without https://: ")
images = input("List images, separated by space: ").split()
user = input("Registry User: ")
password = input("Registry Password: ")
for image in images:
print(f"Checking tags for image {image}...")
get_tags_older_than_a_year(registry, image, user, password)
if __name__ == "__main__":
main()
#!/bin/bash
# based on: https://gist.github.com/jaytaylor/86d5efaddda926a25fa68c263830dac1
# Author: github.com/lautitoti
# changes:
# - Check for images older than a year
-----------
# Function to check tags older than a year
check_tags_older_than_a_year() {
local registry=$1
local image=$2
local user=$3
local password=$4
local tags=$(curl -s -u "$user:$password" "https://${registry}/v2/${image}/tags/list" | jq -r '.tags // [] | .[]')
if [[ -n $tags ]]; then
for tag in $tags; do
# For manifests v2 uncomment the following line and comment the v1 version.
# local created_time=$(curl -s -I -u "$user:$password" -H "Accept: application/vnd.docker.distribution.manifest.v2+json" "https://${registry}/v2/${image}/manifests/${tag}" | jq -r '[.history[]]|map(.v1Compatibility|fromjson|.created)|sort|reverse|.[0]')
local created_time=$(curl -s -u $user:$password -H 'Accept: application/vnd.docker.distribution.manifest.v1+json' -X GET https://$registry/v2/$image/manifests/$tag | jq -r '[.history[]]|map(.v1Compatibility|fromjson|.created)|sort|reverse|.[0]')
local created_timestamp=$(date -d "$created_time" +%s)
local current_timestamp=$(date +%s)
local age_days=$(( (current_timestamp - created_timestamp) / (60*60*24) ))
if [[ $age_days -gt 365 ]]; then
echo "Tag $tag of image $image is older than a year. Deleting..."
# Uncomment the following line to actually delete the tag
curl -s -u "$user:$password" -X DELETE "https://${registry}/v2/${image}/manifests/$(curl -s -I -u "$user:$password" -H "Accept: application/vnd.docker.distribution.manifest.v2+json" "https://${registry}/v2/${image}/manifests/${tag}" | grep -i 'docker-content-digest' | awk -F': ' '{print $2}' | sed 's/[\r\n]//g')"
fi
done
else
echo "No tags found for image $image."
fi
}
# Main function
main() {
echo "Specify private image registry url without https://"
read -r registry
echo "List images, separated by space"
read -r images
echo "Registry User:"
read -r user
echo "Registry Password:"
read -s password
IFS=' ' read -r -a images_array <<< "$images"
for image in "${images_array[@]}"; do
echo "Checking tags for image $image..."
check_tags_older_than_a_year "$registry" "$image" "$user" "$password"
done
}
# Run the main function
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment