Serverspecで、各アプリケーションの動作確認や設定の確認に使用するコマンドは、公式サイトのResource Typesで詳細に解説されている。以下では今回の検証に使用したコマンドの用法や注意点などを記述している。
パッケージのインストールの有無を確認するにはdescribe packageを使用する。以下の記述例は複数のパッケージをループ処理で確認するものとなっている。
php/php-mysql insall check %w{ php php-mysql }.each do |pkg| describe package(pkg) do it { should be_installed } end end
バージョンも含めて確認する場合は以下となる。
# install check describe package('mariadb-server') do it { should be_installed.with_version '5.5 } end
サービスが起動していることと、自動起動が設定されていることの確認にはdescribe serviceを使用する。記述例は以下となる。
# service check describe service('mariadb') do it { should be_enabled } it { should be_running } end
サービスで指定したポートで待ち受け(LISTEN)状態になっていることの確認にはdescribe portを使用する。記述例は以下となる。
# httpd listen port check describe port(80) do it { should be_listening } end
サーバ上のファイルに対しての確認には原則、describe fileを使用する。
(1)ファイルの存在チェック
指定されたファイルが存在するかのチェックの記述例は以下となる。
# wp-config.php file exits check describe file("#{wp_dir}/wp-config.php") do it { should exist } end
(2)ファイルの権限のチェック
ファイルのuser/groupをチェックする記述例は以下となる。記述例では、特定フォルダ以下のファイルのリストを作成し、1個ずつuser/groupをチェックしていく処理になっている。実際に動作させたが、describe fileを1回処理するごとにssh接続が発生し処理に時間がかかり過ぎたため不採用としている。
wordpress file owner/group check (each file/reject) wp_files = Specinfra.backend.run_command( "find #{wp_dir}" ).stdout.chop wp_files.each_line { |wp_file| describe file(wp_file.chomp) do it { should be_owned_by('root') } it { should be_grouped_into('root') } end }
(3)ファイルの記述内容のチェック
「ファイル内の指定の文字列が記述されているか」をチェックする記述例は以下の通り。ただ、この記述の場合、ファイル中に指定された文字列が存在することの確認はできるが、位置までは確認できないので注意が必要である。
# wp-config.php paramaters check describe file("#{wp_dir}/wp-config.php") do it { should contain("define('DB_NAME',.*'#{wp_db_name}');") } it { should contain("define\('DB_USER',.*'#{wp_db_user}'\);") } it { should contain("define\('DB_PASSWORD',.*'#{wp_db_pass}'\);") } it { should contain("define\('AUTH_KEY',.*'#{wp_uniqe_phrse}'\);") } end
containを使う以外にmatchを使う記述方法も存在する。containは廃止が予定されているため、新規に作成するのであれば、こちらのmatchを使用する方が望ましい。
# WordPress version check describe file("#{wp_dir}/readme.html") do its(:content) { should match /Version #{wp_version}/ } end
(4)ファイルの完全一致のチェック
ファイルの記述内容が完全に想定通りになっているかをチェックする記述例は以下の通り。変数にファイルの内容を全て登録し、読み込んだファイルと完全に一致するかを比較している。<<"EOT"からEOTまでが前方の空白も含めて一致している必要があり、スクリプトのnestは無視する必要がある(比較対象のファイルの行がそのままコピーされている形に近い)。
# wordpress.conf check wordpress_conf = <<"EOT" <VirtualHost *:80> ServerName #{hostname} DocumentRoot #{wp_dir} <Directory "#{wp_dir}"> AllowOverride All Options -Indexes </Directory> <Files wp-config.php> order allow,deny deny from all </Files> </VirtualHost> EOT describe file("/etc/httpd/conf.d/wordpress.conf") do it { should contain wordpress_conf } end
(1)コマンドの実行結果(exit code)のチェック
コマンドの実行結果をチェックする記述例は以下となる。記述例はyum check-updateでupdate対象がない場合、exit code=0となることを利用して判定を行っている。
# yum update check describe command("yum check-update") do its(:exit_status) { should eq 0 } end
(2)コマンドの実行時の出力結果のチェック
コマンドの実行結果の出力をチェックする記述例は以下となる。標準出力を対象としているため、:stdoutを使用しているが、エラー出力の場合は、:stderrを使用する。
# mysqladmin ping execute check describe command( "mysqladmin ping" ) do its(:stdout) { should contain('mysqld is alive') } end
(3)コマンド実行で件数を取得する出力結果のチェック
コマンドを実行して、件数を取得し、その結果を基にチェックを行う記述例は以下となる。ある条件で検索した対象の行数や件数をwc -l やgrep -cで数値化する場合に有効な手段となる。
# wordpress file user/group check describe command( "find #{wp_dir} -not -user #{wp_os_user} -or -not -group #{wp_os_group} | wc -l | tr -d '\n'" ) do its(:stdout) { should contain('^0$') } end
標準出力のため、改行コードが付与されてしまう。そのため、tr -dで改行コードを除去している。さらに0件に一致させるために'0'の前後に正規表現で'^'’(行頭を表すメタ文字)と'$'(行末表すメタ文字)を付与して判定を行っている。should containは「行中に指定文字列が含まれる」ことをチェックしているため、'0'のままでチェックを行うと、件数中に0が含まれる(例えば、10件とか909件とか)が正常と誤判定されてしまうこととなる。
(4)コマンド実行結果でチェック処理自体を分岐する
ファイルの有無やシステムの状態によってチェック処理自体を変更する必要がある場合の記述例は以下の通り。
# mariadb logrotate test already_rotate = Specinfra.backend.run_command( "sudo find /var/log/mariadb -name '*.gz' | wc -l" ).stdout.to_i if already_rotate == 0 then describe command("logrotate -vf /etc/logrotate.d/mariadb") do its(:stdout) { should contain('running postrotate script') } end else describe command("logrotate -vd /etc/logrotate.d/mariadb") do its(:stdout) { should contain('log does not need rotating') } end end
このテストケースでは、mariadb-serverのログローテーションを実際に行うことで検証した。ただ、ログローテーションが正常に行われている(すでにgzファイルが存在する)場合は、再実行を行わないよう制御している。
また、lsコマンドでログファイルのgzファイルの件数を取得し、数値化したものを変数に格納している。0件だった場合はlogrotate -vfを、0件以外だった場合はlogrotate -vdを実行する。処理によって出力されるメッセージも異なるため、このような形で実装した。
「Webサイトにアクセスが行えるか」のチェックを以下の実装で行っている。今回はテストサーバ内部からcurlコマンドを利用して、トップページのURLにアクセスし、Body部に書かれている'WordPress'の文字列が取得できることで確認している。
hostname=host_inventory['hostname'] # httpd port open check describe command("curl http://#{hostname}/wp-admin/install.php") do its(:stdout) { should contain('WordPress') } end
Copyright © ITmedia, Inc. All Rights Reserved.