リモートレポジトリ作成をAnsibleで自動化する

Gitでコードを共有するのにリモートレポジトリを作成したいがGithubへのアクセスや社内のGitlabサーバはない、そんなときはふつうのLinuxマシンにベアレポジトリを作ってリモートレポジトリにしてしまいましょう。

レポジトリの作成手順

はじめに

ソースファイル共有をするだけならもちろんftpやsamba、rsyncを使ってもいいのですが、Gitならではの利点があります。

  • バージョン管理ができる
  • (特にWindows向けに)改行コードの違いを吸収。Gitの設定で、WindowsではCR+LF、LinuxではLFへ自動的に変換してくれるのでユーザは意識する必要がない
  • ポートはSSHさえ開いていれば大丈夫

作成にあたっては、ここのサイトを参考にさせて頂きました。

やっているのは、ノンベアレポジトリからベアレポジトリをクローンし、ベアレポジトリをリモートレポジトリとして共有させる、という仕掛けを作ることです。
複数のコマンドを打たなければならず、やや複雑で間違えやすいので、ここではAnsibleを使って自動化することにしました。リモートレポジトリにしたいLinuxサーバ上でAnsibleを動かして設定していきます。

ベアではなくノンベアレポジトリをリモートレポジトリにすることも、不可能ではありませんが推奨されていません。簡単に壊せるからでしょうかね。

Ansibleにはレポジトリを管理するgitモジュールがありますが、やりたい使い方が違うのでここではすべてshellモジュールで処理しています。

下準備

以下リモートレポジトリを作成する予定の、サーバ側での作業です。
前提条件となるSSH(OpenSSH server)、Ansible、Gitをインストールしておきます。以下はCentOSでの例です。
また、既存のものを使い回したくない場合には、別途専用のユーザを作成しておいて下さい。

Ansibleで実行するため、後半に掲載するPlaybook一式をコピーするなどして作成しておいて下さい。

レポジトリ管理フォルダの作成

Gitレポジトリで利用する予定のユーザでログインします。
localhost.ymlに所望の設定を記載したあと、setup.ymlで記述したPlaybookを実行します。
Playbook一式は長いので後でまとめて記載しますが、ここでは動作を解説しておきます。

このPlaybookで設定しているのは、レポジトリを配置するための管理ディレクトリの作成です。
パスはどこでもいいのですが、ここでは例としてreposという名前でホームディレクトリの直下にディレクトリを作成します。後ほど、各レポジトリ用のサブディレクトリをこのディレクトリの直下に作る予定です。

ローカルレポジトリを作成するGitユーザがアクセスできるようパーミッションを設定しておきます。

レポジトリの作成

前のセクションで作成した管理ディレクトリの下に、レポジトリ用のディレクトリを作ります。レポジトリが必要になったときに都度実行する想定です。
次のように、up_repo.ymlにオプションrepo_nameを渡すことで、レポジトリ名を指定します。それ以外の設定を指定する必要はありません。

この例では、管理ディレクトリreposの下に、ノンベアレポジトリmyproject.gitとベアレポジトリmyproject.remote.gitの二つのディレクトリが作成されます。

リモートレポジトリの利用

ベアレポジトリ(myproject.remote.git)をクローンすることで、複数のクライアントからベアレポジトリ(=リモートレポジトリ)を共有できます。クライアント側でgit cloneを実行して下さい。

レポジトリには最初のファイルとしてplaceholderファイルが追加されていますが、実際のコードを作成していく際には削除して構いません。

あとは通常のリモートレポジトリと同様に使えますが、パスワード入力を省略するには、クライアント側でssh-copy-idコマンドを使ってコピーするか、またはサーバ側の~/.ssh/authorized_keysファイルに追記することで公開鍵を登録しておきます。
下記はクライアントでの例です。

ベアレポジトリのmasterブランチへのプッシュをフックして、ノンベアレポジトリが更新されるように設定されています。ノンベアレポジトリには、以降各クライアントからプッシュしたmasterブランチと同じソースコードが格納されているはずです。

サーバ側でCI用のテストを動かす、バックアップを作成するなど平文のソースコードが必要な場合はノンベア(からコピーしたもの)を使います。

Playbook一式

Playbookと必要な設定ファイルを、任意のディレクトリに次のような構成として格納しています。

管理ディレクトリ作成:setup.yml

管理ディレクトリを作成するPlaybookファイルです。設定ファイル(localhost.yml)を参照しています。

レポジトリ作成:up_repo.yml

各レポジトリを作成するPlaybookファイルです。設定ファイル(localhost.yml)を参照しているので、前のsetup.ymlファイル実行時と同じ値になるように注意して下さい。

Playbookの中でrmコマンドを呼んでいるタスクがありますがレポジトリの重複を防ぐためのものです。トリッキーですが、同じ名前を持つディレクトリがすでに存在した場合、Playbookを停止させます。

設定ファイル:localhost.yml

repo_base_dirに管理ディレクトリを作成する先のパスを記載しておきます。setup.yml実行時に作成されるので、予め実在するパスである必要はありません。

フック用スクリプト:post-receive

ベアレポジトリ側に設定されるスクリプトです。

最初のファイル:placeholder

レポジトリが作成される際に最初のファイルとして追加されるファイル。内容は何でも良いのですが、Playbook(up_repo.yml)内で値を書き換えているので、この記載にしておけば動作が確認できます。
必要に応じて.gitignoreなどにしても便利かも知れません。