Docker と Vagrant で dotfiles をテストする
イントロ
で書いたとおり、最近は自分の dotfiles
を MItamae
で管理している。
運用していく中で、ちょっと複雑な receipe
を書いた時、「これ試したいけど、いきなりぶっこむのはちょっとなぁ…」と思うようになった。
そこで MItamae
を試すだけ試して、満足したら廃棄できる環境を作ってみた。
ついでに、その sandbox 的環境をテストする serverspec
も一緒に書いたので、まとめてみた。
準備
Dockerfile.serverspec
ローカルに serverspec
をインストールするのは、ruby に依存してしまうのでナシ。
そこで serverspec
を実行する Docker
コンテナを用意した。
よく docker-api
を使って serverspec
でテストするやり方を見かけるけど、Docker
コンテナの中で docker-api
を使えないので、ssh
接続でテストする。
FROM ruby:2.4.1-alpine RUN apk update && apk add openssh-client && echo -e 'Host *\nUseRoaming no' >> /etc/ssh/ssh_config ENV SERVERSPEC_VERSION 2.39.1 RUN gem install serverspec -v ${SERVERSPEC_VERSION} WORKDIR /serverspec
Vagrant
cookbook を試す環境は Vagrant
で用意した。
最初はこれも Docker
でコンテナを用意してやっていたけど、serverspec からアクセスするのはコンテナではなくイメージなので、テストが失敗する
(状況を見るとそのような挙動に見える)
# 以下は Docker で環境を作って、serverspec でテストするパターンを試したときのログ # `ubuntu`(レシピ実行場所) で bash を起動 $ docker-compose run --rm ubuntu bash # MItamae を install root@a16bec43ae35:/home/root# bin/setup.sh # レシピを実行する root@a16bec43ae35:/home/root# bin/mitamae local cookbooks/git/default.rb INFO : Starting MItamae... INFO : Recipe: /home/root/cookbooks/git/default.rb INFO : package[git] installed will change from 'false' to 'true' # git が install された root@a16bec43ae35:/home/root# which git /usr/bin/git # `serverspec` (serverspec 実行用コンテナ)で sh を起動 $ docker-compose run --rm serverspec sh # spec を実行する。`docker-compose` を使うことで `ubuntu` で名前解決している /serverspec # TARGET_HOST=ubuntu rspec spec/git_spec.rb Package "git" should be installed (FAILED - 1) Failures: 1) Package "git" should be installed On host `ubuntu' Failure/Error: it { should be_installed } expected Package "git" to be installed /bin/sh -c dpkg-query\ -f\ \'\$\{Status\}\'\ -W\ git\ \|\ grep\ -E\ \'\^\(install\|hold\)\ ok\ installed\$\' # ./spec/git_spec.rb:4:in `block (2 levels) in <top (required)>' Finished in 0.26349 seconds (files took 0.62787 seconds to load) 1 example, 1 failure Failed examples: # テストを実行しても、ssh で接続した世界には git が入っていない rspec ./spec/git_spec.rb:4 # Package "git" should be installed
レシピを実行した後に docker commit
して、もう一度 image を build して serverspec
を走らせてもできたが、やってみてあまりに面倒に感じたので、スパッとやめてしまった。
ということで一周戻って Vagrant
で環境を作ることになった。
現在のディレクトリを自動的に sync してくれるのも地味に助かった。
Vagrant.configure("2") do |config| config.vm.box = "ubuntu/xenial64" config.vm.network "private_network", ip: "192.168.33.10" end
レシピ実行
昔なつかし、vagrant ssh
からのレシピ実行
$ vagrant up $ vagrant ssh ubuntu@ubuntu-xenial:~$ cd /vagrant ubuntu@ubuntu-xenial:/vagrant$ bin/setup.sh + mitamae_version=1.3.2 + mitamae_cache=mitamae-1.3.2 + [ -f bin/mitamae-1.3.2 ] + uname + mitamae_bin=mitamae-x86_64-linux + wget -O bin/mitamae-x86_64-linux.tar.gz --max-redirect 3 -q https://github.com/k0kubun/mitamae/releases/download/v1.3.2/mitamae-x86_64-linux.tar.gz + tar xvzf bin/mitamae-x86_64-linux.tar.gz mitamae-x86_64-linux + rm bin/mitamae-x86_64-linux.tar.gz + mv mitamae-x86_64-linux bin/mitamae-1.3.2 + chmod +x bin/mitamae-1.3.2 + ln -sf mitamae-1.3.2 bin/mitamae ubuntu@ubuntu-xenial:/vagrant$ bin/mitamae local cookbooks/git/default.rb INFO : Starting MItamae... INFO : Recipe: /vagrant/cookbooks/git/default.rb
テスト
spec_helper.rb
に vagrant に ssh 接続する情報を書く- host は
Vagrantfile
に書いた private な ipaddress を指定 user
とkey
はvagrant ssh-config
の内容をそのまま使う
- host は
- コンテナから
serverspec
を実行する
require 'serverspec' require 'net/ssh' set :backend, :ssh if ENV['ASK_SUDO_PASSWORD'] begin require 'highline/import' rescue LoadError fail "highline is not available. Try installing it." end set :sudo_password, ask("Enter sudo password: ") { |q| q.echo = false } else set :sudo_password, ENV['SUDO_PASSWORD'] end options = Net::SSH::Config.for(host) options[:user] = 'ubuntu' options[:keys] = '.vagrant/machines/default/virtualbox/private_key' set :host, ENV['TARGET_HOST'] || "192.168.33.10" set :ssh_options, options # Disable sudo set :disable_sudo, true Dir['./spec/shared/*'].each { |f| require f }
$ docker run --rm -it -v ${PWD}:/serverspec --net=host dotfiles_serverspec rspec spec/ubuntu_spec.rb ubuntu behaves like git Package "git" should be installed Finished in 1.15 seconds (files took 0.60525 seconds to load) 1 example, 0 failures
まとめ
ここまですると逆に面倒くさくなってきて、もはや趣味の領域に入りつつあります。
それと Mac 環境でのテストになってなくて、当初目標にしていた事が実現できたとは言い難い。
しかしながら、いつでも OS X を捨てられる準備をしておかないと、もし Apple がとんでもない改悪をしても、
それに耐え続けなければならなくなるし、私はそれを我慢し続けられるほど大人では無いという自覚がある。
ということで目的とはズレてしまったが、 Mac
を捨てる準備を整えることができた、という副産物が得られたので良しとしたい。
それと、少しづつテストやレシピを補完していきたい。