GitLabのコミュニティSlackでトラブルシューティングをした話
この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。
こんにちわ。クリエーションラインのDevOps Solution Team所属の佐藤です。
GitLabを自社サーバーにインストールして運用していて、トラブルが発生して困った経験はないでしょうか?
この記事では、GitLabのコニュニティSlackで実施した、GitLabのトラブルシューティングについて解説します。
GitLabのコミュニティSlackについて
GitLabについて日本語で情報交換ができる場所としてGitLabのコミュニティSlackがあります。
私も参加していて気が向いたときに質問に回答をしていますが、あまり活発ではないのでこのブログで興味を持っていただけたらぜひ参加をしてみてください。
- gitlab-jp.slack.com: 登録はこちら
記事の形式
この記事では、GitLabのコミュニティSlackの#questionチャンネルに投稿された質問について、私が実施したトラブルシューティングについて解説します。
GitLabのコミュニティSlackは無料版のため、3ヶ月以上前のログは表示できなくなります。そのため、冗長ですがSlackのスレッドをすべて転載した上で、私が実施したトラブルシューティングについて解説します。
登場人物
Slackのスレッドの登場人物について簡単に説明します。
sue445
質問者のsue445
さんは「Software Design 2020年1月号」の「自前でGitLabを管理するために知っておかなければならないこと」の著者で、GitLabの運用にはかなり詳しい方です。
そのため、GitLabの運用にかなり詳しい方という前提で、Slackのスレッドのログをお読みください。
jeffi7
回答者のjeffi7
さんはGitLabコミュニティのオーガナイザーの一人です。また、クリエーションラインでは、GitLabのコンサルティングやテクニカルサポートなどを担当しています。
hiroponz
もう一人の回答者のhiroponz
はこの記事の執筆者の私です。GitLabのコントリビューターであり、月間MVPを3回受賞したことがあります。
Slackのスレッドのログ
GitLabのコミュニティSlackでトラブルシューティングを実施したスレッドのログを以下に転載します。
sue445 2023年5月20日 23:17:34
【質問】社内のGitLabを15.6.1から15.11.3に上げたところ、リポジトリに権限があるにも関わらずIssueで「This issue is locked. Only project members can comment. Learn more」と表示されコメントの表示や書き込みができなくなってしまいました。
おそらくこのバージョン間でGitLabのデフォルトの設定が変わったことが予想されるのですが設定箇所が見つかりません。
この権限の設定を以前と同じようにする(リポジトリにDeveloper以上の権限を持っていればissueのコメントの閲覧や書き込みができるようにする)にはどうすれば良いでしょうか?
お手数おかけしますがよろしくお願いします。
sue445 2023年5月20日 23:32:19
【補足】 https://hub.docker.com/r/gitlab/gitlab-ce にあるDockerイメージを使っています。
sue445 2023年5月20日 23:54:03
該当のissueがunlockedの状態でもlock扱いになっている…?
jeffi7 2023年5月21日 00:22:39
しかも、ほんとうはlockしていても、プロジェクトメンバーはコメントできるはずですよね。
本来あり得ないことが起きているので、DBになにか不整合が起きてる感じがします。
Admin Area > Monitoring > Background Migrations で Fail しているものがないでしょうか?
それから、sudo gitlab-rake db:migrate:status
の結果が全行 up
でしょうか?
sue445 2023年5月21日 00:45:11
@jeffi7 回答ありがとうございます。
Admin Area > Monitoring > Background Migrations で Fail しているものがないでしょうか?
Background Migrationsは全部終了してるようでした
それから、sudo gitlab-rake db:migrate:status の結果が全行 up でしょうか?
gitlab-rake db:migrate:status
の結果を見ましたがmigrationは全部あたっているようです
root@69a78640f33b:/# gitlab-rake db:migrate:status | wc -l 5928 root@69a78640f33b:/# gitlab-rake db:migrate:status | grep " up " | wc -l 5922 root@69a78640f33b:/# gitlab-rake db:migrate:status | grep -v " up " database: gitlabhq_production Status Migration ID Migration Name -------------------------------------------------- root@69a78640f33b:/# gitlab-rake db:migrate:status | grep " down " | wc -l 0
sue445 2023年5月21日 00:51:32
データ不整合で思い出したのですが、 db:migrate
中に https://gitlab.com/gitlab-org/gitlab/-/blob/master/db/post_migrate/20221118104752_validate_not_null_contraint_to_issues_namespace_id.rb でエラーになっていました。(issuesのnamespace_idがNULLになっているレコードが存在していてチェック制約に引っかかった)
ci: == 20221118104752 ValidateNotNullContraintToIssuesNamespaceId: migrating ====== ci: -- execute("ALTER TABLE issues VALIDATE CONSTRAINT check_c33362cd43;") /home/runner/work/gcp-gitlab-playbook/gcp-gitlab-playbook/.github/workflows/util.rb:7:in `system': Command failed with exit 1: gcloud (RuntimeError) from /home/runner/work/gcp-gitlab-playbook/gcp-gitlab-playbook/.github/workflows/util.rb:7:in `sh' from ./.github/workflows/run_ansible.rb:121:in `<main>'
そのため、下記のようなSQLでnamespace_idを一括で設定していました。
update issues SET namespace_id = projects.namespace_id FROM projects where issues.namespace_id IS NULL AND projects.id = project_id
sue445 2023年5月21日 09:33:17
新しく作ったissueに対してもThis issue is lockedって表示が出るのでupdateは関係ないように見えるな…
sue445 2023年5月21日 10:01:41
念のためissueも投げてます
https://gitlab.com/gitlab-org/gitlab/-/issues/412375
jeffi7 2023年5月21日 10:16:41
「関係あるかないかわからないけど」と ValidateNotNullContraintToIssuesNamespaceId
がエラーになったこと、SQLで namespace?id
を update したことも、書き添えておくといいかもですね。ValidateNotNullContraintToIssuesNamespaceId
がエラーになったということは、これに該当していて、
https://docs.gitlab.com/ee/update/#1570:~:text=A%20database%20constraint,database%20migration%20error.
つまり、15.4 で namespace_id を backfill するマイグ レーションが、今回のアップデート前に完了していなかったということなんですが、
ここからは、調べきっていなくて確証がないんですが、
その対処がシンプルに namespace_id を update するだけでよかったのかどうかが、気になっています。
15.4 の namespace_id backfill に関係しそうなマイグレーションが、名前から見る限りこれだけあるんで (中身を見ずに言ってますが) もうちょっとややこしいことをしてたのではないかと。
20220914005141 ChangeNamespaceIdNotNullInMembers 20221004092038 TmpIndexMembersOnIdWhereNamespaceIdNull 20221018081416 MembersRemoveMemberNamespaceIdNotNullConstraint 20221103073328 ChangeMemberNamespaceIdNotNull 20221103084213 RemoveTmpIndexMembersOnIdWhereNamespaceIdNull 20221107220420 ValidateNotNullConstraintOnMemberNamespaceId ←これは今回ひっかかったやつ
sue445 2023年5月21日 10:26:09
db:migrateでエラーになったのでupdateした旨も追記しました
hiroponz 2023年5月21日 10:38:36
とりあえず、GitLab 15.11のアップデートで発生するmigrationのエラーのイシューを見つけたのでリンクを貼ります。
https://gitlab.com/gitlab-org/gitlab/-/issues/408835
コメントにwork aroundが書いてあるので、試してみてはいかがでしょうか?
https://gitlab.com/gitlab-org/gitlab/-/issues/408835#note_1373467326
hiroponz 2023年5月21日 10:50:56
408835 の中身を読みましたが、イシューがロックされる問題とは関係なさそうですね。発生バージョンとmigrationエラーということで、関係があると推測しましたが、見当違いっぽいです。
hiroponz 2023年5月21日 11:12:06
関係があるか分かりませんが、以下のようなイシューを見つけたので、sidekiqでエラーが発生していないか確認をしていただけませんか?
hiroponz 2023年5月21日 11:12:09
https://gitlab.com/gitlab-org/gitlab/-/issues/241672
sue445 2023年5月21日 11:18:55
sidekiqのログを見ましたがsidekiqのdeprecation warning以外は出てなさそうです。
root@69a78640f33b:/# cat /var/log/gitlab/sidekiq/current | grep '"severity":"WARN"' {"severity":"WARN","time":"2023-05-21T02:08:27.809Z","message":"Job arguments to FlushCounterIncrementsWorker do not serialize to JSON safely. This will raise an error in\nSidekiq 7.0. See https://github.com/mperham/sidekiq/wiki/Best-Practices or raise an error today\nby calling `Sidekiq.strict_args!` during Sidekiq initialization.\n"} {"severity":"WARN","time":"2023-05-21T02:15:43.963Z","message":"Job arguments to PipelineNotificationWorker do not serialize to JSON safely. This will raise an error in\nSidekiq 7.0. See https://github.com/mperham/sidekiq/wiki/Best-Practices or raise an error today\nby calling `Sidekiq.strict_args!` during Sidekiq initialization.\n"} root@69a78640f33b:/# cat /var/log/gitlab/sidekiq/current | grep '"severity":"ERROR"' root@69a78640f33b:/#
sue445 2023年5月21日 11:21:54
db:migrate
後もRailsやsidekiqが古いスキーマのキャッシュを持ち続けてエラーになる事象は以前ハマったことがあって、 db:migrate
後に明示的にコンテナを再起動するような対応を入れているのでそこの再発はもうしないはず…
hiroponz 2023年5月21日 11:31:56
類似のイシューを探しましたが見つからないので、環境依存の問題な気がします。
ちなみに、該当イシューのissuesテーブルのdisscoussion_lockedの値はtrueになっている感じでしょうか?多分この値がイシューのロック状態を保持していると思います。
https://gitlab.com/gitlab-org/gitlab/-/blob/v15.11.5-ee/db/structure.sql?ref_type=tags#L17492
sue445 2023年5月21日 11:35:36
discussion_locked?
は false
になっていました
irb(main):014:0> Project.find(2).issues.find_by(iid: 3).discussion_locked? => false
hiroponz 2023年5月21日 11:45:41
ちなみに、GitLabサーバー側のログ、およびブラウザのコンソールには、関連しそうなエラーは出力されていないでしょうか?
sue445 2023年5月21日 11:54:22
サーバサイドとフロントエンド、ともに特にエラーは出ていなかったです。
issueのコメントはフロントエンドから /:namespace/:repo_name/noteable/issue/:issue_iid/notes
でとってきてますが、chromeの開発者ツールで見ると空っぽのようでした。(ステータスコードは304)
{"last_fetched_at":1684637203230917,"notes":[]}
gitlab.com だと200を返しているのでちょっと気になってます。
hiroponz 2023年5月21日 11:58:03
304だとブラウザ側のキャッシュの影響が考えらえるので、ブラウザのキャッシュをクリアして変化がないか試していただけますか?
sue445 2023年5月21日 12:00:20
シークレットウィンドウでも同じでした
sue445 2023年5月21日 12:37:38
/:namespace/:repo_name/noteable/issue/:issue_iid/notes
の実装は https://gitlab.com/gitlab-org/gitlab/-/blob/v15.11.3-ee/app/controllers/concerns/notes_actions.rb?ref_type=tags#L24-27 なんですが、 Note#readable_by?
がnotesを全部rejectしてそうな気配を感じます
irb(main):003:0> issue = Project.find(2).issues.find_by(iid: 1) irb(main):004:0> issue.notes.count => 3 irb(main):008:0> current_user = User.find_by(username: "sue445") irb(main):010:0> notes = issue.notes irb(main):011:0> notes = notes.select { |n| n.readable_by?(current_user) } => []
hiroponz 2023年5月21日 13:01:41
関係がありそうな変更を調べていたら、下記のようなコミットが見つかりました。
https://gitlab.com/gitlab-org/gitlab/-/commit/c0092bcb3de24d05149c79a506df11d9bb4e5a1c
issue.work_item_type.widgets.include?(::WorkItems::Widgets::Notes)
上記が true
を返さないと、イシューのコメントがロックされる気がします。
hiroponz 2023年5月21日 13:05:00
revertのrevertが発生していて、ツラミを感じる。
https://gitlab.com/gitlab-org/quality/engineering-productivity/master-broken-incidents/-/issues/491
sue445 2023年5月21日 13:25:45
ここまでの調査結果( NoteController#index
の Note#readable_by?
が怪しそう)をissueに追記しました
https://gitlab.com/gitlab-org/gitlab/-/issues/412375#note_1398636341
sue445 2023年5月21日 13:31:32
上記が
true
を返さないと、イシューのコメントがロックされる気がします。
見事にfalseが返ってきてました…
irb(main):029:0> issue.work_item_type.widgets.include?(::WorkItems::Widgets::Notes) => false irb(main):030:0> issue.work_item_type.widgets => [] irb(main):031:0> issue.work_item_type => #<WorkItems::Type:0x00007f5afbdc5c28 id: 1, base_type: "issue", cached_markdown_version: 1900544, name: "Issue", description: nil, description_html: "", icon_name: "issue-type-issue", namespace_id: nil, created_at: Thu, 20 Oct 2022 12:18:59.633513000 JST +09:00, updated_at: Thu, 20 Oct 2022 12:18:59.633513000 JST +09:00>
hiroponz 2023年5月21日 15:01:07
WorkItem関連のDB migrationに失敗しているような気がします。下記のモデルのテーブルにseedデータは存在するでしょうか?
https://gitlab.com/gitlab-org/gitlab/-/blob/v15.11.5-ee/app/models/work_items/type.rb
https://gitlab.com/gitlab-org/gitlab/-/blob/v15.11.5-ee/app/models/work_items/widget_definition.rb
hiroponz 2023年5月21日 15:02:29
WorkItem関連のseedの投入箇所は以下になります。
https://gitlab.com/gitlab-org/gitlab/-/blob/v15.11.5-ee/db/fixtures/production/003_create_base_work_item_types.rb
hiroponz 2023年5月21日 15:03:12
sue445 2023年5月21日 15:11:14
WorkItems::Type
はデータが入ってたのですが WorkItems::WidgetDefinition
は空でした。
irb(main):001:0> WorkItems::Type.count => 7 irb(main):004:0> WorkItems::Type.pluck(:name) => ["Issue", "Incident", "Test Case", "Requirement", "Task", "Objective", "Key Result"] irb(main):005:0> WorkItems::WidgetDefinition.count => 0
sue445 2023年5月21日 15:26:48
oh…
irb(main):001:0> Gitlab::DatabaseImporters::WorkItems::BaseTypeImporter.upsert_types /opt/gitlab/embedded/lib/ruby/gems/3.0.0/gems/activerecord-6.1.7.2/lib/active_record/connection_adapters/postgresql_adapter.rb:672:in `exec_params': PG::SREModifyingSqlDataNotPermitted: ERROR: Table: "work_item_widget_definitions" is write protected within this Gitlab database. (ActiveRecord::StatementInvalid) HINT: Make sure you are using the right database connection CONTEXT: PL/pgSQL function gitlab_schema_prevent_write() line 4 at RAISE /opt/gitlab/embedded/lib/ruby/gems/3.0.0/gems/activerecord-6.1.7.2/lib/active_record/connection_adapters/postgresql_adapter.rb:672:in `exec_params': ERROR: Table: "work_item_widget_definitions" is write protected within this Gitlab database. (PG::SREModifyingSqlDataNotPermitted) HINT: Make sure you are using the right database connection CONTEXT: PL/pgSQL function gitlab_schema_prevent_write() line 4 at RAISE
sue445 2023年5月21日 16:02:16
gitlab-rake gitlab:db:unlock_writes
して Gitlab::DatabaseImporters::WorkItems::BaseTypeImporter.upsert_types
を実行したらいけました。ありがとうございます!
以上がSlackのスレッドのログとなります。
トラブルシューティングの進め方
私(hiroponz)は5月21日の午前中にSlackの質問に気がついて、スレッドの内容をざっくり確認しました。
スレッドの内容をざっくり確認して感じた印象は次のようなものでした。
- バージョンアップ時のマイグレーションで何らかの不具合を踏んでいる可能性がある。
- 影響が大きい不具合のため、既知の不具合としてイシューに報告されている可能性が高い。
イシューでの調査
そのため、まずは関係のありそうなイシューを検索して、問題を解決出来ないか試しています。
GitLabの不具合は公式イシューに報告するルールとなっています。しかし、ここには不具合だけではなく、機能リクエストや自動テストの失敗など様々なものが登録されています。2023年8月現在は、オープン状態のものだけで5万件近くが登録されていて、目的のイシューを探すのは簡単なことではありません。
参考までに、私がGitLabのイシューを検索する際に使用しているテクニックを紹介します。
はじめに、Google検索でイシューを検索します。これは、Google検索だと目的のイシューが上位に表示されることが多いという、個人的な経験によります。この時に検索条件として「site:gitlab.com inurl:gitlab-org inurl:issues」を付けることで、GitLabのイシューに絞って検索することが出来ます。
Google検索で目的のイシューが見つからない場合は、公式イシュートラッカーで検索します。この時に不具合に関するイシューには、 ~type::bug
というラベルを付けるルールとなっているので、 ~type::bug
というラベルを付けて検索することで、目的のイシューを効率的に検索することが出来ます。
なお、GitLabのイシューは、デフォルトでオープン状態のイシューのみが表示されます。最新版のGitLabでは既に解決済みの不具合の可能性があるので、クローズ状態のイシューも確認するようにしましょう。
ソースコードでの調査
今回のケースでは、イシューでの調査が暗礁に乗り上げたため、ソースコードでの調査を実施しました。
GitLabはソースコードが公開されているので、誰でもソースコードを調査することが出来ます。なお、GitLab EEとCEは一つのリポジトリに統合されているため、どちらのディストリビューションを利用している場合でも、調査するのは同じリポジトリとなります。
メッセージが画面に表示される条件を調べる
調査の取っ掛かりとして、「This issue is locked. Only project members can comment. Learn more」と画面に表示される条件の調査から開始しました。
GitLabではソースコードの検索が可能なため、今回はGitLab上でソースコードの調査を実施しました。GitLab上でGitLabのソースコードを検索する手順は次の通りです。
- GitLabにサインインします。(ソースコードを検索するにはサインインする必要があります。)
- GitLabのリポジトリを表示します。
- バージョンを指定するためv15.11.3-eeタグを選択します。(GitLab CEの調査であっても、
-ee
のタグを選択することに注意してください。) - 画面上部の虫眼鏡アイコンをクリックして検索窓を表示します。
- 検索したい文字列を入力してEnterを押下します。
フロントエンド(Vue.js)のコードを調査する
今回のケースでは「Only project members can comment」で検索すると、それらしいコードがいくつかヒットします。
discussion_locked_widget.vueの中身を読むと、このコンポーネントで「This issue is locked. Only project members can comment. Learn more」というメッセージを表示していることが分かります。
そのため、「DiscussionLockedWidget」で検索して、このコンポーネントを表示する条件を調査します。
その結果、comment_form.vueの下記のコードが、「This issue is locked.」というメッセージを表示する条件であることが分かります。
<discussion-locked-widget v-else-if="!canCreateNote" :issuable-type="noteableDisplayName" />
すなわち、 canCreateNote
が false
の場合にイシューのロックのメッセージが表示されることが分かります。
canCreateNoteの定義を調べると、次のようになっています。
canCreateNote() { return this.getNoteableData.current_user.can_create_note; },
バックエンド(Rails)のコードを調査する
続いて、「can_create_note」で検索して、この定義を調べます。その結果、issue_entity.rbに下記のコードが見つかります。
expose :can_create_note do |issue| can?(request.current_user, :create_note, issue) end
ここで、 can?
というDSLが登場します。これはGitLabの DeclarativePolicy framework の記法であり、その定義はapp/policiesディレクトリに格納されています。ここで知りたいのは、issueのpolicyなのでissue_policy.rbを確認します。すると下記のコードが見つかります。
# accessing notes requires the notes widget to be available for work items(or issue) condition(:notes_widget_enabled, scope: :subject) do @subject.work_item_type.widgets.include?(::WorkItems::Widgets::Notes) end rule { ~notes_widget_enabled }.policy do prevent :create_note prevent :read_note prevent :read_internal_note prevent :set_note_created_at prevent :mark_note_as_internal # these actions on notes are not available on issues/work items yet, # but preventing any action on work item notes as long as there is no notes widget seems reasonable prevent :resolve_note prevent :reposition_note end
上記のコードから以下のことが分かります。
notes_widget_enabled
がfalse
の場合に、create_note
がprevent
される。すなわち、notes_widget_enabled
がfalse
の場合に、create_note
がfalse
となる。notes_widget_enabled
は@subject.work_item_type.widgets.include?(::WorkItems::Widgets::Notes)
の評価結果と同義である。
以上から、下記の評価結果が false
の場合にイシューがロックされると推測されます。
issue.work_item_type.widgets.include?(::WorkItems::Widgets::Notes)
issue_policy.rb の変更がどうやら怪しいと当たりを付けたので、 blame でどのコミットで変更されたのか確認します。その結果、下記のコミット、及びマージリクエストで変更されていることが分かります。
上記のマージリクエストは、マイルストーンが 15.8 に設定されています。これは、GitLabを15.6.1から15.11.3にバージョンアップしたタイミングで問題が発生したことと合致します。
以上から、この変更が今回のトラブルの原因と考えて、Slackで確認を進めて無事にトラブルを解決することが出来ました。
なお、Slackでのやり取りを理解するにはGitLabの運用知識やRailsアプリの開発知識が必要となりますが、この記事で説明するには分量が多くなりすぎるため、この記事では深入りはしないことにします。
おわりに
GitLabのコミュニティSlackで、私が実施したトラブルシューティングについて説明をしました。イシューでの調査方法やソースコードでの調査方法など、GitLabのトラブルシューティングを行う際の参考になれば幸いです。
また、クリエーションラインではGitLabのテクニカルサポートを提供しています。GitLabの運用に課題を感じている場合は、ぜひお気軽にご相談ください。