feat(api/gitlab/v1): add rename repository endpoint
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_runis not specified or is specified and set tofalse - 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.
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.
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 Entityresponse
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.
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
pullscope:scope=repository:{{repository-path}}:pullfrom 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