hatenob

プログラムって分からないことだらけ

一人Web開発~第11夜 Jenkins導入

CIできるようにJenkinsを導入します。
CIといってもまだIntegration Test(IT)のコード書いてないので、まずはこれまでに書いたテストを順に実行できるようにします。
今のところの対象は下の2つ。

  • serverspecのテスト
  • util、ejb、webのJUnitテスト(順番はこの順)

インストール(Jenkins本体)

Jenkinsは、yumで取得可能なパッケージを導入することにします。

cookbook_file "/etc/yum.repos.d/jenkins.repo" do
  action :create
  mode 00644
end

yum_package "jenkins" do
  action :install
  options '--enablerepo=jenkins'
end

service "jenkins" do
  action [:disable, :stop]
end

template "/etc/sysconfig/jenkins" do
  source "jenkins.erb"
  action :create
  mode 00600
end

最後のテンプレートは、Jenkinsの設定関連なので適当に設定しています。
ポート番号がWildflyやNexusとかぶらないように、とかそんなです。

インストール(Maven

Jenkinsでのテスト実施において、JavaコードのビルドやテストにはMavenを使用しますので、インストールと設定をします。Javaコードを書くクライアント側にはすでに入ってますが、サーバ側はまだでした。

# Install Maven

remote_file node[:maven][:file] do
  source node[:maven][:url]
  action :create_if_missing
end

directory "/opt/maven" do
  action :create
  mode 00755
  owner "jenkins"
  group "jenkins"
end

bash "install_maven" do
  cwd "/opt/maven"
  user "jenkins"
  group "jenkins"
  code <<-EOH
    tar --no-same-owner -xzf #{node[:maven][:file]}
  EOH
  not_if { File.exist?("/opt/maven/apache-maven-#{node[:maven][:version]}") }
end

link "/opt/maven/available" do
  to "/opt/maven/apache-maven-#{node[:maven][:version]}"
  user "jenkins"
  group "jenkins"
end

template "/opt/maven/available/conf/settings.xml" do
  source "settings.xml.erb"
  mode 00644
  variables({
    :nexus_host => node[:nexus][:host]
  })
end

最後のsettings.xml以外はダウンロードやシンボリックリンクの作成等、実行可能状態とするまでの記述です。最後のsettings.xmlの中では主に、Mavenリポジトリを以前構築したNexusとするように設定しています。
クライアント側もNexusのホスト名以外は同じで大丈夫なはず。

Jenkins設定

Jenkinsの設定もファイルベースでChefで設定したいところですが、対象のファイルがよく分からないので画面から設定することにします。
4つのプロジェクトを作成します。

  • oneman-utilプロジェクト
  • oneman-ejbプロジェクト
  • oneman-webプロジェクト
  • serverプロジェクト

上3つはMavenプロジェクトで、最後は直接シェルスクリプトを記載するものとしました。
そのほか、Jenkinsの管理画面で先ほどのMavenランタイムを登録しておく等の作業が必要なのと、serverspec実行時にはSSHでroot接続するため、jenkinsユーザがrootにSSH接続できるよう諸々準備しておく必要があります。

また、最初の3つは上から順に依存関係を持たせておくことにします。

server用のプロジェクトはシェル(bash)を使用して実行する形としますが、Jenkinsに長々としたシェルを登録すると、それ自体のテストやバージョン管理が難しいため、予めシェルを作成し、Jenkins側はこれを起動すればよいだけにしておきます。
Jenkins側に登録してるシェルはコチラ。

cd ${WORKSPACE}/platform/test/server
./test_run.sh

呼ばれるシェルはコチラ。最初のほうは本機能とは無関係の共通機能です。

PGMNAME=$(basename $0)

function f_LOG {
  printf "$(date "+%Y-%m-%dT%H:%M:%S%z") %-5s %-15s %s\n" "$1" "${PGMNAME}" "$2"
}

function f_LOG.INFO {
  f_LOG "INFO" "$1"
}

function f_LOG.ERROR {
  f_LOG "ERROR" "$1"
}

# use chef bundle commands (ruby, rake, etc...)
export PATH=$PATH:/opt/chef/embedded/bin

# test target
SPEC=${1:-spec}

f_LOG.INFO "run serverspec test [SPEC=${SPEC}]"

rake ci:setup:rspec ${SPEC}
RC=$?

f_LOG.INFO "end serverspec test [RC=${RC}]"

exit ${RC}

Jenkinsで結果レポートを取得するためにci_reporterというモジュールをインストールしています。
PATHの設定は、Chefにバンドルされたrubyやrakeなんかをそのまま使おうとしているためです。

細かなことは書いてませんが、ひとまずこれでテスト実施可能な環境が出来上がったことになるので回帰テストをしながら進めていくことができるはず。

次はIntegration Testを書きます。