'How do I check if an image:tag exists in gitlab container registry

I know that this can be done with dockerhub. I want to know if there is something similar available for gitlab registry.

The use case is that, I have written a fabric script to revert a deployment to a particular tag provided by the user. Before actually pulling in the images, I want to know whether an image with the specified tag exists in the registry and warn the user accordingly.

I've searched in their documentation, but couldn't find anything.

Note: User here is the person who is deploying the code.



Solution 1:[1]

Update: I added a solution that works without access to the docker server (non-privileged mode) below.

Ok, here is a solution I came up with using the docker:stable image by enabling the experimental client features.

mkdir -p ~/.docker
"echo '{\"experimental\": \"enabled\"}' > ~/.docker/config.json"
docker  login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
docker  manifest inspect $IMGNAME:$IMGTAG > /dev/null && exit || true

The exit terminates the build script in case that tag already exists. Also you should be aware that ~/.docker/config.json is overwritten. That is also why the login must happen afterwards.

Update: Instead of writing to the config one can also set the DOCKER_CLI_EXPERIMENTAL environment variable to enabled. Thus the first two lines can be replaced with export DOCKER_CLI_EXPERIMENTAL=enabled

Update: If you don't have privileged mode turned on and thus no access to the docker-daemon, you can use the registry-api scripts provided by harbor ( Note that they are python2.). This comes handy if you are building a docker image using kaniko, where no access to the docker-daemon is needed.

Solution 2:[2]

Gitlab API can be used.

tag=tag_name
image=image_name
private_token=gitlab_private_token
project=project_number
repo_id=$(curl --header "PRIVATE-TOKEN: $private_token" "https://gitlab.com/api/v4/projects/$project/registry/repositories" | jq -c --arg regex ".*\\$image$" '.[] | select(.path | test($regex))'.id)

if [ $( curl --header "PRIVATE-TOKEN: $private_token" "https://gitlab.com/api/v4/projects/$project/registry/repositories/$repo_id/tags/$tag" | jq -r '.name' ) == "$tag" ] ; then
  echo "$tag exists"
else
  echo "$tag does not exist"
fi

Solution 3:[3]

So in addition to @fparaggio answer, I was looking for an image if it exist for the current branch, if exist then use the branch image, else use the latest tag as a base image

package:
  stage: package
  image:
    name: registry.gitlab.com/org/hak:kaniko-debug
    entrypoint: [""]
  retry:
    max: 2
  tags:
    - kubernetes
  interruptible: true
  script:
    - if [[ $( curl --insecure --header "PRIVATE-TOKEN:$GITLAB_TOKEN" https://gitlab.com/api/v4/projects/xxx/registry/repositories/xxx/tags/$CI_COMMIT_REF_SLUG | jq -r '.name' ) == "$CI_COMMIT_REF_SLUG" ]] ; then
      echo "$CI_COMMIT_REF_SLUG exists";
      export CODE_VERSION=$CI_COMMIT_REF_SLUG;
      else
      echo "tag for the branch $CI_COMMIT_REF_SLUG => $CI_COMMIT_REF_NAME does not exist, using latest";
      export CODE_VERSION="latest";
      fi

and then pass CODE_VERSION as docker build args

     -  /kaniko/executor
        --build-arg CACHE_IMAGE=$CI_REGISTRY_IMAGE/install
        --build-arg CODE_VERSION=$CODE_VERSION
        --dockerfile $CI_PROJECT_DIR/Dockerfile-release
        --destination $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG

you can find registry ID in the Gitlab UI, no need to make two API call.

https://gitlab.com/org/xyz/repository/container_registry/xxx

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 fparaggio
Solution 3 Adiii