OpenShiftでお手軽CI環境を作る話です。
Jenkinsカートリッジの利用
OpenShiftでは、Jenkinsが稼働するギアを用意することができます。Webアプリケーションが稼働するギアに、「Jenkins Client」のカートリッジを入れると、「git push」した後のビルド処理がJenkins上で実施されるようになります。これにより、過去のビルド履歴を管理したり、Jenkins上でビルド処理のカスタマイズなども可能になります。また、Jenkinsを使わない場合、ビルド処理は、各アプリケーションのギア上で直接に行われるため、ビルドに失敗すると、アプリケーションが停止するなどの危険性がありますが、それを避けることもできます。
ここでは、例として、TomcatのアプリケーションをJenkinsでビルドする環境を用意してみます。
なお、Jenkinsによるビルド処理のタイミングで、Jenkinsが稼働するギアとは別に、ビルド処理用のギアが立ち上がります。OpenShift Onlineの無償版では、ギアは3個までに制限されているので、以下の作業は、全てのアプリケーションを削除してから実施してください。(Tomcat/Jenkins/ビルド用で、ちょうど3個のギアを消費します。)Jenkinsによるビルド処理の流れは、こちらに記載があります。
Tomcat環境の用意
OpenShiftでは、「JBoss EWS」カートリッジにより、Tomcatが利用できます。(ちなみに、「JBoss EWS/Enterprise Web Server」は、Red Hatの商用サポート付きのTomcatベースのWebアプリケーションサーバ製品です。)
# rhc app create -a tomcat -t jbossews-1.0 Password: ******** Creating application 'tomcat' ============================= Scaling: no Namespace: enakaidom Cartridge: jbossews-1.0 Gear Size: default ...
いつもの(?)デフォルトコンテンツが用意されていますが、gitの練習を兼ねて、GitHubで公開されているサンプルアプリケーションをpullしてみます。
# cd tomcat # git config --global user.email "xxxxxx" # git config --global user.name "E.Nakai" # git remote add upstream -m master git://github.com/openshift/tomcat6-example.git # git pull -s recursive -X theirs upstream master # git push
最後に「git push」すると、ギアにソースが転送されて、ギア上でビルドが走ります。大量の出力がありますが、最初の方に、次の一行が確認できます。
remote: Found pom.xml... attempting to build with 'mvn -e clean package -Popenshift -DskipTests'
JBoss EWSの他に、JBoss EAPなど、Java系のカートリッジでは、上記のMavenコマンドでビルド処理が行われます。したがって、ローカルの「pom.xml」を編集して、ビルド処理をカスタマイズすることも可能です。
ただし・・・、今回は、Jenkinsでビルドすることが目的ですので、これはそのままにして、次に進みます。
Jenkins環境の用意
まず、Jenkinsが稼働するギアを用意します。
# rhc app create -a jenkins -t jenkins-1.4 Password: ******** Creating application 'jenkins' ============================== Gear Size: default Namespace: enakaidom Scaling: no Cartridge: jenkins-1.4 ... Jenkins created successfully. Please make note of these credentials: User: admin Password: yWW7qQpmAinC Note: You can change your password at: https://jenkins-enakaidom.rhcloud.com/me/configure
最後に、Jenkinsの管理画面のURLとadminパスワードが表示されていますので、指定のURLを開いてパスワードを変更しておきます。
続いて、既存のTomcat環境に、「Jenkins Client」のカートリッジを追加します。
# rhc cartridge add jenkins-client-1.4 -a tomcat Password: ******** Adding 'jenkins-client-1.4' to application 'tomcat' Success jenkins-client-1.4 ================== Properties ========== Job URL = https://jenkins-enakaidom.rhcloud.com/job/tomcat-build/
最後に表示されたURLにアクセスすると、Jenkinsに新たなプロジェクト(tomcat-build)が追加されていることが分かります。
設定を確認すると、ビルド処理は次のシェルスクリプトが指定されています。
source /usr/libexec/openshift/cartridges/abstract/info/lib/jenkins_util jenkins_rsync 9fe0cfff84a745128d2c457f5935ee82@tomcat-enakaidom.rhcloud.com:~/.m2/ ~/.m2/ # Build setup and run user pre_build and build . ci_build.sh if [ -e ${OPENSHIFT_REPO_DIR}.openshift/markers/java7 ]; then export JAVA_HOME=/etc/alternatives/java_sdk_1.7.0 else export JAVA_HOME=/etc/alternatives/java_sdk_1.6.0 fi export MAVEN_OPTS="$OPENSHIFT_MAVEN_XMX" mvn --global-settings $OPENSHIFT_MAVEN_MIRROR --version mvn --global-settings $OPENSHIFT_MAVEN_MIRROR clean package -Popenshift -DskipTests # Deploy new build # Stop app jenkins_stop_app 9fe0cfff84a745128d2c457f5935ee82@tomcat-enakaidom.rhcloud.com # Push content back to application jenkins_sync_jbossews 9fe0cfff84a745128d2c457f5935ee82@tomcat-enakaidom.rhcloud.com # Configure / start app $GIT_SSH 9fe0cfff84a745128d2c457f5935ee82@tomcat-enakaidom.rhcloud.com deploy.sh jenkins_start_app 9fe0cfff84a745128d2c457f5935ee82@tomcat-enakaidom.rhcloud.com $GIT_SSH 9fe0cfff84a745128d2c457f5935ee82@tomcat-enakaidom.rhcloud.com post_deploy.sh
ソースをrsyncで持ってきて、Mavenでビルドして、再度、rsyncで送り返しているようです。
なお、Jenkinsのプラグインを見ると、「OpenShift Origin Jenkins Cloud Plugin」が追加されています。これで、OpenShiftとの連携を行なっているものと思われます。
少しソースを変更して、pushしてみます。
# vi src/main/java/mypackage/Hello.java (適当に変更) # git commit -a -m "hoge" # git push Counting objects: 13, done. Delta compression using up to 2 threads. Compressing objects: 100% (6/6), done. Writing objects: 100% (7/7), 581 bytes, done. Total 7 (delta 2), reused 0 (delta 0) remote: restart_on_add=false remote: Executing Jenkins build. remote: remote: You can track your build at https://jenkins-enakaidom.rhcloud.com/job/tomcat-build remote: remote: Waiting for build to schedule..................................Done remote: Waiting for job to complete.............................................................................Done remote: SUCCESS remote: New build has been deployed. To ssh://9fe0cfff84a745128d2c457f5935ee82@tomcat-enakaidom.rhcloud.com/~/git/tomcat.git/ c0662ed..6383598 master -> master
画面出力から、Jenkinsにビルドを依頼していることが分かります。Jenkinsの画面で、ビルドの成功が確認できます。
Unit Testの追加
せっかくJenkinsと統合できたわけですので、ビルドプロセスにUnit Testを追加してみましょう。
まず、自動作成されたプロジェクトのビルド設定(ビルド→シェルの実行)を見ると、Mavenのオプションに「skipTests」が指定されているので、これをコメントアウトします。
mvn --global-settings $OPENSHIFT_MAVEN_MIRROR clean package -Popenshift ### -DskipTests
ローカルにあるpom.xmlの
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency>
ローカルのソースにテストを追加します。ここでは、デフォルトの必ず成功するテストを入れておきます。。。
src/test/java/mypackage/HelloTest.java
package mypackage; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Unit test for Hello. */ public class HelloTest extends TestCase { /** * Create the test case * * @param testName name of the test case */ public HelloTest( String testName ) { super( testName ); } /** * @return the suite of tests being tested */ public static Test suite() { return new TestSuite( HelloTest.class ); } /** * Rigourous Test :-) */ public void testHello() { assertTrue( true ); } }
あとは、これを commit/push するだけです。
$ git commit -a -m "add unittest" [master a17b839] add unittest 1 files changed, 1 insertions(+), 1 deletions(-) $ git push Counting objects: 13, done. Delta compression using up to 2 threads. Compressing objects: 100% (4/4), done. Writing objects: 100% (7/7), 506 bytes, done. Total 7 (delta 2), reused 0 (delta 0) remote: restart_on_add=false remote: Executing Jenkins build. remote: remote: You can track your build at https://jenkins-demo.example.com/job/tomcat-build remote: remote: Waiting for build to schedule....Done remote: Waiting for job to complete............................................Done remote: SUCCESS remote: New build has been deployed. To ssh://43d9bd0b5b9d44a6a27ea60ca6dbbd66@tomcat-demo.example.com/~/git/tomcat.git/ 5712b64..a17b839 master -> master
Jenkinsのビルドのログをみると、ちゃんとテストフェーズが実行されています。
+ mvn --global-settings /usr/libexec/openshift/cartridges/jbossews-1.0/info/configuration/settings.base.xml clean package -Popenshift [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building tomcat 1.0 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ tomcat --- [INFO] Deleting /var/lib/openshift/b1e2b2cf9e9b48d283af30ca8090d3e1/jbossews-1.0/ci/jenkins/workspace/tomcat-build/target [INFO] [INFO] --- maven-resources-plugin:2.4.3:resources (default-resources) @ tomcat --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 1 resource [INFO] [INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ tomcat --- [INFO] Compiling 1 source file to /var/lib/openshift/b1e2b2cf9e9b48d283af30ca8090d3e1/jbossews-1.0/ci/jenkins/workspace/tomcat-build/target/classes [INFO] [INFO] --- maven-resources-plugin:2.4.3:testResources (default-testResources) @ tomcat --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /var/lib/openshift/b1e2b2cf9e9b48d283af30ca8090d3e1/jbossews-1.0/ci/jenkins/workspace/tomcat-build/src/test/resources [INFO] [INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ tomcat --- [INFO] Compiling 1 source file to /var/lib/openshift/b1e2b2cf9e9b48d283af30ca8090d3e1/jbossews-1.0/ci/jenkins/workspace/tomcat-build/target/test-classes [INFO] [INFO] --- maven-surefire-plugin:2.7.2:test (default-test) @ tomcat --- [INFO] Surefire report directory: /var/lib/openshift/b1e2b2cf9e9b48d283af30ca8090d3e1/jbossews-1.0/ci/jenkins/workspace/tomcat-build/target/surefire-reports Downloading: http://maven.repository.redhat.com/techpreview/all/org/apache/maven/surefire/surefire-junit3/2.7.2/surefire-junit3-2.7.2.pom Downloading: http://repo1.maven.org/maven2/org/apache/maven/surefire/surefire-junit3/2.7.2/surefire-junit3-2.7.2.pom 2 KB Downloaded: http://repo1.maven.org/maven2/org/apache/maven/surefire/surefire-junit3/2.7.2/surefire-junit3-2.7.2.pom (2 KB at 77.2 KB/sec) Downloading: http://maven.repository.redhat.com/techpreview/all/org/apache/maven/surefire/surefire-providers/2.7.2/surefire-providers-2.7.2.pom Downloading: http://repo1.maven.org/maven2/org/apache/maven/surefire/surefire-providers/2.7.2/surefire-providers-2.7.2.pom 2 KB Downloaded: http://repo1.maven.org/maven2/org/apache/maven/surefire/surefire-providers/2.7.2/surefire-providers-2.7.2.pom (2 KB at 127.7 KB/sec) Downloading: http://maven.repository.redhat.com/techpreview/all/org/apache/maven/surefire/surefire-junit3/2.7.2/surefire-junit3-2.7.2.jar Downloading: http://repo1.maven.org/maven2/org/apache/maven/surefire/surefire-junit3/2.7.2/surefire-junit3-2.7.2.jar 4 KB 8 KB 12 KB 14 KB 15 KB 19 KB 23 KB 26 KB Downloaded: http://repo1.maven.org/maven2/org/apache/maven/surefire/surefire-junit3/2.7.2/surefire-junit3-2.7.2.jar (26 KB at 1417.9 KB/sec) ------------------------------------------------------- T E S T S ------------------------------------------------------- Running mypackage.HelloTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.079 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] --- maven-war-plugin:2.1.1:war (default-war) @ tomcat --- [INFO] Packaging webapp [INFO] Assembling webapp [tomcat] in [/var/lib/openshift/b1e2b2cf9e9b48d283af30ca8090d3e1/jbossews-1.0/ci/jenkins/workspace/tomcat-build/target/tomcat] [INFO] Processing war project [INFO] Copying webapp resources [/var/lib/openshift/b1e2b2cf9e9b48d283af30ca8090d3e1/jbossews-1.0/ci/jenkins/workspace/tomcat-build/src/main/webapp] [INFO] Webapp assembled in [110 msecs] [INFO] Building war: /var/lib/openshift/b1e2b2cf9e9b48d283af30ca8090d3e1/jbossews-1.0/ci/jenkins/workspace/tomcat-build/webapps/ROOT.war [INFO] WEB-INF/web.xml already added, skipping [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 29.184s [INFO] Finished at: Thu Jan 17 13:49:39 JST 2013 [INFO] Final Memory: 21M/51M [INFO] ------------------------------------------------------------------------
まだ試していませんが、もし、複数ユーザで環境を共有できれば、お手軽CI環境になりそうですね。ビルドに成功したらデプロイまで自動で行われるので、その上で統合テストまで実施できるのかなと。。。