Jenkins アドベントカレンダー 2013 の12/3 の分の続編となります。
引き続き、Redmine絡みのお話で申し訳ありません…。
前回の記事では、こんなことを書きました。
- ALMiniumのセットアップをJenkins + Vagrantで自動やってしまおう
- せっかくだから、Serverspec とブラウザ表示(Selenium) のテストもしてみよう!
All-in-OneインストーラーのALMiniumではありますが 参照しているソース/バイナリは日々変わり続けています。
そのため、意外にインストールに手こずったり、昨日は通ったインストールも、今日は通らない、なんてことが起こり得ます...。
基本のALMiniuminのインストールはCIっぽくまわせるようになったので、今回は、さらに SSL / Jenkinsも加えてCIしてみることにします。また、ちゃんと組み込まれているかのチェックについても触れることにします。
こんな構成でJenkinsを使ってます (修正版)
前回の記事に載せた図を、少し修正しました。(See: Cacooの図)
Jenkins入りのALMiniumを、ホストOSのJenkins側からセットアップする…という、言葉で表現するとやや分かりにくい内容ですが、概ねこの図の通りの行程になります。
SSL / Jenkinsはデフォルトでは組み込み無し
前回の記事で、Jenkinsからインストールスクリプト (smelt) の実行を呼び出し、うまく行けば後は放置しててもインストールが完了する、と書きました。
ですが、この場合、そのままだとApacheはPlainなhttpのみで SSLではなく、Jenkinsもインストールされません。インストールの最中に、ターミナルで対話モードであれば [ y/N ] を押せばいいのですが、何分待てばいいのか分かりません。
パラメータだけ指定したら、後はお茶を飲んでる間にインストールして欲しい…。
envでパラメータを指定するだけであとは自動で!
smelt というスクリプトを見ると、対話モードでの指定が無い場合は、"ENABLE_JENKINS" / "SSL" という変数の指定があれば、その値を元にインストール有無を判断するようです。
なんとかしてこの値を smelt に渡してあげればよいので、envを使ってこんな感じのShellを実行すればOKになります。
cd /vagrant/alminium && sudo env ENABLE_JENKINS=y SSL=y bash ./smelt
#最初、exportじゃだめなんだっけ?と悩んだりしました…。
ここからがJenkinsさんの出番!
さて、やり方が分かったのですが、『SSL/Jenkins無しでセットアップのチェックをしたい』場合もあれば、そうでない場合もあります。
envで渡す条件も、Jenkinsのパラメータを使ってあげれば、処理のたびに切り替えてチェックができます。
ジョブのステップの一部 (shell / 修正版)
引き続き、Vagrantを使ってCentOSの起動 -> ALMiniumのインストールスクリプトの実行をJenkinsでやっています。
cd VM/${VM_NAME}
if [ ${USE_CLEAN_VM} = "true" ]; then
# 一からマシンを立ち上げる場合はこっち。
vagrant halt
vagrant destroy -f
BUILD_ID=dontKillMe vagrant up
wait
else
# ロールバックした時点でマシンセットアップは飛ばしたい場合はこっち。
BUILD_ID=dontKillMe vagrant up
wait
fi
export LANG=ja_JP.UTF-8
cd VM/${VM_NAME}
rm -fr alminium/*.installed
# ALMiniumインストール前に、sahara を使ってスナップショットを
# 取っておく。
# 失敗したら、rollbackさせて綺麗な状態に戻す。
vagrant sandbox on
vagrant ssh -c "cd /vagrant/alminium && sudo env ENABLE_JENKINS=$ENABLE_JENKINS SSL=$SSL bash ./smelt"
Serverspecで SSL / Jenkins対応になってるかチェック!
前回の記事では、80番 (Apache) の起動のみをチェックしましたが、今回はSSL / Jenkinsについてもテストをするようにしてみます。
require 'spec_helper'
#
# Check for Jenkins
#
describe package('jenkins') do
it { should be_installed }
end
describe service('jenkins') do
it { should be_enabled }
it { should be_running }
end
describe port(8080) do
it { should be_listening }
end
describe file('/etc/sysconfig/jenkins') do
it { should be_file }
it { should be_mode 600 }
it { should be_owned_by 'root' }
it { should be_grouped_into 'root' }
end
# 認証はRedmineのユーザと連携するので、configをチェック
describe file('/etc/httpd/conf.d/jenkins.conf') do
it { should be_file }
it { should contain "Redmine User" }
end
#
# Check for vcs
#
# /var/opt/alminium/ 以下にリポジトリを作ってくれるので、ついでに確認。
#
describe file('/var/opt/alminium/svn') do
it { should be_directory }
it { should be_owned_by 'apache' }
end
describe file('/var/opt/alminium/git') do
it { should be_directory }
it { should be_owned_by 'apache' }
end
describe file('/var/opt/alminium/hg') do
it { should be_directory }
it { should be_owned_by 'apache' }
end
describe file('/var/opt/alminium/maven') do
it { should be_directory }
it { should be_owned_by 'apache' }
end
上記のテスト結果は、こんな感じです。
Seleniumでもテスト!
Seleniumでのチェックも、Jenkinsの画面にアクセスできるか、を追加してみます。(コードは抜粋)
describe "ALMinium Redmineにログイン前" do
it "正しくAlminium Redmineにアクセスできる" do
@driver.navigate.to @base_url
expect(@driver.title).to eq("ALMinium")
@driver.save_screenshot("welcome.png")
end
it "ALMinium Redmineにログインしてアカウントを確認できる" do
@driver.get "#{@base_url}/login"
(@driver.title).should == "ALMinium"
@driver.find_element(:id, "username").clear
@driver.find_element(:id, "username").send_keys "admin"
@driver.find_element(:id, "password").clear
@driver.find_element(:id, "password").send_keys ENV['REDMINE_PASSWD']
@driver.find_element(:name, "login").click
@driver.find_element(:xpath, "//a[@class='user active']").text.include? "admin"
@driver.save_screenshot("login.png")
end
### プラグイン入っているかチェック
it "ALMinium Redmineのプラグイン一覧を確認できる" do
@driver.get "#{@base_url}/admin/plugins"
# サンプル:Code Review Pluginが入っているかチェック
@driver.find_element(:xpath, "//tr[@id='plugin-redmine_code_review']")
@driver.find_element(:xpath, "//tr[@id='plugin-redmine_code_review']/td/span[@class='name']").text.include? "Redmine Code Review plugin"
@driver.save_screenshot("plugins.png")
end
### 追加:Jenkinsのアクセスチェック
it "Jenkinsへのアクセスを確認できる" do
@driver.get "#{@jenkins_auth_url}"
expect(@driver.title).to include("Jenkins")
@driver.save_screenshot("jenkins_welcome.png")
end
end
上記のテスト結果は、こんな感じです。
キャプチャの結果はこんな感じ。
うまくいったら、Promoto!
今回は、ALMiniumのセットアップ用のジョブと、ServerSpec / Seleniumのテストのジョブを分けてみました。
残念ながら、私自身の仕事ではPromoted Build pluginを使う機会が無いので、
- ALMiniumのsmeltスクリプト実行 (Build)
- ServerSpec/ Seleniumのテスト (Test)
に見立てて設定をしてみました。
Build -> Test が上手く行くと、Build側に星マークが付きます。
そうすると、少なくともこのジョブはそれなりに効果(実績のある)ジョブだということが分かるようになります。
#jobの回数が多いのは、涙ぐましいトライアルの跡、と思って下さいませ...
まとめ
以上、前回から少しだけ、Jenkinsを使ったサーバのセットアップの一例ということで、ALMiniumを題材にしてお話を進めてみました。
おかげさまで、CentOS6 & Redmine2.3.4という組み合わせでは、ALMiniumのセットアップスクリプトはほぼ大丈夫というのが分かりました。
逆に、ソースをRedmine2.4に変えてみると、OS標準パッケージは問題は無いものの、Redmine本体のGemとプラグインのGem側とで整合性が取れず、ALMiniumでセットアップを謳っているプラグインが入らなくなってしまいます。
冒頭に書いた通り 日々変わって行くソースを相手にした、All-in-Oneインストーラーの難しさを感じています。
ですが、CIをして行くと、手順が廃れてしまっていないか、というのがきちんと分かるようになります。
ましてや、『ある日を境に通らなくなった…』という記録が残っていれば、原因追及もしやすくなります。
『うまく行った/行かない』の情報だけでも、ALMniumをはじめソースの提供元にフィードバックしていくというのは、重要な情報なんじゃないかと思っています:)
#ちなみに、Ubuntuでも試してみようと書いたものの、Ubuntuはまだうまく行ってません… (><)
明日のJenkins アドベントカレンダー 2013は suzu_vさんです!お楽しみに!