KMC活動ブログ

京大マイコンクラブの活動の様子を紹介します!!

イケてると思う dotfiles の管理方法

イケてると思う 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 レポジトリを作り、その中に zshrctmux.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.elCask をコピーし、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さんによる「八ツ橋シューティングについて 後編」です。