etckeeper で多数のホストの /etc を集約・共有する

etckeeper を使うと /etc の内容と変更履歴を git などのバージョン管理システム (VCS) で手軽に管理できますが、素の etckeeper には /etc の変更をローカルのリポジトリにコミットする機能しかなく、git のような分散 VCS の特徴を生かすことができません。

しかしながら etckeeper と git の組み合わせで、リモートリポジトリとブランチをうまく設定し一工夫を加えることで、多数のホストの /etc の変更をひとつのリポジトリに集約し共有することが簡単にできるようになります。

準備

まずは etckeepr を git で動かしてください。 Debian squeeze では apt-get install etckeeper とするだけで git と etckeeper がインストールされ、 /etc で最初のコミットが作られます。

次に設定を共有するリモートリポジトリの準備をしてください。たとえば gitolite を使うのであれば、まず root で ssh-keygen を実行してパスフレーズなしの SSH 鍵を作るのがよいでしょう。

root@sakura00:~# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
83:11:6d:ff:ac:3a:9a:cd:49:76:77:1c:32:ce:1b:d8 root@sakura00

こうしてできた SSH 公開鍵 /root/.ssh/id_rsa.pub を gitolite に登録します。

ここではリモートリポジトリには git:etc でアクセスできるものとします。

最初のプッシュ

etckeeper のローカルリポジトリ /etc に移動してリモートリポジトリ origin を登録し最初のプッシュを実行します。

root@sakura00:/etc# git remote add origin git:etc
root@sakura00:/etc# git push -u origin master:sakura00
root@sakura00:/etc# git config push.default tracking

ここでのミソはプッシュ先のリモートブランチをローカルブランチと同じ master ではなく sakura00 といったホストを表す名前に設定していることです。また push -u とすることで、同時に origin/sakura00master のトラッキングブランチに指定しています。

さらにリポジトリ設定 push.defaulttracking とすることで、 git push ひとつで master の変更が origin/sakura00 にプッシュされるようになります。

プッシュの自動化とメール通知

etckeeper によるコミットで自動的にプッシュもされるように設定するには、次の内容で /etc/etckeeper/commit.d/90push のようなフックスクリプトを作ります。スクリプトのパーミッションは実行可能にしておいてください。

#!/bin/sh
[ "$VCS" = git ] && [ -d .git ] && git push

私は /etc の変更のサマリやプッシュの結果がメールで通知されてくるとうれしいので次のようなフックスクリプトを使っています。

#!/bin/sh
set -e
if [ "$VCS" = git ] && [ -d .git ]; then
	( git show --stat ; git push ) |
		mail -s "etckeeper $(hostname) $(git log -1 --oneline)" root
fi

これは他のマシン vs069 の例ですが、パッケージのインストールなどで /etc に変更があると次のようなメールが送られてきます。

From: root@vs069
To: root@vs069
Subject: etckeeper vs069 17f0bcd saving uncommitted changes in /etc prior to apt run

commit 17f0bcd5bf02418ce265c593b3aa77abd1c49d80
Author: yaegashi <yaegashi@vs069>
Date:   Mon May 28 01:01:02 2012 +0900

    saving uncommitted changes in /etc prior to apt run

 .etckeeper                |    1 +
 etckeeper/commit.d/90push |    7 +++++++
 2 files changed, 8 insertions(+)
To git:etc
   83c201e..17f0bcd  master -> vs069

リモートリポジトリの活用法

先ほどの例のようにホストごとのリモートブランチにプッシュするように設定しておけば、ひとつのリモートリポジトリに多数のホストの /etc の変更履歴を集めることができます。

さらにこのリポジトリに対して gitweb や Redmine などリポジトリビューワーを設定すれば、各ホストの /etc の変更が一覧できて便利です。ただしセキュリティ上重要なファイルが大量に含まれているわけなので、アクセス権限の設定には十分注意してください。

また他のホストのブランチが登録された時点で git fetch とすることで、他のホストの変更履歴がすべて手元にコピーされ参照できるようになります。これは分散バックアップにもなりますね。

root@sakura00:/etc# git fetch
Fetching origin
remote: Counting objects: 2408, done.
remote: Compressing objects: 100% (1354/1354), done.
remote: Total 2408 (delta 805), reused 2162 (delta 572)
Receiving objects: 100% (2408/2408), 932.11 KiB | 817 KiB/s, done.
Resolving deltas: 100% (805/805), done.
From git:etc
 * [new branch]      vs064      -> origin/vs064
 * [new branch]      vs065      -> origin/vs065
 * [new branch]      vs066      -> origin/vs066
 * [new branch]      vs067      -> origin/vs067
 * [new branch]      vs068      -> origin/vs068
 * [new branch]      vs069      -> origin/vs069
 * [new branch]      vs071      -> origin/vs071
 * [new branch]      vs072      -> origin/vs072
 * [new branch]      vs074      -> origin/vs074
root@sakura00:/etc# git branch -av
* master                   d73e366 Adding /etc/etckeeper/commit.d/90push.
  remotes/origin/sakura00  d73e366 Adding /etc/etckeeper/commit.d/90push.
  remotes/origin/vs064     5863f37 saving uncommitted changes in /etc prior to apt run
  remotes/origin/vs065     d32c4e2 daily autocommit
  remotes/origin/vs066     6d9a9ba committing changes in /etc after apt run
  remotes/origin/vs067     0119d71 Initial commit
  remotes/origin/vs068     614257a saving uncommitted changes in /etc prior to apt run
  remotes/origin/vs069     17f0bcd saving uncommitted changes in /etc prior to apt run
  remotes/origin/vs071     110ac52 committing changes in /etc after apt run
  remotes/origin/vs072     6cee958 committing changes in /etc after apt run
  remotes/origin/vs074     7038c83 committing changes in /etc after apt run

他のホストのファイルをちょっと見たいときには git showgit diff などで直接参照できます。これはわざわざ ssh で見に行ったり scp でコピーしたりするのに比べるとかなり手軽で便利です。

root@sakura00:/etc# git show origin/vs064:passwd
(vs064 のファイル /etc/passwd の内容を表示)
root@sakura00:/etc# git show origin/vs064:etckeeper
(vs064 のディレクトリ /etc/etckeeper の内容を表示)
root@sakura00:/etc# git diff origin/vs064..origin/vs065 passwd
(vs064 と vs065 でファイル /etc/passwd の差分を表示)

なお操作をミスすると /etc の内容が他のホストのものにそっくり入れ替わるなど大変なことになるので注意してください。特に普通の git checkout は絶対に実行してはなりません。心配ならば次のように他の場所にクローンしてそちらを参照するのがよいと思います。

root@sakura00:~# git clone git:etc /root/git/etc
root@sakura00:~# chmod 700 /root/git

この場合もやはりファイルアクセスパーミッションには注意してください。

まとめ

etckeeper と git を使い、多数のホストの /etc をひとつのリポジトリに集約して共有およびバックアップする方法を紹介しました。

さらに git pull を自動化すればリモートリポジトリを介して複数ホストの設定を同時にデプロイするようなこともできるかもしれません。

アクセス権限設定や操作ミスにはくれぐれも注意してください。

2012/05/27 18:40:00 JST