Skip to content

Use the Container Registry API when fetching a single repository tag

What does this MR do and why?

We have new container registry APIs that are available for use for migrated container repositories. We want to gradually migrate to the use of these new APIs. In this MR, we introduce a new feature that fetches the container registry tag from the Gitlab API for migrated repositories.

With this change, we want to update the Get details of a registry repository tag API of the Gitlab API such that it fetches the tag from the container registry API if it is migrated.

We introduce this change behind the feature flag fetch_tag_info_from_registry to be able to toggle the feature and release it gradually.

In the old implementation, given a name, a tag is instantiated. This tag may or may not be existent. Only when calling tag.valid? in API::ProjectContainerRepositories, will we know if it was an existing tag or not. tag.valid? originally checks if a manifest exists or not. A manifest is what is fetched in the old implementation from the /v2 API that contains the information for the tag. So if this does not exist then there was no tag found. With this new API available, we can already prefill the tag with the information and we don't have a manifest to check. On this, we have added a from_api? attribute to the Tag model and when this is true, we know that the tag information was fetched from the API and that is is valid and existing.

How to set up and validate locally

For the feature to be enabled, we need to simulate that we have migrated repositories. For now, only Gitlab.com is recognized as migrated but we can update the check to simulate that our local setup is also migrated. Update the following method in app/models/container_repository.rb and add true ||

def migrated?
  true || Gitlab.com_except_jh?
end

Make sure to also have the container registry running and that you have tags available.

  1. First, we try to call the Gitlab API while the feature flag is disabled to see the original implementation. Run the following command in your terminal (your personal access token should have access to the project and the container registry):
curl --header "PRIVATE-TOKEN: <your-personal-access-token-here>" \
     "http://gdk.test:3000/api/v4/projects/<project-id>/registry/repositories/<repository id>/tags/<tag-name>"

You may find the project id and repository id via the Rails Console.

The result would look something like:

{"name":"latest","path":"october-group/proj-lalalo:latest","location":"registry.test:5000/october-group/proj-lalalo:latest","revision":"8ac438ac5ec8f4f2ec2ac99afa64a514","short_revision":"8ac438ac5","digest":"sha256:02399a844fe2a1e4ce421decfb31ca938","created_at":"2023-12-20T17:19:17.843+00:00","total_size":185117038}
  1. In the Rails console, we then enable the feature fully
Feature.enable(: fetch_tag_info_from_registry)

And we can verify that the new behaviour would indeed kick in. We can run the following in the Rails Console and it should return true:

repository = ContainerRepository.find(<repository-id>)

repository.migrated? &&
Feature.enabled?(:fetch_tag_info_from_registry, repository.project, type: :gitlab_com_derisk) &&
ContainerRegistry::GitlabApiClient.supports_gitlab_api?
  1. Now that the new feature is enabled, we can run the same curl command above and verify that the curl command still works
curl --header "PRIVATE-TOKEN: <your-personal-access-token-here>" \
     "http://gdk.test:3000/api/v4/projects/<project-id>/registry/repositories/<repository id>/tags/<tag-name>"

Related to #432472 (closed)

Edited by Adie (she/her)

Merge request reports