Merged in feature/eula.part1 (pull request #206)
eula support * eula support * docs
This commit is contained in:
Executable
+111
@@ -0,0 +1,111 @@
|
||||
#!/bin/bash
|
||||
# cleanup.docker.images.sh
|
||||
#
|
||||
# Removes old Docker images, keeping only the newest image per repository.
|
||||
# Images are sorted by creation date, and only the most recent per repo is retained.
|
||||
#
|
||||
# Usage:
|
||||
# ./cleanup.docker.images.sh [--dryrun]
|
||||
#
|
||||
# Options:
|
||||
# --dryrun Show what would be deleted without actually deleting
|
||||
#
|
||||
# Returns:
|
||||
# 0 on success
|
||||
# 1 on error
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
DRYRUN=false
|
||||
|
||||
# Parse arguments
|
||||
for arg in "$@"; do
|
||||
case $arg in
|
||||
--dryrun)
|
||||
DRYRUN=true
|
||||
shift
|
||||
;;
|
||||
--help|-h)
|
||||
echo "Usage: $0 [--dryrun]"
|
||||
echo ""
|
||||
echo "Removes old Docker images, keeping only the newest per repository."
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --dryrun Show what would be deleted without actually deleting"
|
||||
echo " --help Show this help message"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $arg"
|
||||
echo "Use --help for usage information"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Get images to delete: all but the newest per repository
|
||||
# Format: repository|tag|id|created
|
||||
# Sort by repo, then by date descending (newest first)
|
||||
# Skip the first (newest) for each repo, output the rest
|
||||
get_images_to_delete() {
|
||||
docker images --format '{{.Repository}}|{{.Tag}}|{{.ID}}|{{.CreatedAt}}' | \
|
||||
grep -v '<none>' | \
|
||||
sort -t'|' -k1,1 -k4r | \
|
||||
awk -F'|' 'seen[$1]++ {print $1"|"$2"|"$3}'
|
||||
}
|
||||
|
||||
# Get unique image IDs from the list
|
||||
get_unique_ids() {
|
||||
awk -F'|' '{print $3}' | sort -u
|
||||
}
|
||||
|
||||
echo "Scanning Docker images..."
|
||||
echo ""
|
||||
|
||||
IMAGES_TO_DELETE=$(get_images_to_delete)
|
||||
|
||||
if [ -z "$IMAGES_TO_DELETE" ]; then
|
||||
echo "No old images to clean up. Each repository has only one image."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Count images
|
||||
IMAGE_COUNT=$(echo "$IMAGES_TO_DELETE" | wc -l | tr -d ' ')
|
||||
UNIQUE_IDS=$(echo "$IMAGES_TO_DELETE" | get_unique_ids)
|
||||
UNIQUE_COUNT=$(echo "$UNIQUE_IDS" | wc -l | tr -d ' ')
|
||||
|
||||
if [ "$DRYRUN" = true ]; then
|
||||
echo "=== DRY RUN MODE ==="
|
||||
echo "The following images would be deleted ($IMAGE_COUNT tags, $UNIQUE_COUNT unique images):"
|
||||
echo ""
|
||||
printf "%-50s %-35s %s\n" "REPOSITORY" "TAG" "IMAGE ID"
|
||||
printf "%-50s %-35s %s\n" "----------" "---" "--------"
|
||||
echo "$IMAGES_TO_DELETE" | while IFS='|' read -r repo tag id; do
|
||||
printf "%-50s %-35s %s\n" "$repo" "$tag" "$id"
|
||||
done
|
||||
echo ""
|
||||
echo "Run without --dryrun to delete these images."
|
||||
else
|
||||
echo "Deleting $IMAGE_COUNT image tags ($UNIQUE_COUNT unique images)..."
|
||||
echo ""
|
||||
|
||||
DELETED=0
|
||||
FAILED=0
|
||||
|
||||
for id in $UNIQUE_IDS; do
|
||||
if docker rmi "$id" 2>/dev/null; then
|
||||
((DELETED++)) || true
|
||||
else
|
||||
# Try force removal if normal removal fails
|
||||
if docker rmi -f "$id" 2>/dev/null; then
|
||||
((DELETED++)) || true
|
||||
else
|
||||
echo "Warning: Could not delete image $id (may be in use)"
|
||||
((FAILED++)) || true
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Cleanup complete: $DELETED deleted, $FAILED failed/skipped"
|
||||
fi
|
||||
Reference in New Issue
Block a user