Git
Redmine
同期

外部のgitリポジトリを自前のRedmineのリポジトリ管理に追加する方法

sync_git_repos.png

Redmineのリポジトリ管理におけるリポジトリパスにはlocalhost上のパスしか設定できないため、リモートリポジトリが外部サーバにある場合は自サーバ上にクローンしなければならないが、二重管理は手間なのでこれを同期させることで、データベースでいうレプリケーション構成のスレーブ参照のような設定とします。

図でいう、左上が本来のリモートリポジトリです。上述のレプリケーションの例でいうマスタに相当します。左下は通常の開発におけるローカルリポジトリ。

一方、右上には別サーバ(Redmineのインストールしてあるサーバ)に同期されたリモートリポジトリです。例でいうスレーブに相当します。今回の記事の主役です。右下にはそこから取得したリポジトリがRedmineから常に最新常態で確認できるようになります。

ここでは便宜的に、左上のリモートリポジトリのサーバーをmaster.com、右上のリモートリポジトリのサーバーをslave.comと称します。

サーバーの操作アカウントは仮にreposとします(もちろんそれぞれのサーバーで異なっても構いません)。それぞれ実際のものに読み替えてください。

では構築例です。


1. SSH鍵ペアの用意


  • master.com⇒slave.comの鍵

  • slave.com⇒master.comの鍵

のふたつを用意しておきます。

なぜふたつ必要になるのかは追って説明します。

なお、同期を双方向のSSHプロトコルを介した自動化処理で実現する都合上、いずれも秘密鍵はパスフレーズなしで作成してください。


2. repos@slave.com

master.comへのSSH接続を許可するため、秘密鍵を設置します。

vi ~/.ssh/master.com.ppk

slave.com⇒master.comの秘密鍵

chmod 0600 ~/.ssh/master.com.ppk

SSH接続をおこなうために必要な接続先ホストの固有な接続情報を定義します。

vi ~/.ssh/config

host master.com
user repos
identityfile ~/.ssh/master.com.ppk

chmod 0600 ~/.ssh/config

master.comからSSH接続を許可するため、公開鍵を設置します。

vi ~/.ssh/authorized_keys

master.com⇒slave.comの公開鍵

chmod 0600 ~/.ssh/authorized_keys

ここで一度手動でSSHログインをおこない、初回known_hostsへの登録時のプロンプトを通しておき次回以降は暗黙ログインができるようにしておきます。

ssh master.com


3. repos@slave.com

slave.comへのSSH接続を許可するため、秘密鍵を設置します。

vi ~/.ssh/slave.com.ppk

master.com⇒slave.comの秘密鍵

chmod 0600 ~/.ssh/slave.com.ppk

上記秘密鍵を使った鍵認証方式でgitを操作するために読み込ませるスクリプトを用意します。

vi ~/.ssh/slave.com.sh

#!/bin/sh
exec ssh -o IdentityFile=~/.ssh/slave.com.ppk "$@"

chmod 0700 ~/.ssh/slave.com.ppk

上記スクリプトを自動で読み込ませる設定を追加します。

vi ~/.bashrc

GIT_SSH=~/.ssh/slave.com.sh

. ~/.bashrc

SSH接続をおこなうために必要な接続先ホストの固有な接続情報を定義します。

vi ~/.ssh/config

host slave.com
user repos
identityfile ~/.ssh/slave.com.ppk

chmod 0600 ~/.ssh/config

slave.comからSSH接続を許可するため、公開鍵を設置します。

vi ~/.ssh/authorized_keys

slave.com⇒master.comの公開鍵

chmod 0600 ~/.ssh/authorized_keys

ここで一度手動でSSHログインをおこない、初回known_hostsへの登録時のプロンプトを通しておき次回以降は暗黙ログインができるようにしておきます

ssh slave.com

slave.com側にリモートリポジトリのクローンをつくっておきます。

mkdir ~/{slave.comのベアレポジトリの配置するディレクトリ}/

git clone --bare ssh://repos@master.com:22/home/repos/{master.comのベアレポジトリのパス}/


4. repos@slave.com

master.comのリモートリポジトリにpushされたら、hookスクリプトを通じてslave.comのリモートリポジトリからfetchさせることで同期できる設定をおこないます。

vi ~/{master.comのベアレポジトリのパス}/hooks/post-receive

#!/bin/sh
ssh -i ~/.ssh/slave.com.ppk repos@slave.com "cd ~/{slave.comのベアレポジトリのパス}/ && git fetch origin 'refs/heads/*:refs/heads/*'"

chmod 0770 ~/{master.comのベアレポジトリのパス}/hooks/post-receive

(パーミッションは環境にあわせて読み替えてください)


以上です。

これでslave.comのリモートリポジトリはmaster.comへのpushをトリガーに更新情報が同期され、master.comはそのままで、slave.com側のRedmineは最新のリポジトリ情報を参照することができるようになります。

4.がこの設定の要の部分なので、もう少し説明しますと、

まず、masterへのpushで自動実行されるpost-receiveで、slave.comにSSHログインします。この方向で「1. SSH鍵ペアの用意」で作成した「master.com⇒slave.comの鍵」を利用します。

次にログインしたslave.comから再びmaster.com側にSSH経由でgit fetchをおこないます。この方向で「1. SSH鍵ペアの用意」で作成した「slave.com⇒master.comの鍵」を利用します。

ベアリポジトリではgit pullが使えないため、git fetchでブランチ情報を更新するようにしています。

冒頭の図の左下にあたる、ローカルリポジトリからgit pushしてみてください。

すぐにRedmine側でもその更新内容が、画面から確認できるようになっているかと思います。

slave.com側のpost-receiveでも同様な設定を記述することで、双方向のデュアルマスタのような構成にもできるのではないかと思います。