15

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.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Dineshs91
  • 2,044
  • 1
  • 25
  • 24
  • Check out GitLab 13.0 (May 2020): there is no GUI search for docker images in GitLab. See [my edited answer below](https://stackoverflow.com/a/47663239/6309). – VonC May 22 '20 at 23:24

5 Answers5

12

Hint: Also have a look at @filiprafaj's answer using crane.

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

Morty
  • 2,889
  • 2
  • 19
  • 28
  • Beware you may be using stable but you are still enabling experimental features, of which `docker manifest inspect` is one – Mark Tickner Sep 03 '18 at 11:04
  • @MarkTickner Yes you are right, yet I don't think that this is a real issue, as while the command line parameters may change, I don't think the functionality will be removed. – Morty Sep 03 '18 at 17:26
  • On Ubuntu 19.04, you get the error “docker manifest inspect is only supported on a Docker cli with experimental cli features enabled”. – Torsten Bronger Oct 24 '19 at 06:53
  • @TorstenBronger: Did you carefully look at the second line? – Morty Oct 29 '19 at 08:16
  • @morty Yes, I did, but running your mini script gave that error message. – Torsten Bronger Oct 29 '19 at 12:59
  • @TorstenBronger: That's strange indeed. Are you using a vanilla image or are you doing any magic like changing the user or or other setting? – Morty Nov 12 '19 at 10:02
7

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
fparaggio
  • 393
  • 4
  • 12
  • I found that the jq regexp wasn't needed / didn't work, but you can just extract the id key directly like this: `repo_id=$(curl --header "PRIVATE-TOKEN: $private_token" "https://gitlab.com/api/v4/projects/$project/registry/repositories" | jq '.[0].id')` – Tyler Rick May 28 '20 at 03:07
  • 1
    That is not equivalent though since it ignores `$image`. Correct should be `repo_id=$(curl --header "PRIVATE-TOKEN: $private_token" "https://gitlab.com/api/v4/projects/$project/registry/repositories" | jq '.[] | select(.name==env.image) | .id` – renefritze Nov 12 '20 at 16:10
5

Unless the GitLab Container Registry supports the kind of curl dockerhub does (with v1/repositories/$1/tags/$2), I doubt it offers that feature.

For instance, issue 26866 "GitLab Registry available images list/search" is still open after 10 months.

Update for GitLab 12.2 (April 2019, 18 months later)

After working through the implementation, it made sense to create two endpoints:

  • GET /groups/:id/registry/repositories - Returns a list of all Docker container repositories for all projects within the group, similar to GET /projects/:id/registry/repositories

and

  • GET /groups/:id/registry/repositories/tags - Returns a list of all Docker container repositories for all projects within the group including all tags for each container repository. The response will look something like this:

So that could help checking if an image:tag exists.


Update GitLab 13.0 (May 2020)

Use search to quickly find and discover images hosted in the GitLab Container Registry

When you or someone on your team publishes an image to the GitLab Container Registry, you need a way to quickly find it and ensure the image was built properly.
If you’re using GitLab CI/CD to publish images with each build, it’s been very difficult to find an image efficiently within the current user interface. Instead, you’ve relied on the command line or the API.

We are excited to announce that in 13.0, we’ve added search functionality to the GitLab Container Registry.

Simply navigate to your project or group’s registry and enter an image name to see a list of all your images.

https://docs.gitlab.com/ee/user/packages/container_registry/img/container_registry_repositories_with_quickstart_v13_0.png

See documentation and issue.


See also GitLab 14.7 (January 2022)

Sort Docker tags in the Container Registry browser

You can now sort the list of tags in the Container Registry tag details page by name.

Previously, there was no sort functionality. This sometimes required you to scroll through many pages to find a specific tag.

By default, the tags list is now sorted by name in ascending order. You may also change the sort order to descending.
See this issue to track any further work on tag sorting.

See Documentation and Issue.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
2

Crane is a tool that might help. Below is an example, where crane manifest is used inside Gitlab CI/CD Pipeline (.gitlab-ci.yml file).

check_if_image_exists:
  stage: check_if_image_exists
  image:
    name: gcr.io/go-containerregistry/crane:debug
    entrypoint: [""]
  script:
    - crane auth login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - if crane manifest $CI_REGISTRY_IMAGE/image:tag; then echo "exists"; else echo "not exists"; fi
filiprafaj
  • 105
  • 2
  • 8
  • Just in case someone wonders how to use this in a pipeline: Put Crane's result in an artifact and in the next build-step, build the image based on the the contents of the artifact. – Morty Mar 17 '23 at 16:17
0

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

Adiii
  • 54,482
  • 7
  • 145
  • 148