Rake 任务的完整性检查

Rake 任务的完整性检查

Tier: 基础版,专业版,旗舰版

Offering: 私有化部署

极狐GitLab 提供 Rake 任务来检查各个组件的完整性。另请参阅检查极狐GitLab 配置 Rake 任务。

仓库完整性#

尽管 Git 非常稳定,并尝试防止数据完整性问题,但有时事情会出错。以下 Rake 任务旨在帮助极狐GitLab 管理员诊断有问题的仓库,以便进行修复。

这些 Rake 任务使用三种不同的方法来确定 Git 仓库的完整性。

Git 仓库文件系统检查(git fsck)。此步骤验证仓库中对象的连接性和有效性。

检查仓库目录中的 config.lock。

检查 refs/heads 中的任何分支/引用锁文件。

config.lock 或引用锁的存在本身并不一定表示问题。锁文件通常在 Git 和极狐GitLab 对仓库执行操作时被创建和移除。它们可以防止数据完整性问题。然而,如果 Git 操作被中断,这些锁可能无法正确清理。

以下症状可能表明仓库完整性存在问题。如果用户遇到这些症状,您可以使用下面描述的 Rake 任务来确定哪些仓库导致了问题。

尝试推送代码时收到错误 - remote: error: cannot lock ref

查看极狐GitLab 仪表板或访问特定项目时出现 500 错误。

检查项目代码仓库#

此任务循环遍历项目代码仓库并运行之前描述的完整性检查。如果项目使用池仓库,也会进行检查。其他类型的 Git 仓库不会被检查。

要检查项目代码仓库:

Linux package (Omnibus)Self-compiled (source)

shellsudo gitlab-rake gitlab:git:fsck

shellsudo -u git -H bundle exec rake gitlab:git:fsck RAILS_ENV=production

仓库引用的校验和#

可以通过对每个仓库的所有引用进行校验和来比较两个 Git 仓库。如果两个仓库具有相同的引用,并且都通过完整性检查,那么我们可以确信两个仓库是相同的。

例如,这可以用于将仓库的备份与源仓库进行比较。

检查所有极狐GitLab 仓库#

此任务循环遍历极狐GitLab 服务器上的所有仓库,并以 , 格式输出校验和。

如果仓库不存在,项目 ID 是一个空白校验和。

如果仓库存在但为空,输出的校验和是 0000000000000000000000000000000000000000。

不存在的项目被跳过。

要检查所有极狐GitLab 仓库:

Linux package (Omnibus)Self-compiled (source)

shellsudo gitlab-rake gitlab:git:checksum_projects

shellsudo -u git -H bundle exec rake gitlab:git:checksum_projects RAILS_ENV=production

例如,如果:

ID 为 2 的项目不存在,则跳过。

ID 为 4 的项目没有仓库,其校验和为空。

ID 为 5 的项目有一个空仓库,其校验和为 0000000000000000000000000000000000000000。

输出将如下所示:

plaintext1,cfa3f06ba235c13df0bb28e079bcea62c5848af2

3,3f3fb58a8106230e3a6c6b48adc2712fb3b6ef87

4,

5,0000000000000000000000000000000000000000

6,6c6b48adc2712fb3b6ef87cfa3f06ba235c13df0

检查特定极狐GitLab 仓库#

可以选择通过设置环境变量 CHECKSUM_PROJECT_IDS 来校验特定项目 ID,使用逗号分隔的整数列表,例如:

shellsudo CHECKSUM_PROJECT_IDS="1,3" gitlab-rake gitlab:git:checksum_projects

上传文件的完整性#

用户可以上传各种类型的文件到极狐GitLab 安装中。这些完整性检查可以检测丢失的文件。此外,对于本地存储的文件,上传时会生成校验和并存储在数据库中,这些检查会将它们与当前文件进行验证。

完整性检查支持以下类型的文件:

CI 产物

LFS 对象

项目级安全文件(在极狐GitLab 16.1.0 中引入)

用户上传

要检查上传文件的完整性:

Linux package (Omnibus)Self-compiled (source)

shellsudo gitlab-rake gitlab:artifacts:check

sudo gitlab-rake gitlab:ci_secure_files:check

sudo gitlab-rake gitlab:lfs:check

sudo gitlab-rake gitlab:uploads:check

shellsudo -u git -H bundle exec rake gitlab:artifacts:check RAILS_ENV=production

sudo -u git -H bundle exec rake gitlab:ci_secure_files:check RAILS_ENV=production

sudo -u git -H bundle exec rake gitlab:lfs:check RAILS_ENV=production

sudo -u git -H bundle exec rake gitlab:uploads:check RAILS_ENV=production

这些任务也接受一些环境变量,您可以用来覆盖某些值:

VariableTypeDescriptionBATCHinteger指定批次大小。默认为 200。ID_FROMinteger指定开始 ID,包含该值。ID_TOinteger指定结束 ID,包含该值。VERBOSEboolean导致故障单独列出,而不是总结。

shellsudo gitlab-rake gitlab:artifacts:check BATCH=100 ID_FROM=50 ID_TO=250

sudo gitlab-rake gitlab:ci_secure_files:check BATCH=100 ID_FROM=50 ID_TO=250

sudo gitlab-rake gitlab:lfs:check BATCH=100 ID_FROM=50 ID_TO=250

sudo gitlab-rake gitlab:uploads:check BATCH=100 ID_FROM=50 ID_TO=250

示例输出:

shell1$ sudo gitlab-rake gitlab:uploads:check

2Checking integrity of Uploads

3- 1..1350: Failures: 0

4- 1351..2743: Failures: 0

5- 2745..4349: Failures: 2

6- 4357..5762: Failures: 1

7- 5764..7140: Failures: 2

8- 7142..8651: Failures: 0

9- 8653..10134: Failures: 0

10- 10135..11773: Failures: 0

11- 11777..13315: Failures: 0

12Done!

详细输出示例:

shell1$ sudo gitlab-rake gitlab:uploads:check VERBOSE=1

2Checking integrity of Uploads

3- 1..1350: Failures: 0

4- 1351..2743: Failures: 0

5- 2745..4349: Failures: 2

6 - Upload: 3573: #

7 - Upload: 3580: #

8- 4357..5762: Failures: 1

9 - Upload: 4636: #

10- 5764..7140: Failures: 2

11 - Upload: 5812: #

12 - Upload: 5837: #

13- 7142..8651: Failures: 0

14- 8653..10134: Failures: 0

15- 10135..11773: Failures: 0

16- 11777..13315: Failures: 0

17Done!

LDAP 检查#

LDAP 检查 Rake 任务测试绑定 DN 和密码凭证(如果已配置),并列出 LDAP 用户的示例。此任务也作为 gitlab:check 任务的一部分执行,但可以单独运行。有关详细信息,请参阅 LDAP Rake Tasks - LDAP Check。

验证数据库值是否可以使用当前密钥解密#

此任务遍历数据库中所有可能的加密值,验证它们是否可以使用当前密钥文件 (gitlab-secrets.json) 解密。

自动解决方案尚未实现。如果您有无法解密的值,可以按照步骤重置它们,请参阅我们的文档 当密钥文件丢失时。

这可能需要很长时间,具体取决于您的数据库大小,因为它会检查所有表中的所有行。

要验证数据库值是否可以使用当前密钥解密:

Linux package (Omnibus)Self-compiled (source)

shellsudo gitlab-rake gitlab:doctor:secrets

shellbundle exec rake gitlab:doctor:secrets RAILS_ENV=production

示例输出

plaintext1I, [2020-06-11T17:17:54.951815 #27148] INFO -- : Checking encrypted values in the database

2I, [2020-06-11T17:18:12.677708 #27148] INFO -- : - ApplicationSetting failures: 0

3I, [2020-06-11T17:18:12.823692 #27148] INFO -- : - User failures: 0

4[...] other models possibly containing encrypted data

5I, [2020-06-11T17:18:14.938335 #27148] INFO -- : - Group failures: 1

6I, [2020-06-11T17:18:15.559162 #27148] INFO -- : - Operations::FeatureFlagsClient failures: 0

7I, [2020-06-11T17:18:15.575533 #27148] INFO -- : - ScimOauthAccessToken failures: 0

8I, [2020-06-11T17:18:15.575678 #27148] INFO -- : Total: 1 row(s) affected

9I, [2020-06-11T17:18:15.575711 #27148] INFO -- : Done!

详细模式#

要获取有关哪些行和列无法解密的详细信息,您可以传递 VERBOSE 环境变量。

要使用详细信息验证数据库值是否可以使用当前密钥解密:

Linux package (Omnibus)Self-compiled (source)

shellsudo gitlab-rake gitlab:doctor:secrets VERBOSE=1

shellbundle exec rake gitlab:doctor:secrets RAILS_ENV=production VERBOSE=1

详细输出示例

plaintext1I, [2020-06-11T17:17:54.951815 #27148] INFO -- : Checking encrypted values in the database

2I, [2020-06-11T17:18:12.677708 #27148] INFO -- : - ApplicationSetting failures: 0

3I, [2020-06-11T17:18:12.823692 #27148] INFO -- : - User failures: 0

4[...] other models possibly containing encrypted data

5D, [2020-06-11T17:19:53.224344 #27351] DEBUG -- : > Something went wrong for Group[10].runners_token: Validation failed: Route can't be blank

6I, [2020-06-11T17:19:53.225178 #27351] INFO -- : - Group failures: 1

7D, [2020-06-11T17:19:53.225267 #27351] DEBUG -- : - Group[10]: runners_token

8I, [2020-06-11T17:18:15.559162 #27148] INFO -- : - Operations::FeatureFlagsClient failures: 0

9I, [2020-06-11T17:18:15.575533 #27148] INFO -- : - ScimOauthAccessToken failures: 0

10I, [2020-06-11T17:18:15.575678 #27148] INFO -- : Total: 1 row(s) affected

11I, [2020-06-11T17:18:15.575711 #27148] INFO -- : Done!

当无法恢复加密令牌时重置#

History

引入于极狐GitLab 16.6。

此操作很危险,可能导致数据丢失。请务必极其谨慎地进行操作。您必须了解极狐GitLab 内部结构才能执行此操作。

在某些情况下,加密令牌无法再恢复并导致问题。通常情况下,群组和项目的 runner 注册令牌可能会在非常大的实例上出现故障。

要重置损坏的令牌:

确定具有损坏的加密令牌的数据库模型。例如,可以是 Group 和 Project。

确定损坏的令牌。例如 runners_token。

要重置损坏的令牌,请使用 VERBOSE=true MODEL_NAMES=Model1,Model2 TOKEN_NAMES=broken_token1,broken_token2 运行 gitlab:doctor:reset_encrypted_tokens。例如:

shell VERBOSE=true MODEL_NAMES=Project,Group TOKEN_NAMES=runners_token gitlab-rake gitlab:doctor:reset_encrypted_tokens

shell bundle exec rake gitlab:doctor:reset_encrypted_tokens RAILS_ENV=production VERBOSE=true MODEL_NAMES=Project,Group TOKEN_NAMES=runners_token

您将看到此任务将尝试执行的每个操作:

plain1I, [2023-09-26T16:20:23.230942 #88920] INFO -- : Resetting runners_token on Project, Group if they can not be read

2I, [2023-09-26T16:20:23.230975 #88920] INFO -- : Executing in DRY RUN mode, no records will actually be updated

3D, [2023-09-26T16:20:30.151585 #88920] DEBUG -- : > Fix Project[1].runners_token

4I, [2023-09-26T16:20:30.151617 #88920] INFO -- : Checked 1/9 Projects

5D, [2023-09-26T16:20:30.151873 #88920] DEBUG -- : > Fix Project[3].runners_token

6D, [2023-09-26T16:20:30.152975 #88920] DEBUG -- : > Fix Project[10].runners_token

7I, [2023-09-26T16:20:30.152992 #88920] INFO -- : Checked 11/29 Projects

8I, [2023-09-26T16:20:30.153230 #88920] INFO -- : Checked 21/29 Projects

9I, [2023-09-26T16:20:30.153882 #88920] INFO -- : Checked 29 Projects

10D, [2023-09-26T16:20:30.195929 #88920] DEBUG -- : > Fix Group[22].runners_token

11I, [2023-09-26T16:20:30.196125 #88920] INFO -- : Checked 1/19 Groups

12D, [2023-09-26T16:20:30.196192 #88920] DEBUG -- : > Fix Group[25].runners_token

13D, [2023-09-26T16:20:30.197557 #88920] DEBUG -- : > Fix Group[82].runners_token

14I, [2023-09-26T16:20:30.197581 #88920] INFO -- : Checked 11/19 Groups

15I, [2023-09-26T16:20:30.198455 #88920] INFO -- : Checked 19 Groups

16I, [2023-09-26T16:20:30.198462 #88920] INFO -- : Done!

如果您确信此操作重置了正确的令牌,请禁用 dry-run 模式并再次运行操作:

shell DRY_RUN=false VERBOSE=true MODEL_NAMES=Project,Group TOKEN_NAMES=runners_token gitlab-rake gitlab:doctor:reset_encrypted_tokens

shell bundle exec rake gitlab:doctor:reset_encrypted_tokens RAILS_ENV=production DRY_RUN=false VERBOSE=true MODEL_NAMES=Project,Group TOKEN_NAMES=runners_token

故障排除#

以下是使用上述 Rake 任务可能发现的问题的解决方案。

悬挂对象#

gitlab-rake gitlab:git:fsck 任务可以发现悬挂对象,例如:

plaintextdangling blob a12...

dangling commit b34...

dangling tag c56...

dangling tree d78...

要删除它们,请尝试运行维护。

如果问题仍然存在,请尝试通过 Rails 控制台触发垃圾收集:

rubyp = Project.find_by_path("project-name")

Repositories::HousekeepingService.new(p, :gc).execute

如果悬挂对象比默认的 2 周宽限期年轻,并且您不想等到它们自动过期,请运行:

rubyRepositories::HousekeepingService.new(p, :prune).execute

删除对缺失远程上传的引用#

gitlab-rake gitlab:uploads:check VERBOSE=1 检测远程对象不存在,因为它们在外部被删除,但其引用仍然存在于极狐GitLab 数据库中。

带有错误消息的示例输出:

shell1$ sudo gitlab-rake gitlab:uploads:check VERBOSE=1

2Checking integrity of Uploads

3- 100..434: Failures: 2

4- Upload: 100: Remote object does not exist

5- Upload: 101: Remote object does not exist

6Done!

要删除这些对在外部删除的远程上传的引用,请打开 极狐GitLab Rails 控制台并运行:

ruby1uploads_deleted=0

2Upload.find_each do |upload|

3 next if upload.retrieve_uploader.file.exists?

4 uploads_deleted=uploads_deleted + 1

5 p upload ### allow verification before destroy

6 # p upload.destroy! ### uncomment to actually destroy

7end

8p "#{uploads_deleted} remote objects were destroyed."

删除对缺失产物的引用#

gitlab-rake gitlab:artifacts:check VERBOSE=1 检测产物(或 job.log 文件):

在极狐GitLab 外部被删除。

仍然在极狐GitLab 数据库中有引用。

当检测到这种情况时,Rake 任务显示错误消息。例如:

shell1Checking integrity of Job artifacts

2- 1..15: Failures: 2

3 - Job artifact: 9: #

4 - Job artifact: 15: Remote object does not exist

5Done!

6

要删除对缺失的本地和/或远程产物(job.log 文件)的引用:

打开 极狐GitLab Rails 控制台。

运行以下 Ruby 代码:

ruby1artifacts_deleted = 0

2::Ci::JobArtifact.find_each do |artifact| ### Iterate artifacts

3# next if artifact.file.filename != "job.log" ### Uncomment if only `job.log` files' references are to be processed

4 next if artifact.file.file.exists? ### Skip if the file reference is valid

5 artifacts_deleted += 1

6 puts "#{artifact.id} #{artifact.file.path} is missing." ### Allow verification before destroy

7# artifact.destroy! ### Uncomment to actually destroy

8end

9puts "Count of identified/destroyed invalid references: #{artifacts_deleted}"

删除对缺失 LFS 对象的引用#

如果 gitlab-rake gitlab:lfs:check VERBOSE=1 检测到存在于数据库但不在磁盘上的 LFS 对象,请按照 LFS 文档中的程序移除数据库条目。

更新悬挂对象存储引用#

如果您已从对象存储迁移到本地存储,并且文件丢失,则悬挂数据库引用仍然存在。

这在迁移日志中可见,错误如下所示:

shellW, [2022-11-28T13:14:09.283833 #10025] WARN -- : Failed to transfer Ci::JobArtifact ID 11 with error: undefined method `body' for nil:NilClass

W, [2022-11-28T13:14:09.296911 #10025] WARN -- : Failed to transfer Ci::JobArtifact ID 12 with error: undefined method `body' for nil:NilClass

尝试删除对缺失产物的引用后禁用对象存储,导致以下错误:

plaintextRuntimeError (Object Storage is not enabled for JobArtifactUploader)

要更新这些引用以指向本地存储:

打开 极狐GitLab Rails 控制台。

运行以下 Ruby 代码:

ruby1artifacts_updated = 0

2::Ci::JobArtifact.find_each do |artifact| ### Iterate artifacts

3 next if artifact.file_store != 2 ### Skip if file_store already points to local storage

4 artifacts_updated += 1

5 # artifact.update(file_store: 1) ### Uncomment to actually update

6end

7puts "Updated file_store count: #{artifacts_updated}"

现在,脚本可以删除对缺失产物的引用,并正确清理数据库。

删除对缺失安全文件的引用#

VERBOSE=1 gitlab-rake gitlab:ci_secure_files:check 检测安全文件:

在极狐GitLab 外部被删除。

仍然在极狐GitLab 数据库中有引用。

当检测到这种情况时,Rake 任务显示错误消息。例如:

shell1Checking integrity of CI Secure Files

2- 1..15: Failures: 2

3 - Job SecureFile: 9: #

4 - Job SecureFile: 15: Remote object does not exist

5Done!

6

要删除对缺失的本地或远程安全文件的引用:

打开 极狐GitLab Rails 控制台。

运行以下 Ruby 代码:

ruby1secure_files_deleted = 0

2::Ci::SecureFile.find_each do |secure_file| ### Iterate secure files

3 next if secure_file.file.file.exists? ### Skip if the file reference is valid

4 secure_files_deleted += 1

5 puts "#{secure_file.id} #{secure_file.file.path} is missing." ### Allow verification before destroy

6# secure_file.destroy! ### Uncomment to actually destroy

7end

8puts "Count of identified/destroyed invalid references: #{secure_files_deleted}"

相关推荐