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_run
is 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
dry-run
vs without
With 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 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.
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