Skip to content

feat(api/gitlab/v1): add rename repository endpoint

Suleimi Ahmed requested to merge 894-introduce-rename-repository-api into master

Related to #894 (closed)

Summary 🌱

This MR builds on !1220 (merged) to expose an API endpoint to conduct renames of container repositories from GitLab rails only.

The new endpoint is of the form PATCH http://{{registry-host}}/gitlab/v1/repositories/{{repository-to-rename}}/?dry_run={true|false} and uses a JSON request payload of {"name": "new-name"} to communicate the new name of the identified repository in the request route (i.e {{repository-to-rename}}).

The endpoint is only partially complete as it requires the reliance on "repository-lease" to guarantee data consistency (see #896 (closed) for more context).

We will iterate on the endpoint introduced here when tackling #895 (closed) to guarantee data consistency with "repository-rename-leases". There are no plans to roll out this endpoint (to GitLab rails) until the complete solution is in place (i.e until Rename a base container repository (and all sub... (#897 - closed) is completed) And because of this, documentation of how the endpoint should/would work will only be available once the feature is ready for use by the GitLab rails.

Note: This MR does not include adding the API documentation of the endpoint, the documentation MR will come when the feature is complete and is ready to be used.

Cases a rename will not happen

As mentioned in #894 (closed), the following cases will block a rename:

  • Repository to be renamed contains more than 1000 sub-repositories
  • A conflict, the name is taken by another repository
  • The query option dry_run is not specified or is specified and set to false
  • Non-GitLab Rails request (i.e requests without the pull scopes of {{repository-path}}/* and{{repository-path}}, AND the push scope of {{repository-path}} see: #924 (moved) )

Demo 📺

Click to expand

With dry-run vs without

Shows the flow for a dry-run rename request and a non-dry-run rename request. Also shows what happens when rename request conflicts with an existing repository and when the repository to be renamed does not exist.

rename-1-demo

Setup

  • Create a repository (and maybe a few sub-repositories <=1000 under the base repository) in the container registry. You can do this by pushing a random images to a base repository (or the base repository's sub-repositories). for example:
docker pull alpine:latest
docker tag alpine:latest registry:5000/test/alpine:latest
docker push registry:5000/test/alpine:latest
for i in `seq 1 2`;  do docker tag alpine:latest test/alpine/${i}:latest; docker push test/alpine/${i}:latest; done
  • Make a request to rename the base repository PATCH http://{{registry-host}}/gitlab/v1/repositories/test/not-alpine/?dry_run={{true|false}}, with body {"name": "new-name"}
  • Verify the repository and its sub-repositories were renamed or not

Repository to be renamed exceeds 1000 sub-repositories limit

Shows the flow for a rename request to a repository that exceeds 1000 sub-repositories.

rename-2-demo

Setup

  • Create a repository with >1000 sub-repositories. You can do this by pushing a random images to a base repository and the base repository's sub-repositories. for example:
docker pull alpine:latest
docker tag alpine:latest registry:5000/test/alpine:latest
docker push registry:5000/test/alpine:latest
for i in `seq 1 1001`;  do docker tag alpine:latest registry:5000/test/alpine/${i}:latest; docker push registry:5000/test/alpine/${i}:latest; done
  • Make a request to rename the base repository http://{{registry-host}}/gitlab/v1/repositories/test/not-alpine/?dry_run={{true|false}}
  • Verify the repository and its sub-repositories could not be renamed with a 422 Unprocessable Entity response

Wrong JWT scope (i.e non-GitLab rails request)

Shows the flow for a rename request that does not have the necessary JWT scopes to access the endpoint.

rename-3-demo

Setup

  • Setup and start gdk with the registry built from this git branch
  • Push an image to a project with container-repository enabled in your gdk, e.g
docker pull alpine:latest
docker tag alpine:latest {{registry-gdk-host}}/{{repository-path}}:latest
docker push {{registry-gdk-host}}/{{repository-path}}:latest
  • Obtain a token with pull scope: scope=repository:{{repository-path}}:pull from the authentication service started with gdk e.g: GET http://{{gittlab-api-host}}/jwt/auth?service=container_registry&scope=repository:{{repository-path}}:pull (remember to pass in the necessary Auth Header for the user).
  • Make a request to rename the base repository http://{{registry-host}}/gitlab/v1/repositories/test/not-alpine/?dry_run={{true|false}}
  • Verify the request is denied, and the response lists the required scopes
Edited by Suleimi Ahmed

Merge request reports