Command To Delete All Image Versions of Artifact Registry Except Latest? - google-cloud-platform

I have a GitHub Action that pushes my image to Artifact Registry. This is the steps that authenticates and then pushes it to my Google Cloud Artifact Registry
- name: Configure Docker Client
run: |-
gcloud auth configure-docker --quiet
gcloud auth configure-docker $GOOGLE_ARTIFACT_HOST_URL --quiet
- name: Push Docker Image to Artifact Registry
run: |-
docker tag $IMAGE_NAME:latest $GOOGLE_ARTIFACT_HOST_URL/$PROJECT_ID/images/$IMAGE_NAME:$GIT_TAG
docker push $GOOGLE_ARTIFACT_HOST_URL/$PROJECT_ID/images/$IMAGE_NAME:$GIT_TAG
Where $GIT_TAG is always 'latest'
I want to add one more command that then purges all except the latest version. In this screenshot below, you see theres 2 images
I would like to remove the one that was 3 days ago as its not the one with the tag 'latest'.
Is there a terminal command to do this?

You may initially check through the filtered list of container images for your specific criteria.
gcloud artifacts docker images list --include-tags
Once you have the view of the images to be deleted, move to the following.
You may use the following command to delete an Artifact Registry container image.
gcloud artifacts docker images delete IMAGE [--async] [--delete-tags] [GCLOUD_WIDE_FLAG …]
A valid container image that can be referenced by tag or digest, has the format of
LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY-ID/IMAGE:tag
This command can fail for the following reasons:
Trying to delete an image by digest when the image is still tagged.
Add --delete-tags to delete the digest and the tags.
Trying to delete an image by tag when the image has other tags. Add
--delete-tags to delete all tags.
A valid repository format was not provided.
The specified image does not exist.
The active account does not have permission to delete images.
It is always recommended to check and reconfirm any deletion operations so you don’t lose any useful artifacts and data items.
Also check this helpful document here for Artifacts docker Image Deletion guidelines and some useful information on Managing Images.
As guillaume blaquiere mentioned you may have a look at this link which may help you.

Related

How to use custom Cloud Builders with images from Google Artifact Repository

How do I use a custom builder image in Cloud Build which is stored in a repository in Artifact Registry (instead of Container Registry?)
I have set up a pipeline in Cloud Build where some python code is executed using official python images. As I want to cache my python dependencies, I wanted to create a custom Cloud Builder as shown in the official documentation here.
GCP clearly indicates to switch to Artifact Registry as Container Registry will be replaced by the former. Consequently, I have pushed my docker image to Artifact Registry. I also gave my Cloud Builder Service Account the reader permissions to Artifact Registry.
Using the image in a Cloud Build step like this
steps:
- name: 'europe-west3-docker.pkg.dev/xxxx/yyyy:latest'
id: install_dependencies
entrypoint: pip
args: ["install", "-r", "requirements.txt", "--user"]
throws the following error
Step #0 - "install_dependencies": Pulling image: europe-west3-docker.pkg.dev/xxxx/yyyy:latest
Step #0 - "install_dependencies": Error response from daemon: manifest for europe-west3-docker.pkg.dev/xxxx/yyyy:latest not found: manifest unknown: Requested entity was not found.
"xxxx" is the repository name and "yyyy" the name of my image. The tag "latest" exists.
I can pull the image locally and access the repository.
I could not find any documentation on how to integrate these images from Artifact Registry. There is only this official guide, where the image is built using the Docker image from Container Registry – however this should not be future proof.
It looks like you need to add your Project ID to your image name.
You can use the "$PROJECT_ID" Cloud Build default substitution variable.
So your updated image name would look something like this:
steps:
- name: 'europe-west3-docker.pkg.dev/$PROJECT_ID/xxxx/yyyy:latest'
For more details about substituting variable values in Cloud Build see:
https://cloud.google.com/build/docs/configuring-builds/substitute-variable-values

How to duplicate/clone an image inside same AWS ECR repository with different tag?

I have an existing image inside an ECR repo with the tag "780" and I wanted to make a copy of it inside the same repo with the tag "781".
I tried executing the below commands which I found from here but that gives a new tag to the same image when given the same repo.
docker login REPO
docker pull REPO/IMAGE:TAG
docker tag REPO/IMAGE:TAG REPO/IMAGE:NEWTAG
docker push REPO/IMAGE:NEWTAG
Is there an API or utility (preferably in python) or any other way using which this can be achieved?
It's not possible to have two Docker images in the same repo with the same SHA256 hash. The Docker repository is saving space by detecting that they are the same image, so it is simply adding the tags to the image that already exists in the repo. This is working as intended.

Docker Image tagging in ECR

I am pushing docker image in AWS ECR using Jenkins.
While pushing the image I am providing tag as $Build_Number. So in ECR repo I have images with tags like 1,2,3,4.
But when I am trying to pull the image from EC2 with below command from Jenkins job
docker pull 944XXX.dkr.ecr.us-east-1.amazonaws.com/repository1:latest
I am getting an error as there is no image with tag as latest.
Here I want to pull the latest image (with tag 4). I cannot hard-code tag number here as docker pull command will run from Jenkins job automatically. So what way can I pull the latest image?
I believe that the correct approach here would be to push the same image twice with different tags. One push would include the image with no tag and then the second push would be the same image after you have tagged it.
Note that you don't have to build the image twice. You only need to issue the docker push twice.
ECR is "smart" enough to recognise that the image digest did not change and it will not try to actually upload the image twice. On the second push only the tag will be send to ECR.
Now that you have an untagged version and a tagged version, you can pull the image without the tag specification and you will get the :latest image. Here is a reference to the AWS docs where they mention that the :latest tag will be added if no tag was sent by the user.
The flow would look something like this:
# Build the image
docker build -f ./Dockerfile -t my-web-app
# Push the untagged image (will become the ":latest")
docker push my-web-app
# Tag the image with your build_number
docker tag my-web-app my-web-app:build_number
# Push the tagged image
docker push my-web-app:build_number
You will now be able to:
docker pull my-web-app:build_number
docker pull my-web-app
Which will result in 2 identical images with only the tag differentiating between them.
one solution is suggested by #Lix that you can try, or if you are interested with just latest pushed image and no matter whats the tag of a latest image then you can get the latest image from AWS-CLI.
So your Jenkins job command will be
TAG=$(aws ecr describe-images --output json --repository-name stage/redis --query 'sort_by(imageDetails,& imagePushedAt)[-1].imageTags[0]' | jq . --raw-output)
docker pull 944XXX.dkr.ecr.us-east-1.amazonaws.com/repository1:$TAG
aws-cli-ecr-list-images-get-newest
If you want a latest tag on ECR, you need to add it and push it there when you build the image. You can use the -t to docker build multiple times (see https://docs.docker.com/v17.09/engine/reference/commandline/build/); just make sure to push them all.

Moving images from Docker registry to GCR

Google cloud run does not support the docker registry, therefore I have to manually pull the image, tag it and push it to GCR.
Container image URL should match pattern [region.]gcr.io/repo-path[:tag or #digest]
Is there any simpler way to do this?
Sadly, that's the easiest way to move a Docker image from one container registry to another one.
Just for documentation purposes, I will add the steps for the benefit of the community:
Pull the Docker image using the following command:
docker pull [REPOSITORY-NAME]/[IMAGE]:[TAG]
Then, tag that pulled image using the following command:
docker tag [IMAGE] gcr.io/[PROJECT-ID]/[IMAGE]
Push that image to your gcr repository using the following command:
docker push gcr.io/[PROJECT-ID]/[IMAGE]
I'm afraid in any case, "simpler" won't be a thing. Though, you may try to use Docker web hooks to call a simple Cloud function (pull, tag, push) in order to keep your images in sync in your GCR.
There seems to be some projects to manage that kind of hassle like dregsy but I didn't try them...
I've been working on some tooling called regclient that supports this use case. For copying a single image, the command would be:
regctl image copy ${source} ${target}
e.g.
regctl image copy ubuntu:latest gcr.io/your-project/ubuntu:latest
This checks the digests before copying with a HEAD request to allow the command to be run frequently but only using your quota when the upstream image doesn't match what's on GCR. It also copies multi-platform images which you wouldn't get with a docker pull and docker push (docker dereferences the image to your platform on the pull). And unlike the docker pull, the individual layers are only copied when they don't exist on the target registry.
If you have lots of images to continuously mirror, there's also a regsync command that copies according to a yaml file with a list of images, tags, and schedule to run the copies.
These can run as containers, but they are also available as standalone binaries that don't require docker to run.

Google cloud build cli - get artifact URL while build is ongoing

I'm using a Google cloud build trigger to build my container image. After pushing a new build (push by git tag), I can see it on my Cloud Build history.
As you can see, the build already has an artifact URI (the URI of the image). But, when calling the gcloud build list - it's not there:
It only appears in the IMAGE column AFTER the building is completed.
How to get the artifact build while building?
IIUC, builds and artifacts are different things.
When you submit gcloud builds, you're creating build(job)s that are identified by build IDs.
Builds may result in the creation of artifacts (usually -- but not limited to-- container images). It is only during the conclusion of a build that artifacts are generated and so you would not expect these to be available until then.
steps:
- name: "gcr.io/cloud-builders/docker"
args:
- build
- -t
- "gcr.io/your-project/your-image
- .
images:
- "gcr.io/your-project/your-image"
Or:
artifacts:
objects:
location: [STORAGE_LOCATION]
paths:
- [ARTIFACT_PATH]
- [ARTIFACT_PATH]
- ...
Because you specify images|artifacts in your build spec, you can infer (before these are created), where they will result and you could query them directly then. In the case of container images pushed, you may query these using gcloud container images list, perhaps (per the above) gcloud container image list --repository=gcr.io/your-project
See:
https://cloud.google.com/cloud-build/docs/configuring-builds/store-images-artifacts#artifacts_examples
HTH!