Search code examples
imagerepositorygcloudexcept

How to delete all images in all repositories except in one repository named "devops" in gcloud platform


I have the code to delete all images in a repository except the latest 6 images,but i want to take the script to next level which deletes all images in repositories except a repository named "devops"..

IFS=$'\n\t'
set -eou pipefail

if [[ "$#" -ne 2 || "${1}" == '-h' || "${1}" == '--help' ]]; then
    cat >&2 <<"EOF"

EOF
    exit 1
# elif [ ${2} -ge 0 ] 2>/dev/null; then
#     echo "no number of images to remain given" >&2
#     exit 1
fi

main() {
    local C=0
    IMAGE="${1}"
    NUMBER_OF_IMAGES_TO_REMAIN=$((${2} - 1))

    DATE=$(gcloud container images list-tags $IMAGE --limit=unlimited \
        --sort-by=~TIMESTAMP --format=json | TZ=/usr/share/zoneinfo/UTC jq -r '.['$NUMBER_OF_IMAGES_TO_REMAIN'].timestamp.datetime | sub("(?<before>.*):"; .before ) | strptime("%Y-%m-%d %H:%M:%S%z") | mktime | strftime("%Y-%m-%d")')

    for digest in $(gcloud container images list-tags $IMAGE --limit=unlimited --sort-by=~TIMESTAMP \
        --filter="timestamp.datetime < '${DATE}'" --format='get(digest)'); do
        (
            set -x
            gcloud container images delete -q --force-delete-tags "${IMAGE}@${digest}"
        )
        let C=C+1
    done
    echo "Deleted ${C} images in ${IMAGE}." >&2
}

main "${1}" ${2}```

Solution

  • It's confusing but, Google Container Registry differs from other Google Cloud Platform services in that it represents an implementation of a 3rd-party (Docker) Registry API.

    For this reason, there is no set of Google (!) client libraries for managing images in Container Registry and unlike almost every other gcloud command, gcloud container images commands call Google's implementation of the Docker Registry APIs. You can observe this by appending --log-http to gcloud container images commands.

    All this to say that there is no Google Python SDK for interacting with this service.

    Another quirk is that Google Cloud Platform projects own Google Container Registry registries but the mapping is non-trivial. It is often gcr.io/${PROJECT} but can be us.gcr.io/${PROJECT}. The following script assumes (!) gcr.io/${PROJECT}

    The code that you include in your question is bash. In that spirit (and given the above), here's a script that does what you need.

    Please be very careful as, if you include the delete command, this script will irrevocably delete all images in every project except ${EXCLUDE}

    PROCEED WITH CARE

    Unsafe

    # Exclude this project
    EXCLUDE="devops"
    
    PROJECTS=$(gcloud projects list --format="value(projectId)")
    
    # Projects accessible to current user
    for PROJECT in ${PROJECTS}
    do
      printf "Project: %s\n" ${PROJECT}
      if [ "${PROJECT}" == "${EXCLUDE}" ]
      then
        printf "Excluding Repository: %s\n" ${PROJECT}
      else
        printf "Including Repository: %s\n" ${PROJECT}
        # Images in ${PROJECT} repository
        IMAGES=$(gcloud container images list --project=${PROJECT})
        for IMAGE in ${IMAGES}
        do
          printf "Deleting Image: %s\n" ${IMAGE}
          # Image delete command goes here
        done
      fi
    done
    

    Unsafer

    Replace the # comment with:

    gcloud container images delete ${IMAGE} --project=${PROJECT}
    

    Unsafest

    Replace the # comment with:

    gcloud container images delete ${IMAGE} --project=${PROJECT} --quiet
    

    Less Awful

    It would be less risky to provide the script with a list of Projects (Repositories) that you wish to be included in the purge. But, this script is still dangerous:

    # Include these projects
    PROJECTS=("first" "second" "third")
    
    # Projects accessible to current user
    for PROJECT in ${PROJECTS[@]}
    do
      printf "Including Repository: %s\n" ${PROJECT}
      # Images in ${PROJECT} repository
      IMAGES=$(gcloud container images list --project=${PROJECT})
      for IMAGE in ${IMAGES}
      do
        printf "Deleting Image: %s\n" ${IMAGE}
        # Image delete command goes here
      done
    fi
    

    To reiterate PLEASE PROCEED WITH CARE

    Deleting Images is irrevocable and you will be unable to recover deleted images