GitLab Omnibus移行時の留意点

By | 2016年2月18日

こんにちは。

1日だけ春並みに暖かくなって、冬の気温に戻る気まぐれな気候に振り回され気味のヒロです。

今回はAWSから少し離れまして、弊社が自社内で使っているGitLabのバージョンアップと移行を行った際に悩んでしまったことについて、書かれている場所があまり見当たらなかったので、備忘録も兼ねて書きたいと思います。

GitLab移行の背景

これまで自社内で使用していたGitLabは以前ソースを使ってインストールしたものでした。しかし、アップデートなどの今後の運用を考えるとそのまま使い続けるのは手間が掛かるので、今回のアップデートを機会にOmnibusパッケージを使って新しくサーバを立ててそちらに移行することになりました。

条件

  • アップデート前のGitLabバージョン:6.0
  • アップデート後のGitLabバージョン:7.12.2
  • GitLabの現行サーバはAWS EC2で作成されている
  • 移行先のサーバはAWS EC2で作成する
  • OSは移行前もAmazon Linux移行後もAmazon Linuxを使っている

GitLabバージョンアップ、データ移行の流れ

  1. 現在稼働中のGitLabサーバのAWSイメージを作成
  2. 作成したAWSイメージを使用して新しくサーバA(バージョンアップのための仮サーバ)を構築
  3. サーバAのGitLabを7.12.2にバージョンアップ
  4. サーバAのGitLabのバックアップデータを作成
  5. バックアップデータをMysqlからPostgreSQL対応に変換
  6. サーバB(新GitLabサーバ)を構築
  7. サーバBに7.12.2-Omnibusを新規でインストール
  8. サーバAからサーバBにバックアップデータを移動
  9. サーバBでバックアップデータを使用してリストア
  10. GitLabサーバへの通信確認

サーバ移行完了後の問題

本記事の本題です。
移行完了後に確認すると一見問題なく動作しており、データも不足なく移行できたのですが、rakeタスクでcheckを行ったところ、エラーが起きました。

[root@ip-10-0-1-168 ~]# gitlab-rake gitlab:check SANITIZE=true
Checking GitLab Shell ...

GitLab Shell version >= 2.6.3 ? ... OK (2.6.3)
Repo base directory exists? ... yes
Repo base directory is a symlink? ... no
Repo base owned by git:git? ... yes
Repo base access is drwxrws---? ... yes
Satellites access is drwxr-x---? ... yes
hooks directories in repos are links: ...
1/1 ... repository is empty
4/2 ... rake aborted!
Errno::ENOENT: No such file or directory @ realpath_rec - /home/git
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/check.rake:488:in `realpath'
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/check.rake:488:in `block in check_repos_hooks_directory_is_link'
/opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/activerecord-4.1.11/lib/active_record/relation/batches.rb:52:in `block (2 levels) in find_each'
/opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/activerecord-4.1.11/lib/active_record/relation/batches.rb:52:in `each'
/opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/activerecord-4.1.11/lib/active_record/relation/batches.rb:52:in `block in find_each'
/opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/activerecord-4.1.11/lib/active_record/relation/batches.rb:126:in `find_in_batches'
/opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/activerecord-4.1.11/lib/active_record/relation/batches.rb:51:in `find_each'
/opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/activerecord-4.1.11/lib/active_record/querying.rb:9:in `find_each'
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/check.rake:482:in `check_repos_hooks_directory_is_link'
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/check.rake:343:in `block (3 levels) in <top (required)>'
Tasks: TOP => gitlab:check => gitlab:gitlab_shell:check
(See full trace by running task with --trace)
[root@ip-10-0-1-168 ~]# cat /opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/check.rake | head -n 491 | tail -n 8
        project_hook_directory = File.join(project.repository.path_to_repo, "hooks")

        if project.empty_repo?
          puts "repository is empty".magenta
        # 488行目ここでエラーになってる
        elsif File.directory?(project_hook_directory) && File.directory?(gitlab_shell_hooks_path) &&
            (File.realpath(project_hook_directory) == File.realpath(gitlab_shell_hooks_path))
          puts 'ok'.green
        else

調べた結果、GitLabにはリポジトリ毎にhooksリンクが用意されていることが分かりました。
エラーの原因はhooksのリンク先が存在せずにリンクが無効になっていることでした。

[root@ip-10-0-1-168 ~]# ls /var/opt/gitlab/git-data/repositories/test/test.git/ -la | grep hooks
lrwxrwxrwx 1 git git   28 Feb 18 03:02 hooks -> /home/git/gitlab-shell/hooks

リンク先が存在していなかった原因

hooksはソースを使ってGitLabをインストールした場合、パッケージを使ってGitLabをインストールした場合でデフォルトの置き場所が変わるようです。

ソース版 /home/git/gitlab-shell/hooks/
パッケージ版 /opt/gitlab/embedded/service/gitlab-shell/hooks/

これはバージョン依存ではなく、ソース版、パッケージ版の違いのようです。
ソース版からパッケージ版もしくはパッケージ版からソース版にサーバを移行する場合はリンク先の齟齬が起きてしまうようです。

infoタスクでGitlab Shellの情報を確認するとhooksが何処にあるか分かります。
デフォルトのままだと以下のようになっています。

一部抜粋

ソース版

admin@ip-10-0-1-162:/home/git/gitlab$ sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production

…
GitLab Shell
Version:        2.6.10
Repositories:   /home/git/repositories/
Hooks:          /home/git/gitlab-shell/hooks/
Git:            /usr/bin/git

パッケージ版

[root@ip-10-0-1-169 ~]# gitlab-rake gitlab:env:info

…
GitLab Shell
Version:        2.6.10
Repositories:   /var/opt/gitlab/git-data/repositories
Hooks:          /opt/gitlab/embedded/service/gitlab-shell/hooks/
Git:            /opt/gitlab/embedded/bin/git

解決方法

解決は方法はリンクをhooksの正しい向き先に修正するだけです。
パッケージ版に移行して、リポジトリの場所、hooksの場所を変えていない場合、以下のコマンドで、全てのリポジトリのhooksのリンク先を修正できます。

find /var/opt/gitlab/git-data/repositories -name \*.git -type d -exec sh -c 'ln -sf /opt/gitlab/embedded/service/gitlab-shell/hooks $0' {} \;

まとめ

hooksのリンクだけでなく、ディレクトリ構成、設定ファイルの変更、更新方法、rakeタスクの実行コマンドなどGitlabはパッケージからインストールした時とソースからインストールした時で異なる部分が多いです。
今回のことで移行時はもちろん、移行後の運用でも動作や設定がうまくいかない時はソース版とパッケージ版の違いを調べた方がいいということが分かりました。