Skip to content

Instantly share code, notes, and snippets.

@DawnBreather
Last active November 26, 2024 11:51
Show Gist options
  • Save DawnBreather/852a73e26cede6bff21bfe34be963378 to your computer and use it in GitHub Desktop.
Save DawnBreather/852a73e26cede6bff21bfe34be963378 to your computer and use it in GitHub Desktop.
GCP Toolbox (i.e. scripts)

GCR Image Cleanup Script

A simple Bash script to clean up Google Container Registry (GCR) images older than a specified number of days. Includes a dry-run mode to preview deletions without making any changes.

Prerequisites

  • Google Cloud SDK (gcloud) installed and authenticated.
  • jq installed for JSON processing.
  • Access to the GCR repository from Cloud Shell or your local environment.

Setup

  1. Download the Script:

    Save the cleanup_gcr.sh script to your desired directory.

  2. Make the Script Executable:

    chmod +x cleanup_gcr.sh
#!/bin/bash
# Script to clean up Google Container Registry images older than a specified number of days.
# Supports a dry-run mode to simulate deletions without performing them.
# Exit immediately if a command exits with a non-zero status
set -e
# Variables
PROJECT_ID="your-gcp-project-id" # Replace with your GCP Project ID
GCR_REPO="your-container-registry" # Replace with your GCR repository name, e.g., "gcr.io/project-id"
OLDER_THAN_DAYS=30 # Number of days to consider for deletion
# Default mode is actual deletion
DRY_RUN=false
# Function to display usage
usage() {
echo "Usage: $0 [--dry-run]"
echo ""
echo "Options:"
echo " --dry-run Simulate deletions without removing any images."
echo " -h, --help Display this help message."
exit 1
}
# Parse command-line arguments
while [[ "$#" -gt 0 ]]; do
case $1 in
--dry-run)
DRY_RUN=true
shift
;;
-h|--help)
usage
;;
*)
echo "Unknown parameter passed: $1"
usage
;;
esac
done
# Set the project
gcloud config set project "${PROJECT_ID}"
# Get the current date and calculate the cutoff date
CUTOFF_DATE=$(date -d "-${OLDER_THAN_DAYS} days" +%s)
# Fetch all images in the GCR repository
echo "Fetching images from ${GCR_REPO}..."
IMAGES=$(gcloud container images list --repository="${GCR_REPO}" --format="value(NAME)")
if [[ -z "$IMAGES" ]]; then
echo "No images found in the repository: ${GCR_REPO}."
exit 0
fi
# Iterate through each image and check tags
for IMAGE in $IMAGES; do
echo "Processing image: $IMAGE"
# Get all tags for the image in JSON format
TAGS=$(gcloud container images list-tags "$IMAGE" --format="json")
if [[ "$TAGS" == "[]" ]]; then
echo "No tags found for $IMAGE. Skipping..."
continue
fi
# Process each tag
echo "$TAGS" | jq -c '.[]' | while read -r TAG; do
# Extract timestamp, digest, and tag name
TIMESTAMP=$(echo "$TAG" | jq -r '.timestamp.datetime')
DIGEST=$(echo "$TAG" | jq -r '.digest')
TAG_NAME=$(echo "$TAG" | jq -r '.tags[]?')
# Convert timestamp to seconds since epoch
TIMESTAMP_SECONDS=$(date -d "$TIMESTAMP" +%s)
# Check if the image is older than the cutoff date
if [[ $TIMESTAMP_SECONDS -lt $CUTOFF_DATE ]]; then
if $DRY_RUN; then
echo "[Dry-Run] Would delete: $IMAGE@$DIGEST (tag: $TAG_NAME, timestamp: $TIMESTAMP)"
else
echo "Deleting old image: $IMAGE@$DIGEST (tag: $TAG_NAME, timestamp: $TIMESTAMP)"
# Delete the specific digest
gcloud container images delete "${IMAGE}@${DIGEST}" --quiet --force-delete-tags
fi
else
echo "Skipping recent image: $IMAGE@$DIGEST (tag: $TAG_NAME, timestamp: $TIMESTAMP)"
fi
done
done
if $DRY_RUN; then
echo "Dry-run completed. No images were deleted."
else
echo "Cleanup completed."
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment