serverspecを試してみる
今回はserverspecを簡単に触ってみました。
インストール
まずはrubyをインストールします。
独立した環境を作りたい為、特定のユーザホームディレクトリ配置したrubyの環境を作ります。
$ cd /usr/local/src $ wget ftp://ftp.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p195.tar.gz $ tar -xvf ruby-2.0.0-p195.tar.gz $ cd ruby-2.0.0-p195 $ ./configure --prefix=/home/myuser/ruby --enable-shared $ make $ make install $ PATH=$PATH:/home/myuser/ruby/bin $ export PATH
serverspecを導入します。gemだけで入ります。
$ /home/myuser/ruby/bin/gem install serverspec Fetching: net-ssh-2.6.7.gem (100%) Successfully installed net-ssh-2.6.7 Fetching: rspec-core-2.13.1.gem (100%) Successfully installed rspec-core-2.13.1 Fetching: diff-lcs-1.2.4.gem (100%) Successfully installed diff-lcs-1.2.4 Fetching: rspec-expectations-2.13.0.gem (100%) Successfully installed rspec-expectations-2.13.0 Fetching: rspec-mocks-2.13.1.gem (100%) Successfully installed rspec-mocks-2.13.1 Fetching: rspec-2.13.0.gem (100%) Successfully installed rspec-2.13.0 Fetching: highline-1.6.19.gem (100%) Successfully installed highline-1.6.19 Fetching: serverspec-0.6.2.gem (100%) Successfully installed serverspec-0.6.2 Parsing documentation for net-ssh-2.6.7 Installing ri documentation for net-ssh-2.6.7 Parsing documentation for rspec-core-2.13.1 Installing ri documentation for rspec-core-2.13.1 Parsing documentation for diff-lcs-1.2.4 Installing ri documentation for diff-lcs-1.2.4 Parsing documentation for rspec-expectations-2.13.0 Installing ri documentation for rspec-expectations-2.13.0 Parsing documentation for rspec-mocks-2.13.1 Installing ri documentation for rspec-mocks-2.13.1 Parsing documentation for rspec-2.13.0 Installing ri documentation for rspec-2.13.0 Parsing documentation for highline-1.6.19 Installing ri documentation for highline-1.6.19 Parsing documentation for serverspec-0.6.2 Installing ri documentation for serverspec-0.6.2 8 gems installed
初期化します。今回はローカル実行にします。
$ /home/myuser/ruby/bin/serverspec-init Select a backend type: 1) SSH 2) Exec (local) Select number: 2 + spec/localhost/ + spec/localhost/httpd_spec.rb + spec/spec_helper.rb + Rakefile
これで準備が出来ました。
使ってみる
テストケースを書いてみました。内訳は以下の通りです。
- SELinuxは無効になっている
- ntpdが起動しており、ntp.nict.jp、ntp.jst.mfeed.ad.jp、ntp.nc.u-tokyo.ac.jpを参照先とする
- 「myuser」というユーザのチェック
- 「/etc/sudoers」のファイルチェック
内容は以下の通りです。
require 'spec_helper' # SELinux describe selinux do it { should be_disabled } end describe command('sestatus') do it { should return_stdout 'SELinux status: disabled' } end describe file('/etc/selinux/config') do it { should contain 'SELINUX=disabled' } end # ntpd describe service('ntpd') do it { should be_enabled } end describe service('ntpd') do it { should be_running } end describe file('/etc/ntp.conf') do it { should contain 'server ntp.nict.jp' } end describe file('/etc/ntp.conf') do it { should contain 'server ntp.jst.mfeed.ad.jp' } end describe file('/etc/ntp.conf') do it { should contain 'server ntp.nc.u-tokyo.ac.jp' } end # User describe user('myuser') do it { should exist } end describe user('myuser') do it { should belong_to_group 'myuser' } end describe user('myuser') do it { should have_uid 2000 } end describe group('myuser') do it { should exist } end group('myuser') do it { should have_gid 2000 } end describe user('myuser') do it { should have_home_directory '/home/myuser' } end describe user('myuser') do it { should have_login_shell '/bin/bash' } end # File describe file('/etc/sudoers') do it { should be_file } end describe file('/etc/sudoers') do it { should be_mode 440 } end describe file('/etc/sudoers') do it { should be_owned_by 'root' } end describe file('/etc/sudoers') do it { should be_grouped_into 'root' } end
実行してみます。
# rake spec (in /home/myuser/test) /home/myuser/ruby/bin/ruby -S rspec spec/localhost/linux_spec.rb ........Fid: myuser: No such user Fid: myuser: No such user FFFF.... Failures: 1) User "myuser" Failure/Error: it { should exist } id myuser id: myuser: No such user # ./spec/localhost/linux_spec.rb:39:in `block (2 levels) in <top (required)>' 2) User "myuser" Failure/Error: it { should belong_to_group 'myuser' } id myuser | awk '{print $3}' | grep -- myuser # ./spec/localhost/linux_spec.rb:43:in `block (2 levels) in <top (required)>' 3) User "myuser" Failure/Error: it { should have_uid 2000 } id myuser | grep -- \^uid\=2000\( # ./spec/localhost/linux_spec.rb:47:in `block (2 levels) in <top (required)>' 4) Group "myuser" Failure/Error: it { should exist } getent group | grep -wq -- myuser # ./spec/localhost/linux_spec.rb:51:in `block (2 levels) in <top (required)>' 5) User "myuser" Failure/Error: it { should have_home_directory '/home/myuser' } getent passwd myuser | cut -f 6 -d ':' | grep -w -- /home/myuser # ./spec/localhost/linux_spec.rb:59:in `block (2 levels) in <top (required)>' 6) User "myuser" Failure/Error: it { should have_login_shell '/bin/bash' } getent passwd myuser | cut -f 7 -d ':' | grep -w -- /bin/bash # ./spec/localhost/linux_spec.rb:63:in `block (2 levels) in <top (required)>' Finished in 0.16055 seconds 18 examples, 6 failures Failed examples: rspec ./spec/localhost/linux_spec.rb:39 # User "myuser" rspec ./spec/localhost/linux_spec.rb:43 # User "myuser" rspec ./spec/localhost/linux_spec.rb:47 # User "myuser" rspec ./spec/localhost/linux_spec.rb:51 # Group "myuser" rspec ./spec/localhost/linux_spec.rb:59 # User "myuser" rspec ./spec/localhost/linux_spec.rb:63 # User "myuser" rake aborted! /home/myuser/ruby/bin/ruby -S rspec spec/localhost/linux_spec.rb failed
「myuser」というユーザが存在しなかったため、これに関係するテストケースが失敗しました。
ということで、ユーザを作成します。
# groupadd -g 2000 myuser # useradd -g 2000 -u 2000 -s /bin/bash -d /home/myuser myuser
もう一度実行すると、テストケースが全て通り、問題が解消された事が確認出来ました。
# rake spec (in /home/myuser/test) /home/myuser/ruby/bin/ruby -S rspec spec/localhost/linux_spec.rb .................. Finished in 0.15403 seconds 18 examples, 0 failures
分かりやすい事もあり、テストケースを増やして環境構築時の品質向上を考えてみようと思います。
今日はこんなところで。