问题描述
在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_hash
是project_id
的SHA256哈希。可以使用以下步骤计算路径:
- 从
project_id
计算SHA256哈希,得到proj_sha256
。 - 将路径格式化为上述结构,使用
proj_sha256
、created_at
、job_id
、id
和file
等信息。
这里提供了一个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对象存储中查找的路径。记得在使用时注意版本差异并做好备份。
正文完