容器仓库 API

从 13.12 版本开始,CI_JOB_TOKEN 的使用范围仅限于当前项目。

这里是极狐GitLab 容器仓库的 API 文档。

ci_job_token_scope 功能标志打开的时候(默认禁用),您可以通过传递 $CI_JOB_TOKEN 变量作为 JOB-TOKEN 头部,在 CI/CD 作业里使用下面的端点。 作业令牌只有访问自身所在项目的权限。

有权访问 Rails 控制台的管理员可以选择性的启用它。

要启用它:

Feature.enable(:ci_job_token_scope)

要禁用它:

Feature.disable(:ci_job_token_scope)

修改容器仓库的可见性

引入于 14.2 版本。

这个功能是用来控制谁可以查看容器仓库。

PUT /projects/:id/
参数 类型 是否必需 描述
id integer/string yes 可以被经过身份验证的用户访问的 ID 或项目的 URL 编码路径
container_registry_access_level string no 容器仓库所需的可见性,enabledprivatedisabled 三者之一。

container_registry_access_level 可能的值对应的描述:

  • enabled (默认):容器仓库对可以访问这个项目的所有人可见,如果这个项目是公开的,那么容器仓库也是公开的。如果项目是内部的或者私有的,容器仓库也是内部或者私有的。
  • private:容器仓库仅对具有报告者或更高角色的项目成员可见。这个和项目是私有的,同时设置了容器仓库可见性为 enabled 时的表现一致。
  • disabled:禁用了容器仓库。

查看容器仓库可见性权限一文里更多关于这个设置授予用户的权限的细节。

curl --request PUT "https://gitlab.example.com/api/v4/projects/5/" \
     --header 'PRIVATE-TOKEN: <your_access_token>' \
     --header 'Accept: application/json' \
     --header 'Content-Type: application/json' \
     --data-raw '{
         "container_registry_access_level": "private"
     }'

响应示例:

{
  "id": 5,
  "name": "Project 5",
  "container_registry_access_level": "private",
  ...
}

容器镜像库分页

默认情况下,GET 请求一次返回 20 个结果,因为 API 结果是分页的

列出仓库内存储库

项目内部

获取项目内的仓库里的存储库列表

GET /projects/:id/registry/repositories
参数 类型 是否必需 描述
id integer/string yes 可以被经过身份验证的用户访问的 ID 或项目的 URL 编码路径
tags boolean no 如果包含这个参数,且是 true,那么在响应里的每个存储库包含一个 "tags" 数组。
tags_count boolean no 如果包含这个参数,且是 true,那么在响应里的每个存储库包含 "tags_count"
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/registry/repositories"

响应示例:

[
  {
    "id": 1,
    "name": "",
    "path": "group/project",
    "project_id": 9,
    "location": "gitlab.example.com:5000/group/project",
    "created_at": "2019-01-10T13:38:57.391Z",
    "cleanup_policy_started_at": "2020-01-10T15:40:57.391Z"
  },
  {
    "id": 2,
    "name": "releases",
    "path": "group/project/releases",
    "project_id": 9,
    "location": "gitlab.example.com:5000/group/project/releases",
    "created_at": "2019-01-10T13:39:08.229Z",
    "cleanup_policy_started_at": "2020-08-17T03:12:35.489Z"
  }
]

群组内

tagstag_count 属性移除于 15.0 版本。

在群组内获取仓库里的存储库列表。

GET /groups/:id/registry/repositories
参数 类型 是否必需 描述
id integer/string yes 可以被经过身份验证的用户访问的 ID 或群组的 URL 编码路径
curl --header "PRIVATE-TOKEN: <your_access_token>" \
     "https://gitlab.example.com/api/v4/groups/2/registry/repositories"

响应示例:

[
  {
    "id": 1,
    "name": "",
    "path": "group/project",
    "project_id": 9,
    "location": "gitlab.example.com:5000/group/project",
    "created_at": "2019-01-10T13:38:57.391Z",
    "cleanup_policy_started_at": "2020-08-17T03:12:35.489Z",
  },
  {
    "id": 2,
    "name": "",
    "path": "group/other_project",
    "project_id": 11,
    "location": "gitlab.example.com:5000/group/other_project",
    "created_at": "2019-01-10T13:39:08.229Z",
    "cleanup_policy_started_at": "2020-01-10T15:40:57.391Z",
  }
]

获取单个存储库的细节

引入于 13.6 版本。

获取仓库里某个存储库的细节。

GET /registry/repositories/:id
参数 类型 是否必需 描述
id integer/string yes 经过身份验证的用户可以访问的仓库里的存储库的 ID。
tags boolean no 如果包含这个参数,且是 true,那么在响应里的每个存储库包含一个 "tags" 数组。
tags_count boolean no 如果包含这个参数,且是 true,那么响应里包含 "tags_count"
size boolean no 如果包含这个参数,且是 true,那么响应里包含 "size"。这是存储库里所有镜像去重后的大小。去重消除了完全相同的数据的额外副本。例如,如果你上传了相同的镜像两次,容器仓库只存储一个副本。
curl --header "PRIVATE-TOKEN: <your_access_token>" \
     "https://gitlab.example.com/api/v4/registry/repositories/2?tags=true&tags_count=true&size=true"

响应示例:

{
  "id": 2,
  "name": "",
  "path": "group/project",
  "project_id": 9,
  "location": "gitlab.example.com:5000/group/project",
  "created_at": "2019-01-10T13:38:57.391Z",
  "cleanup_policy_started_at": "2020-08-17T03:12:35.489Z",
  "tags_count": 1,
  "tags": [
    {
      "name": "0.0.1",
      "path": "group/project:0.0.1",
      "location": "gitlab.example.com:5000/group/project:0.0.1"
    }
  ],
  "size": 2818413
}

删除仓库里的存储库

删除仓库里的某个存储库。

这个操作是异步执行的,因此需要花费一些时间来执行。

DELETE /projects/:id/registry/repositories/:repository_id
参数 类型 是否必需 描述
id integer/string yes 可以被经过身份验证的用户访问的 ID 或项目的 URL 编码路径
repository_id integer yes 仓库里存储库的 ID。
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" \
     "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2"

列出仓库里存储库的标签

在项目内部

获取给定仓库里的某个存储库标签列表。

GET /projects/:id/registry/repositories/:repository_id/tags
参数 类型 是否必需 描述
id integer/string yes 可以被经过身份验证的用户访问的 ID 或项目的 URL 编码路径
repository_id integer yes 仓库里存储库的 ID。
curl --header "PRIVATE-TOKEN: <your_access_token>" \
     "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags"

响应示例:

[
  {
    "name": "A",
    "path": "group/project:A",
    "location": "gitlab.example.com:5000/group/project:A"
  },
  {
    "name": "latest",
    "path": "group/project:latest",
    "location": "gitlab.example.com:5000/group/project:latest"
  }
]

获取仓库里存储库的某个标签的详情

获取仓库里某个存储库的某个标签的详情。

GET /projects/:id/registry/repositories/:repository_id/tags/:tag_name
参数 类型 是否必需 描述
id integer/string yes 可以被经过身份验证的用户访问的 ID 或项目的 URL 编码路径
repository_id integer yes 仓库里存储库的 ID。
tag_name string yes 标签的名称
curl --header "PRIVATE-TOKEN: <your_access_token>" \
     "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags/v10.0.0"

响应示例:

{
  "name": "v10.0.0",
  "path": "group/project:latest",
  "location": "gitlab.example.com:5000/group/project:latest",
  "revision": "e9ed9d87c881d8c2fd3a31b41904d01ba0b836e7fd15240d774d811a1c248181",
  "short_revision": "e9ed9d87c",
  "digest": "sha256:c3490dcf10ffb6530c1303522a1405dfaf7daecd8f38d3e6a1ba19ea1f8a1751",
  "created_at": "2019-01-06T16:49:51.272+00:00",
  "total_size": 350224384
}

删除仓库里存储库的某个标签

删除仓库里存储库的某个标签。

DELETE /projects/:id/registry/repositories/:repository_id/tags/:tag_name
参数 类型 是否必需 描述
id integer/string yes 可以被经过身份验证的用户访问的 ID 或项目的 URL 编码路径
repository_id integer yes 仓库里存储库的 ID
tag_name string yes 标签的名称
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" \
     "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags/v10.0.0"

这个动作不会删除 blobs。要删除他们并回收磁盘空间,运行垃圾回收

在 bulk 里删除仓库里存储库的标签

基于给定的标准在 bulk 里删除仓库里存储库的标签。

DELETE /projects/:id/registry/repositories/:repository_id/tags
参数 类型 是否必需 描述
id integer/string yes 可以被经过身份验证的用户访问的 ID 或项目的 URL 编码路径
repository_id integer yes 仓库里存储库的 ID。
name_regex string no 要删除的名称的 re2 正则表达式。要删除所有标签,使用.*注意:name_regex 已经废弃了,请使用name_regex_delete。此字段已验证。
name_regex_delete string yes 要删除的名称的 re2 正则表达式。要删除所有标签,使用.*。此字段已验证。
name_regex_keep string no 要保留的名称的 re2 正则表达式。这个值会覆盖任何匹配name_regex_delete的标签名。这个字段已验证。注意:设置为 .* 会导致不做任何操作。
keep_n integer no 要保留的给定名称的最新标签的数量。
older_than string no 早于这个给定时间的标签会被删除,以人类可读的方式书写,例如:1h, 1d, 1month

这个 API 返回 HTTP 响应状态码 202,如果成功,然后执行下面的操作:

  • 通过创建日期将所有标签排序,创建日期是清单的创建时间,不是标签推送的时间。
  • 会仅删除匹配给定的 name_regex_delete 字段的标签(或废弃的 name_regex),保留匹配 name_regex_keep 的标签。
  • 永远不会移除名为 latest 的标签。
  • 保留 N 个最新的匹配标签(如果指定了 keep_n)。
  • 只会移除早于 X 时间的标签。(如果指定了 older_than)。
  • 会在后台调度异步任务执行。

这些操作都是异步的,会需要花费一些时间去执行。对于给定的容器存储库,一个小时最多只能运行一次。

caution如果您的容器仓库有大量标签需要删除,只会删除它们中的一部分。因此你可能需要多次调用这个 API 。要调度标签自动删除,使用一个清除策略来代替。

示例:

  1. 移除名称匹配正则(Git SHA),保留至少 5 个,早于 2 天的标签:

    curl --request DELETE --data 'name_regex_delete=[0-9a-z]{40}' --data 'keep_n=5' --data 'older_than=2d' \
         --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags"
    
  2. 移除所有标签,但是保留至少 5 个:

    curl --request DELETE --data 'name_regex_delete=.*' --data 'keep_n=5' \
         --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags"
    
  3. 移除所有标签,但是保留以 stable 开头的标签:

    curl --request DELETE --data 'name_regex_delete=.*' --data 'name_regex_keep=stable.*' \
         --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags"
    
  4. 移除所有早于1个月的标签:

    curl --request DELETE --data 'name_regex_delete=.*' --data 'older_than=1month' \
         --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags"
    

实例范围端点

除了上面解释的群组或项目级别的 API,容器仓库有它自己的端点。要查询这些端点,跟着仓库的内置组件,使用一个认证令牌来获取。

note不同于极狐GitLab 应用程序中的项目或个人访问令牌。

从极狐GitLab 获取令牌

GET ${CI_SERVER_URL}/jwt/auth?service=container_registry&scope=*

您必须指定正确的范围和操作以检索有效令牌:

$ SCOPE="repository:${CI_REGISTRY_IMAGE}:delete" #or push,pull

$ curl  --request GET --user "${CI_REGISTRY_USER}:${CI_REGISTRY_PASSWORD}" \
        "https://gitlab.example.com/jwt/auth?service=container_registry&scope=${SCOPE}"
{"token":" ... "}

通过引用删除镜像标签

DELETE http(s)://${CI_REGISTRY}/v2/${CI_REGISTRY_IMAGE}/tags/reference/${CI_COMMIT_SHORT_SHA}

您可以使用通过预定义的 CI_REGISTRY_USERCI_REGISTRY_PASSWORD 变量检索到的指令,在您的极狐GitLab 实例上通过引用删除容器镜像标签。

$ curl  --request DELETE --header "Authorization: Bearer <token_from_above>" \
        --header "Accept: application/vnd.docker.distribution.manifest.v2+json" \
        "https://gitlab.example.com:5050/v2/${CI_REGISTRY_IMAGE}/tags/reference/${CI_COMMIT_SHORT_SHA}"

列出所有容器仓库

GET http(s)://${CI_REGISTRY}/v2/_catalog

要列出您的实例上的所有容器存储库,需要管理员凭证:

$ SCOPE="registry:catalog:*"

$ curl  --request GET --user "<admin-username>:<admin-password>" \
        "https://gitlab.example.com/jwt/auth?service=container_registry&scope=${SCOPE}"
{"token":" ... "}

$ curl --header "Authorization: Bearer <token_from_above>" https://gitlab.example.com:5050/v2/_catalog