イケてると思う dotfiles の管理方法
この記事は、今年もやります!KMCアドベントカレンダー!! - KMC活動ブログの21日目の記事です。 昨日の20日目の記事はReturn Value Optimization (RVO)の話 【KMCアドベントカレンダー20日目】 - KMC活動ブログでした。
KMC5回生の wacky です。今日は dotfiles の管理方法についての話をします。
dotfiles を管理していないと
何らかの UNIX を長いこと使っていると、ホームディレクトリには自分の書いた .zshrc
や .tmux.conf
などの設定ファイルがたくさん転がっていると思います。そして、長いこと UNIX を使っている人であれば、自分が単一のサーバにしかログインしない、というのは稀でしょう。当然、自分のログインするサーバ全てのホームディレクトリには .zshrc
や .tmux.conf
のコピーが転がっていることになります。
さて、ここで .zshrc
の設定を更新したくなったとしましょう。どこかのサーバで設定を変更したあと scp
などで設定ファイルを他のサーバに移すことになりますが、大抵の場合、この「scp
で設定ファイルを移す」という作業は面倒臭くてサボってしまうことが多いです。そのようなことが重なると、A というサーバでは a という更新が加えられていて、B というサーバでは b という変更が加えられていて……という状況が発生することになります。
dotfiles の管理に Git を使う
というわけで、.zshrc
や .tmux.conf
を管理するのにバージョン管理システムを使おう、という発想が出てきます(今回は Git を使うことにします)。しかし、ホームディレクトリ全体を Git レポジトリにするわけにはいかないので(してる人を見たことはありますが)、 $HOME/.dotfiles
などに Git レポジトリを作り、その中に zshrc
や tmux.conf
などを置き、 $HOME/.zshrc
から $HOME/.dotfiles/zshrc
へシンボリックリンクを張ることになると思います。
この方法であれば、 dotfiles を更新したあとはとりあえず commit & push しておけばよく、後で別のサーバの設定ファイルが古いなー、と思ったらその時に pull する、ということが出来るようになります。
デプロイが面倒臭い
dotfiles の管理に Git を使うのは良いのですが、どうやってシンボリックリンクを張るのか、までは考えていませんでした。 dotfiles の中身が増えてくると、手作業でシンボリックリンクを張るのは骨の折れる作業です。作業ミスも増えるでしょう。また、 emacs のプラグインを Cask で管理するなどのことをしていると「$HOME/.emacs.d/Cask
が更新されたら cask
を実行したい」などの要望が出てきます。自力でスクリプトや Makefile
を書くのも良いですが、もう少し良い方法を考えたいものです。
デプロイに ansible を使う
というわけで、ここで構成管理ツールである ansible を導入してみたいと思います。似たようなものに chef がありますが、今回は以下の2つの理由から ansible を選択しています。
- サーバに特別なソフトをインストールする必要がないこと
- 特別なソフトはいらない、といっても sshd と python2 がないと動きません
- ansible は手元のマシンにさえインストールされていれば OK です
- サーバで sudo を使う権限がなくとも動かせること
以下でいくつか例を見ていきましょう。
$HOME/.tmux.conf
のデプロイ
.dotfiles/roles/tmux/files/tmux.conf
好きな設定を書いてください。
.dotfiles/roles/tmux/tasks/main.yml
--- - action: copy src=tmux.conf dest=~/.tmux.conf mode=0644
tmux.conf
を $HOME/.tmux.conf
にコピーする、という内容です。
.dotfiles/hosts
[test] localhost ansible_python_interpreter=/usr/bin/python2
自分自身へデプロイする場合の設定です。 Arch Linux などの python が python3 へのシンボリックリンクになっているシステムでは ansible_python_interpreter の設定を行ない、python2 を使うことを明示する必要があります。
.dotfiles/test.yml
--- - hosts: test roles: - tmux
ここまで色々と設定を書いたら、あとは
$ cd $HOME/.dotfiles $ ansible-playbook -i hosts test.yml
とすればあとは勝手にやってくれます。
emacs の設定のデプロイ
.dotfiles/roles/emacs/files/init.el
.dotfiles/roles/emacs/files/Cask
好きな設定を書いてください。
.dotfiles/roles/emacs/handlers/main.yml
--- - name: exec_cask action: command ~/.cask/bin/cask chdir=~/.emacs.d
exec_cask
というハンドラを定義しています。
.dotfiles/roles/emacs/task/main.yml
- shell: curl -fsSkL https://raw.github.com/cask/cask/master/go | python3 creates=~/.cask - action: file path=~/.emacs.d mode=0755 state=directory - action: copy src=init.el dest=~/.emacs.d/init.el mode=0644 - action: copy src=Cask dest=~/.emacs.d/Cask mode=0644 notify: - exec_cask
cask
をインストールし、 $HOME/.emacs.d
というディレクトリを作成したあと、 init.el
と Cask
をコピーし、Cask
が更新された場合は先ほど定義した exec_cask
を呼びだします。
.dotfiles/hosts
先ほどと同じです。
.dotfiles/test.yml
--- - hosts: test roles: - emacs
ここまで色々と設定を書いたら、あとは先ほどと同様に
$ cd $HOME/.dotfiles $ ansible-playbook -i hosts test.yml
とすればあとは勝手にやってくれます。
まとめ
dotfiles の管理には ansible を使うことができます。今日の話では触れませんでしたが、ansible は jinja2 というテンプレートを用いることもできます。ansible を実行した祭にはデプロイ先の情報を取得することができるので、うまく設定すればデプロイ先の OS に合わせて設定ファイルを変える、ということもできるようになります。
wacky612/dotfiles に自分の dotfiles があるので参考にしてみてください。
次回予告
明日12月22日(月)のKMCアドベントカレンダーは、 hideyaさんによる「八ツ橋シューティングについて 後編」です。