14

When we push repeatedly into gcr.io with the same image name and a version (tag), there is a high number of untagged images.
Is there a simple way to remove all untagged images for a single image using the gcloud CLI tool to avoid incurring Storage costs?

Ninjaxor
  • 876
  • 12
  • 27
Robert Lacok
  • 4,176
  • 2
  • 26
  • 38

7 Answers7

15

gcloud container images list-tags gcr.io/project-id/repository --format=json --limit=unlimited will give you an easily consumable json blob of info for images in a repo (such as digests w/ associated tags).

In order to just enumerate all digests which lack tags:

gcloud container images list-tags gcr.io/project-id/repository --filter='-tags:*' --format='get(digest)' --limit=unlimited

Which you can iterate over and delete with: gcloud container images delete --quiet gcr.io/project-id/repository@DIGEST

jsand
  • 595
  • 4
  • 8
10

Handy when you glue them together with awk and xargs

gcloud container images list-tags gcr.io/${PROJECT_ID}/${IMAGE} --filter='-tags:*' --format='get(digest)' --limit=unlimited | awk '{print "gcr.io/${PROJECT_ID}/${IMAGE}@" $1}' | xargs gcloud container images delete --quiet

sffc
  • 6,186
  • 3
  • 44
  • 68
nuzz
  • 101
  • 1
  • 3
6

The previous one-liner was not working for me. I am using this one at the moment:

  • Deletes all the un-tagged images for a given PROJECT_ID and IMAGE
  • Uses Xargs -I, which creates a token (called {arg} in this case)
gcloud container images list-tags gcr.io/${PROJECT_ID}/${IMAGE} \
    --filter='-tags:*' --format='get(digest)' --limit=unlimited |\
  xargs -I {arg} gcloud container images delete \
    "gcr.io/${PROJECT_ID}/${IMAGE}@{arg}" --quiet
Shawn Hemelstrand
  • 2,676
  • 4
  • 17
  • 30
Benos
  • 676
  • 7
  • 17
  • Thanks, the other answer wasn't working for me either on my bash shell because the ENV var wasn't interpolating within single quotes. – Ninjaxor Jan 22 '23 at 18:33
1

My use case was to delete all untagged images from a specific project. I wrote simple script to achieve this:

delete_untagged() {
    echo "   |-Deleting untagged images for $1"
    while read digest; do
       gcloud container images delete $1@$digest --quiet 2>&1 | sed 's/^/        /'
    done < <(gcloud container images list-tags $1 --filter='-tags:*' --format='get(digest)' --limit=unlimited)
}

delete_for_each_repo() {
    echo "|-Will delete all untagged images in $1"
    while read repo; do
        delete_untagged $repo
    done < <(gcloud container images list --repository $1 --format="value(name)")
}

delete_for_each_repo gcr.io/<project-id>/<repository>

The full script can be found here: https://gist.github.com/lahsivjar/2b011d69368a26af7043d4aa70ec78f8

Hope it will be helpful to someone

lahsivjar
  • 29
  • 5
1

It is documented here but one important thing to be noted is that

DIGEST must be of the form "sha256:<digest>"

So catch first the form sha256:<digest> of untagged images

$ DIGEST=`gcloud container images list-tags gcr.io/[PROJECT-ID]/[IMAGE] \
--filter='-tags:*' --format='get(digest)'`
$ echo $DIGEST
sha256:7c077a9ca45aea7134d8436a3071aceb5fa62758cc86eadec63f02692b7875f7

Then use the variable to remove it

$ gcloud container images delete --quiet gcr.io/[PROJECT-ID]/[IMAGE]@$DIGEST
Digests:
- gcr.io/[PROJECT-ID]/[IMAGE]@sha256:7c077a9ca45a......
Deleted [gcr.io/[PROJECT-ID]/[IMAGE]@sha256:7c077a9ca45a......].
eQ19
  • 9,880
  • 3
  • 65
  • 77
1

Powershell version of the one liner posted by @Benos

gcloud container images list-tags gcr.io/myprojectname/myimagename --filter='-tags:*' --format='get(tags)' --limit=unlimited | ForEach-Object { gcloud container images delete "gcr.io/myprojectname/myimagename:$PSItem" --quiet } 

Remove the --filter='-tags:*' to delete all tags of a certain image (this is what I was trying to accomplish)

Dave
  • 2,774
  • 4
  • 36
  • 52
0

Corrected Powershell Command

gcloud container images list-tags gcr.io/myprojectname/myimagename --filter='-tags:*' --format='get(digest)' --limit=unlimited | ForEach-Object { gcloud container images delete "gcr.io/myprojectname/myimagename@$PSItem" --quiet }
MattyBoy
  • 25
  • 5