Created
April 1, 2025 07:34
-
-
Save akunzai/c330451f4d4cdcf5253bdfd50dd3ce50 to your computer and use it in GitHub Desktop.
Clean up old Podman images while keeping the newest version of each image
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 | |
# Show usage information | |
show_help() { | |
cat << EOF | |
Usage: $(basename "$0") [OPTIONS] [IMAGE_PATTERN] | |
Clean up old Podman images while keeping the newest version of each image. | |
Options: | |
--dryrun Show what would be removed without actually removing anything | |
--help Display this help message and exit | |
Arguments: | |
IMAGE_PATTERN Pattern to match image names (default: .*) | |
Examples: | |
$(basename "$0") # Clean all images from any registry | |
$(basename "$0") --dryrun # Show what would be removed (dry run) | |
$(basename "$0") asia-east1-docker.pkg.dev # Clean only asia-east1-docker.pkg.dev images | |
$(basename "$0") --dryrun asia-east1-docker.pkg.dev # Dry run for asia-east1-docker.pkg.dev images | |
EOF | |
exit 0 | |
} | |
# Parse arguments | |
IMAGE_PATTERN=".*" | |
DRYRUN=false | |
for arg in "$@"; do | |
case "$arg" in | |
--help|-h) | |
show_help | |
;; | |
--dryrun) | |
DRYRUN=true | |
;; | |
-*) | |
# Skip other options | |
;; | |
*) | |
IMAGE_PATTERN="$arg" | |
;; | |
esac | |
done | |
# Extract version from tag | |
extract_version() { | |
echo "$1" | grep -o '[0-9]\+\(\.[0-9]\+\)*' 2>/dev/null || echo "" | |
} | |
# Get images | |
TMPFILE=$(mktemp) | |
RESULT_FILE=$(mktemp) | |
LATEST_FILE=$(mktemp) | |
CLEANUP_FILE=$(mktemp) | |
# Ensure cleanup on exit | |
cleanup() { | |
rm -f "$TMPFILE" "$RESULT_FILE" "$LATEST_FILE" "$CLEANUP_FILE" | |
} | |
trap cleanup EXIT INT TERM | |
# Get all images matching pattern | |
podman image ls | grep "$IMAGE_PATTERN" > "$TMPFILE" || true | |
if [ ! -s "$TMPFILE" ]; then | |
echo "No images found matching pattern: $IMAGE_PATTERN" | |
exit 0 | |
fi | |
# Process each line into repo, tag, id | |
cat "$TMPFILE" | while read -r line; do | |
repo=$(echo "$line" | awk '{print $1}') | |
tag=$(echo "$line" | awk '{print $2}') | |
id=$(echo "$line" | awk '{print $3}') | |
# Skip if no repo or tag | |
[ -z "$repo" ] || [ -z "$tag" ] && continue | |
# Store repo, tag, id | |
echo "$repo|$tag|$id" >> "$RESULT_FILE" | |
done | |
# Find latest version for each repo and list images to remove | |
for repo in $(cat "$RESULT_FILE" | cut -d'|' -f1 | sort | uniq); do | |
# Get all tags and find latest version | |
latest_tag="" | |
latest_ver="" | |
# Get all tags for this repo | |
for entry in $(grep "^$repo|" "$RESULT_FILE"); do | |
tag=$(echo "$entry" | cut -d'|' -f2) | |
# Skip 'latest' tag for version comparison | |
if [ "$tag" != "latest" ]; then | |
version=$(extract_version "$tag") | |
if [ -n "$version" ]; then | |
# If first version or newer | |
if [ -z "$latest_ver" ] || [ "$(printf '%s\n%s' "$latest_ver" "$version" | sort -V | tail -n1)" = "$version" ]; then | |
latest_ver="$version" | |
latest_tag="$tag" | |
fi | |
fi | |
fi | |
done | |
# Only proceed if we found a version tag | |
if [ -n "$latest_tag" ]; then | |
# Find old versions to remove | |
remove_ids="" | |
remove_tags="" | |
for entry in $(grep "^$repo|" "$RESULT_FILE"); do | |
tag=$(echo "$entry" | cut -d'|' -f2) | |
id=$(echo "$entry" | cut -d'|' -f3) | |
if [ "$tag" != "$latest_tag" ] && [ "$tag" != "latest" ]; then | |
remove_ids="$remove_ids $id" | |
remove_tags="$remove_tags $tag" | |
fi | |
done | |
# Clean up the lists | |
remove_ids=$(echo "$remove_ids" | tr -s ' ' | sed 's/^ //') | |
remove_tags=$(echo "$remove_tags" | tr -s ' ' | sed 's/^ //') | |
# Only output if we found images to remove | |
if [ -n "$remove_ids" ]; then | |
echo "Repo: $repo" | |
echo " Latest: $latest_tag" | |
echo " Remove: $remove_tags" | |
echo " Command: podman image rm -f $remove_ids" | |
if [ "$DRYRUN" = false ]; then | |
# shellcheck disable=SC2086 | |
podman image rm -f $remove_ids | |
fi | |
fi | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment