从ci_job_artifacts表创建GitLab对象存储中的路径

88次阅读
没有评论

问题描述

在GitLab中有一个内部的PostgreSQL数据库,使用了名为gitlab-psql的客户端包装器连接到其中。通过表ci_job_artifacts,他可以查询作业的构件信息。这个表的结构如下:

project_id       | integer                 
file_type        | integer                  
size             | bigint                   
created_at       | timestamp with time zone 
updated_at       | timestamp with time zone 
expire_at        | timestamp with time zone 
file             | character varying        
file_store       | integer                  
file_sha256      | bytea                    
file_format      | smallint                 
file_location    | smallint                 
id               | bigint                   
job_id           | bigint                   
locked           | smallint                 
original_filename| text                     
partition_id     | bigint                   
accessibility    | smallint                 

用户希望将这些作业构件的信息转换为路径,以便在GitLab对象存储中查找相应的构件。

解决方案

请注意以下操作可能涉及版本差异,请谨慎操作。

方案1

GitLab有一个用于创建路径的文档,名为“Uploads guide: Adding new uploads”,位于doc/development/uploads/working_with_uploads.md。在这份文档中,展示了GitLab各处的存储桶结构的详细信息。特别是对于作业构件,路径结构如下:

/artifacts/<proj_id_hash>/<date>/<job_id>/<artifact_id>

其中,proj_id_hashproject_id的SHA256哈希。可以使用以下步骤计算路径:

  1. project_id计算SHA256哈希,得到proj_sha256
  2. 将路径格式化为上述结构,使用proj_sha256created_atjob_ididfile等信息。

这里提供了一个SQL函数,可以根据作业构件的信息生成路径:

CREATE EXTENSION pgcrypto; -- 需要 `digest(bytea, text)` 函数

CREATE OR REPLACE FUNCTION generate_job_artifact_bucket_path(project_id bigint, created_at timestamp with time zone, job_id bigint, id bigint, file text)
RETURNS text AS $$
  SELECT FORMAT(
    '%s/%s/%s/%s/%s/%s/%s',
    substring(proj_sha256 FROM 1 FOR 2),
    substring(proj_sha256 FROM 3 FOR 2),
    proj_sha256,
    to_char(created_at, 'YYYY_MM_DD'),
    job_id,
    id,
    file
  )
  FROM encode(digest(project_id::text::bytea, 'SHA256'), 'hex') AS proj_sha256
$$ LANGUAGE SQL IMMUTABLE;

现在,你可以使用以下查询来获取作业构件的路径:

SELECT generate_job_artifact_bucket_path(project_id, created_at, job_id, id, file)
FROM ci_job_artifacts;

方案2

除了方案1中的方法外,你还可以创建一个更通用的函数,支持多个表的路径生成。以下是一个示例函数:

CREATE OR REPLACE FUNCTION to_bucket_path(t ci_job_artifacts)
RETURNS text AS $$
  SELECT FORMAT(
    '%s/%s/%s/%s/%s/%s/%s',
    substring(proj_sha256 FROM 1 FOR 2),
    substring(proj_sha256 FROM 3 FOR 2),
    proj_sha256,
    to_char(t.created_at, 'YYYY_MM_DD'),
    t.job_id,
    t.id,
    t.file
  )
  FROM encode(digest(t.project_id::text::bytea, 'SHA256'), 'hex') AS proj_sha256
$$ LANGUAGE SQL IMMUTABLE;

CREATE OR REPLACE FUNCTION to_bucket_path(t ci_pipeline_artifacts)
RETURNS text AS $$
  SELECT FORMAT(
    '%s/%s/%s/pipelines/%s/artifacts/%s/%s',
    substring(proj_sha256 FROM 1 FOR 2),
    substring(proj_sha256 FROM 3 FOR 2),
    proj_sha256,
    t.pipeline_id,
    t.id,
    t.file
  )
  FROM encode(digest(t.project_id::text::bytea, 'SHA256'), 'hex') AS proj_sha256
$$ LANGUAGE SQL IMMUTABLE;

这将创建一个通用的函数,用于不同表的路径生成。你可以使用以下查询来获取路径:

SELECT to_bucket_path(ci_job_artifacts) FROM ci_job_artifacts;
SELECT to_bucket_path(ci_pipeline_artifacts) FROM ci_pipeline_artifacts;

通过这些方法,你可以将作业构件的信息转换为在GitLab对象存储中查找的路径。记得在使用时注意版本差异并做好备份。

正文完