etckeeperで設定ファイルのバージョン管理を始めよう

斎藤です。こんにちは。

今日は、etckeeperを用いて、設定ファイルをバージョン管理する方法を説明します。設定ファイルの書き換えで辛い目に遭う前に、どうぞお試しください。

※CentOS 6.4, Ubuntu 12.04 LTS, etckeepr 1.7を基準に説明します

etckeeperとは

etckeeperは主に/etc配下をVCS(Version Control Systems)を用いてバージョン管理します。実態は、gitやmercurialのwrapperとなっています。

設定ファイルの書き換えの際に、ファイル名に日付をつけてバックアップしたりする手間を省いたり、誤って書き換えてしまったときのための 保険 として利用する事ができます。

インストール方法

はじめに

先程も述べました通り、etckeeperはVCSのwrapperとして動きます。そのため、インストール時には必ず次の4つのいずれかのVCSを導入する必要があります。

  • git
  • mercurial (hg)
  • buzzar
  • darcs

パッケージからインストールする場合、CentOSではgit、Ubuntuではbuzzarが用いられています。もちろん、設定ファイルの書き換えによって好みのVCSに切り替える事が可能です。当社ではmercurialに設定している事例もあります。なお、本記事ではgitを利用している前提で説明します。

CentOS --- パッケージによるインストール

CentOS では、epel(Extra Packages for Enterprise Linux)リポジトリが利用できる場合、パッケージマネージャからのインストールが可能です。

# yum install etckeeper

gitがインストールされていない場合は、ここで同時にインストールできます。

CentOS --- ソースコードからのインストール

CentOSを利用されている方で、epelリポジトリを利用する設定にしていない方もいらっしゃるかと思います。その場合は、ソースコードからRPMパッケージを作成し、インストールします。

まず、RPMをビルドする環境を整えます。既にビルド環境をお持ちの方はここを読み飛ばしてかまいません。

$ yum groupinstall "Development Tools"
$ yum install rpm-build git
$ mkdir -p ~/rpmbuild/{BUILD,SRPMS,SPECS,SOURCES,RPMS}
$ echo "_topdir ~/rpmbuild" > ~/.rpmmacros

続いて、etckeeperのRPMをビルドします。

$ cd ~/rpmbuild/SOURCES
$ git clone git://git.kitenet.net/etckeeper.git
$ cd etckeeper
$ tar zcf etckeeper_$(sed -n '2,1p' etckeeper/etckeeper.spec | sed -e "s/Version: \([0-9\.]*\)/\1/").tar.gz etckeeper
$ cp -a etckeeper/etckeeper.spec ../SPECS/
$ cd ~/rpmbuild/SPECS
$ rpmbuild -bb etckeeper.spec
$ cd ~/rpmbuild/RPMS/x86_64
$ sudo yum install etckeeper-1.7-4.el6.x86_64.rpm
$ etckeeper vcs version
(gitのバージョン情報が表示されればOK)

以上で、インストール完了です。

Ubuntu

Ubuntuでは、標準のリポジトリからインストール可能です。

$ sudo apt-get install etckeeper

bazzarがインストールされていない場合は、ここで同時にインストールできます。

利用方法

リポジトリの初期化

まずはリポジトリの初期化を行います。パッケージのインストール時に行われない場合もありますので、念のため実施してください。

まず、VCSの管理配下にいる事を確認します。

# etckeeper vcs status
fatal: Not a git repository (or any of the parent directories): .git

"fatal"と出ている場合、管理下になるようリポジトリを初期化します。

# etckeeper init
Initialized empty Git repository in /etc/.git/

# etckeeper vcs status
 # On branch master
 #
 # Initial commit
 #
 # Changes to be committed:
 #   (use "git rm --cached ..." to unstage)
 #
 #  new file:   .etckeeper
(以下省略)

以上でリポジトリの初期化が完了しました。

変更時

コミットのコマンドを実行します。内部で、設定したVCSのコミットコマンドをラップして実行しています。

# etckeeper vcs diff HEAD   # diffを表示 これはVCSがgitの時のコマンド
# etckeeper commit "input your comment."

cronによる自動保存

cronを用いて、自動保存する事もできます。パッケージからインストールした場合、自動的にcron.dailyに自動保存のタスクが登録されます。これで、万一コミットし忘れた場合でも1日前の編集なら復元できます。便利ですね。

パッケージマネジャを通じたインストール・アンインストール時の自動保存

yum, aptなどのパッケージマネジャを利用する際、インストール直前・直後それぞれの設定ファイルの状態を保存することができます。パッケージからインストールした場合、pre, postのタスクが自動登録されます。

以下は、実際にApacheをインストールした際の例です。

# yum install httpd
Loaded plugins: etckeeper, fastestmirror
Loading mirror speeds from cached hostfile
(中略)
Running Transaction
etckeeper: pre transaction commit
  Installing : apr-util-ldap-1.3.9-3.el6_0.1.x86_64                                                       1/3 
  Installing : httpd-tools-2.2.15-29.el6.centos.x86_64                                                    2/3 
  Installing : httpd-2.2.15-29.el6.centos.x86_64                                                          3/3 
etckeeper: post transaction commit
  Verifying  : httpd-2.2.15-29.el6.centos.x86_64                                                          1/3 
  Verifying  : httpd-tools-2.2.15-29.el6.centos.x86_64                                                    2/3 
  Verifying  : apr-util-ldap-1.3.9-3.el6_0.1.x86_64                                                       3/3 

Installed:
  httpd.x86_64 0:2.2.15-29.el6.centos                                                                         

Dependency Installed:
  apr-util-ldap.x86_64 0:1.3.9-3.el6_0.1               httpd-tools.x86_64 0:2.2.15-29.el6.centos              

Complete!

# etckeeper vcs log
commit de125667214d42d17db481b59f10fe3e9ce76731
Author: root 
Date:   Tue Sep 3 16:14:23 2013 +0900

    committing changes in /etc after yum run

    Package changes:
    +0:apr-util-ldap-1.3.9-3.el6_0.1.x86_64
    +0:httpd-2.2.15-29.el6.centos.x86_64
    +0:httpd-tools-2.2.15-29.el6.centos.x86_64

commit 84f33d3ae930cf6359e539c8cb8231cf30e8e849
Author: hbadmin 
Date:   Tue Sep 3 16:13:20 2013 +0900

    saving uncommitted changes in /etc prior to yum run

ここから、パッケージをインストールした際に、万一設定ファイルが書き変わってしまっても、復元することができる状態になります。先のcron.dailyによる自動コミットとともに、単にVCSを利用したバックアップよりもより確実なバージョン管理を行う事ができます。

/etc 以外を対象にする

/etc以外、例えばソースからビルドしたApacheのconfファイルをバージョン管理する事もできます。"-d"オプションを付加する点がポイントです。

# etckeeper init -d /usr/local/httpd/conf/
# etckeeper commit -d /usr/local/httpd/conf/ "Initial commit."

なお、このままでは自動保存の対象になりません。自動保存の対象にする場合は、次の通りcron.dailyにコマンドを追記します。

# vim /etc/cron.daily/etckeeper 
@@ -14,6 +14,9 @@
                if [ -x /usr/bin/etckeeper ] && [ -e /etc/etckeeper/etckeeper.conf ]; then
                        if etckeeper unclean; then
                                etckeeper commit "daily autocommit" >/dev/null
                        fi
+                       if etckeeper unclean -d /usr/local/httpd/conf/; then
+                               etckeeper commit -d /usr/local/httpd/conf/ "daily autocommit" >/dev/null
+                       fi
                fi
        fi
 fi

復元

ここまで、主に保存方法についてお話ししました。ここからは、肝心の復元方法です。

「うぁぁぁ、やっちまった!」。そんなときのために設定したのがetckeeperだったはずです。しかし、困った事にetckeeperには復元のためのラップしたコマンドはありません...。

従って、"etckeeper vcs"コマンドを通じて、VCS標準のコマンドを実行します。ここでは、"sysctl.conf"を誤って編集したと想定し、作業をします。

# vim /etc/sysctl.conf
# etckeeper vcs diff HEAD
diff --git a/sysctl.conf b/sysctl.conf
index 1fe3fdd..4d04c2c 100644
--- a/sysctl.conf
+++ b/sysctl.conf
@@ -38,3 +38,5 @@ kernel.shmmax = 68719476736

 # Controls the maximum number of shared memory segments, in pages
 kernel.shmall = 4294967296
+
+kernel.panicc = 30

# etckeeper commit -m "Add kernel.panic."

"kernel.panic"の綴りがおかしいまま、コミットしてしまいました。とても残念な状況です。仕方ないので復元しましょう。

# etckeeper vcs log
commit d690aad85ef0aacf881cb70e39cdc473fce8120b
Author: hbadmin 
Date:   Tue Sep 3 14:52:17 2013 +0900

    Add kernel.panic.

commit 7cfddebf6934c0e106979d674f4ea26e1f583bfb
Author: hbadmin 
Date:   Tue Sep 3 14:49:17 2013 +0900

    Initial commit.

誤って編集してしまったバージョンは、"d69"で始まるものになります。こちらにrevertしましょう。

# etckeeper vcs revert -n d690aad85ef0aacf881cb70e39cdc473fce8120b
Finished one revert.
# etckeeper vcs diff HEAD
diff --git a/sysctl.conf b/sysctl.conf
index 4d04c2c..1fe3fdd 100644
--- a/sysctl.conf
+++ b/sysctl.conf
@@ -38,5 +38,3 @@ kernel.shmmax = 68719476736

 # Controls the maximum number of shared memory segments, in pages
 kernel.shmall = 4294967296
-
-kernel.panicc = 30

これで復元する事ができました。バージョン管理、様々です。とはいえ、etckeeper側で何とかなればいいのですが...

おわりに

ここまで、etckeeperを用いた設定ファイルのバージョン管理方法についてお話ししました。

プログラムのソースコードのように設定ファイルをバージョン管理する事で、編集履歴の管理、及び誤って編集してしまった場合の復元が容易に行える事を説明しました。また、パッケージのインストール時や日次で自動コミットされる事で、コミットし忘れによる復元できないトラブルも最小限にする事ができます。

ただし、復元にはetckeeperがラップしたVCS、例えばgitのコマンドを用いて復元する必要がある点に気をつけなければなりません。とはいえ、ファイル名に日付を付けてバックアップし続けるよりは、/etcディレクトリ配下を美しくかつ履歴を追いやすい状況にする事ができます。

最後に、VCSの利用全般に言える事ですが、コミット時のコメントは「後で見てもわかりやすい」ものにしておきましょう。とりあえずこれでいいや、というものを書いてしまうと、半年後に何を意図してコミットしたかわからなくなってしまいかねません。

設定ファイルの管理に際し、本記事がお役に立てば幸いです。

それでは皆様、ごきげんよう。

参考資料