0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Jenkins - z/OS連携: (2) Pipelineの利用

Last updated at Posted at 2021-04-21

はじめに

Jenkinsを活用してメインフレーム・アプリケーションの管理をどのように行えるのかを探っていく連載記事です。
今回は、ごくシンプルなPipelineを作成してシェル・コマンドをz/OSに対して実行するところまでやってみます。

関連記事

Jenkins - z/OS連携: (1) 概要
Jenkins - z/OS連携: (2) Pipelineの利用
Jenkins - z/OS連携: (3) Pipeline+Gitの利用
Jenkins - z/OS連携: (4) Pipeline+Git+Webhookの利用
Jenkins - z/OS連携: (5) Pipeline+Git+DBBの利用
Jenkins - z/OS連携: (6) Jenkins Pipeline利用シナリオ

環境情報

今回、検証に利用する環境は、IBM Wazi Developer for Red Hat CodeReady WorkspacesというOpenShift上に構成されるz/OS開発環境を利用します。この製品はSandboxと呼ばれるz/OSエミュレーターを中心に各種開発ツールがバンドルされており、DBBなども含まれます。
このWaziのSandbox(z/OSエミュレーター)は、最初からDBBやGitなどが構成された状態のz/OSイメージが提供されているので、今回はそれをそのまま使います。

z/OS(Sandbox)

z/OS V2.4

Jenkins Server

Waziの手順に従い、Sandboxと同OpenShift上にJenkins Serverを構成
参考: Configuring a Jenkins server in OpenShift

Jenkins V2.235.5
Git plugin V4.2.2
Git client plugin V3.4.2
SSH Build Agents plugin V1.31.5
SSH Credentials plugin V1.18.1

シンプルなPipelineの実行

image.png

さて、まずはごくシンプルなPipelineを作ってそれをz/OSに対して流してみましょう。

Jenkins用ユーザー (z/OS)

Jenkinsからz/OSをSlaveとして管理する場合、SSH経由で制御することになるので、SSHで接続できるユーザーを用意しておきます。Jenkinsから実施される処理は基本的にこのユーザーで実行されることになります。

Jenkins:ノード構成

z/OSをJenkinsの管理対象のノードとして構成します。
ノードを構成すると対象ノードにSSH経由で接続してAgentの構成を行います。AgentはSSH経由でシェルからJavaとして実行されるので、シェルの環境変数やJVMオプションなどを指定します。

image.png

image.png

起動時の主要パラメータ補足:

パラメーター 補足
Javaのパス /usr/lpp/java/J8.0_64/bin/java
JVMオプション -Xquickstart -Dfile.encoding=UTF-8 -Xnoargsconversion
Prefix Start Agent Command export JAVA_HOME=/usr/lpp/java/J8.0_64 && export IBM_JAVA_ENABLE_ASCII_FILETAG=ON && env &&
Suffix Start Agent Command -text 先頭にブランク
ノード接続時のログ
[03/12/21 09:31:46] [SSH] The remote user's environment is:
@="sh"
ERRNO="0"
HOME="/u/JENKIN2"
IFS=" 	
"
LINENO="0"
LOGNAME="JENKIN2"
MAIL="/usr/mail/JENKIN2"
MAILCHECK="600"
OPTIND="1"
PATH="/bin"
PPID="50398323"
PS1="\$ "
PS2="> "
PS3="#? "
PS4="+ "
PWD="/u/JENKIN2"
RANDOM="24367"
SECONDS="0"
SHELL="/bin/sh"
SSH_CLIENT="172.26.1.1 50003 22"
SSH_CONNECTION="172.26.1.1 50003 172.26.1.2 22"
USER="JENKIN2"
[03/12/21 09:31:47] [SSH] Starting sftp client.
[03/12/21 09:31:48] [SSH] Copying latest remoting.jar...
Source agent hash is E5FEC468D6F172BF394E1F2571EA686C. Installed agent hash is E5FEC468D6F172BF394E1F2571EA686C
Verified agent jar. No update is necessary.
Expanded the channel window size to 4MB
[03/12/21 09:31:52] [SSH] Starting agent process: export JAVA_HOME=/usr/lpp/java/J8.0_64 && export IBM_JAVA_ENABLE_ASCII_FILETAG=ON && env &&cd "/u/JENKIN2/agent/wazi-test01" && /usr/lpp/java/J8.0_64/bin/java -Xquickstart -Dfile.encoding=UTF-8 -Xnoargsconversion -jar remoting.jar -workDir /u/JENKIN2/agent/wazi-test01 -jar-cache /u/JENKIN2/agent/wazi-test01/remoting/jarCache -text
MAIL=/usr/mail/JENKIN2
PATH=/bin
SSH_CLIENT=172.26.1.1 50003 22
SHELL=/bin/sh
IBM_JAVA_ENABLE_ASCII_FILETAG=ON
_=/bin/env
LOGNAME=JENKIN2
USER=JENKIN2
HOME=/u/JENKIN2
SSH_CONNECTION=172.26.1.1 50003 172.26.1.2 22
JAVA_HOME=/usr/lpp/java/J8.0_64
Running in text mode
Mar 12, 2021 9:32:47 AM org.jenkinsci.remoting.engine.WorkDirManager initializeWorkDir
INFO: Using /u/JENKIN2/agent/wazi-test01/remoting as a remoting work directory
Mar 12, 2021 9:32:49 AM org.jenkinsci.remoting.engine.WorkDirManager setupLogging
INFO: Both error and output logs will be printed to /u/JENKIN2/agent/wazi-test01/remoting
<===[JENKINS REMOTING CAPACITY]===><===[HUDSON TRANSMISSION BEGINS]===channel started
Remoting version: 4.3
This is a Unix agent
Mar 12, 2021 9:35:43 AM hudson.remoting.UserRequest perform
WARNING: LinkageError while performing UserRequest:jenkins.slaves.StandardOutputSwapper$ChannelSwapper@6884a3c3
java.lang.UnsatisfiedLinkError: Native library (com/sun/jna/z/os-s390x/libjnidispatch.so) not found in resource path ([])
	at com.sun.jna.Native.loadNativeDispatchLibraryFromClasspath(Native.java:1032)
	at com.sun.jna.Native.loadNativeDispatchLibrary(Native.java:988)
	at com.sun.jna.Native.<clinit>(Native.java:195)
	at hudson.util.jna.GNUCLibrary.<clinit>(GNUCLibrary.java:115)
	at jenkins.slaves.StandardOutputSwapper$ChannelSwapper.swap(StandardOutputSwapper.java:60)
	at jenkins.slaves.StandardOutputSwapper$ChannelSwapper.call(StandardOutputSwapper.java:45)
	at jenkins.slaves.StandardOutputSwapper$ChannelSwapper.call(StandardOutputSwapper.java:39)
	at hudson.remoting.UserRequest.perform(UserRequest.java:211)
	at hudson.remoting.UserRequest.perform(UserRequest.java:54)
	at hudson.remoting.Request$2.run(Request.java:369)
	at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:72)
	at java.util.concurrent.FutureTask.run(FutureTask.java:277)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1160)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.lang.Thread.run(Thread.java:820)

ERROR: Failed to monitor for Clock Difference
java.util.concurrent.TimeoutException
	at hudson.remoting.Request$1.get(Request.java:316)
	at hudson.remoting.Request$1.get(Request.java:240)
	at hudson.remoting.FutureAdapter.get(FutureAdapter.java:59)
	at hudson.node_monitors.AbstractAsyncNodeMonitorDescriptor.monitorDetailed(AbstractAsyncNodeMonitorDescriptor.java:114)
	at hudson.node_monitors.AbstractAsyncNodeMonitorDescriptor.monitor(AbstractAsyncNodeMonitorDescriptor.java:78)
	at hudson.node_monitors.AbstractNodeMonitorDescriptor$Record.run(AbstractNodeMonitorDescriptor.java:306)
ERROR: Failed to monitor for Architecture
java.util.concurrent.TimeoutException
	at hudson.remoting.Request$1.get(Request.java:316)
	at hudson.remoting.Request$1.get(Request.java:240)
	at hudson.remoting.FutureAdapter.get(FutureAdapter.java:59)
	at hudson.node_monitors.AbstractAsyncNodeMonitorDescriptor.monitorDetailed(AbstractAsyncNodeMonitorDescriptor.java:114)
	at hudson.node_monitors.AbstractAsyncNodeMonitorDescriptor.monitor(AbstractAsyncNodeMonitorDescriptor.java:78)
	at hudson.node_monitors.AbstractNodeMonitorDescriptor$Record.run(AbstractNodeMonitorDescriptor.java:306)
ERROR: Failed to monitor for Free Disk Space
java.util.concurrent.TimeoutException
	at hudson.remoting.Request$1.get(Request.java:316)
	at hudson.remoting.Request$1.get(Request.java:240)
	at hudson.remoting.FutureAdapter.get(FutureAdapter.java:59)
	at hudson.node_monitors.AbstractAsyncNodeMonitorDescriptor.monitorDetailed(AbstractAsyncNodeMonitorDescriptor.java:114)
	at hudson.node_monitors.AbstractAsyncNodeMonitorDescriptor.monitor(AbstractAsyncNodeMonitorDescriptor.java:78)
	at hudson.node_monitors.AbstractNodeMonitorDescriptor$Record.run(AbstractNodeMonitorDescriptor.java:306)
ERROR: Failed to monitor for Response Time
java.util.concurrent.TimeoutException
	at hudson.remoting.Request$1.get(Request.java:316)
	at hudson.remoting.Request$1.get(Request.java:240)
	at hudson.remoting.FutureAdapter.get(FutureAdapter.java:59)
	at hudson.node_monitors.AbstractAsyncNodeMonitorDescriptor.monitorDetailed(AbstractAsyncNodeMonitorDescriptor.java:114)
	at hudson.node_monitors.ResponseTimeMonitor$1.monitor(ResponseTimeMonitor.java:57)
	at hudson.node_monitors.AbstractNodeMonitorDescriptor$Record.run(AbstractNodeMonitorDescriptor.java:306)
ERROR: Failed to monitor for Free Temp Space
java.util.concurrent.TimeoutException
	at hudson.remoting.Request$1.get(Request.java:316)
	at hudson.remoting.Request$1.get(Request.java:240)
	at hudson.remoting.FutureAdapter.get(FutureAdapter.java:59)
	at hudson.node_monitors.AbstractAsyncNodeMonitorDescriptor.monitorDetailed(AbstractAsyncNodeMonitorDescriptor.java:114)
	at hudson.node_monitors.AbstractAsyncNodeMonitorDescriptor.monitor(AbstractAsyncNodeMonitorDescriptor.java:78)
	at hudson.node_monitors.AbstractNodeMonitorDescriptor$Record.run(AbstractNodeMonitorDescriptor.java:306)
ERROR: Failed to monitor for Free Swap Space
java.util.concurrent.TimeoutException
	at hudson.remoting.Request$1.get(Request.java:316)
	at hudson.remoting.Request$1.get(Request.java:240)
	at hudson.remoting.FutureAdapter.get(FutureAdapter.java:59)
	at hudson.node_monitors.AbstractAsyncNodeMonitorDescriptor.monitorDetailed(AbstractAsyncNodeMonitorDescriptor.java:114)
	at hudson.node_monitors.AbstractAsyncNodeMonitorDescriptor.monitor(AbstractAsyncNodeMonitorDescriptor.java:78)
	at hudson.node_monitors.AbstractNodeMonitorDescriptor$Record.run(AbstractNodeMonitorDescriptor.java:306)
Agent successfully connected and online
The Agent is connected, disconnect it before to try to connect it again.

Pipelineの作成

新規ジョブ作成を選択します。
名前を指定して、"パイプライン"を選択します。
image.png

image.png

Pipeline Scriptとして以下を記載します。

pipeline_script
pipeline {
   agent {label 'wazi-test01'}

   stages {
      stage('Hello') {
         steps {
            echo 'Hello World'
         }
      }
      stage('Hello2'){
         steps {
             sh """
               echo 'Hello World2'
               hostname
               pwd
             """
         }
      }
      stage('Hello3'){
         steps {
            sh """
               echo 'Hello World3'
               ls -la
            """
         }
      }
   }
}

先頭のagent {label 'wazi-test01'}で、実行するノードのラベルを指定しています。
処理内容としては、3つのステージを定義し、それぞれ単純なシェル・コマンドを実行しているだけです。

Pipeline実行

Pipelineを開いて左側のメニューからビルド実行を選択
image.png

ログを確認

パイプライン実行時のログ
Started by user IAM#xxxxx
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on wazi-test01 in /u/JENKIN2/agent/wazi-test01/workspace/Tag_pipeline_hello
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Hello)
[Pipeline] echo
Hello World
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Hello2)
[Pipeline] sh
+ echo Hello World2 
Hello World2
+ hostname 
S0W1.DAL-EBIS.IHOST.COM
+ pwd 
/u/JENKIN2/agent/wazi-test01/workspace/Tag_pipeline_hello
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Hello3)
[Pipeline] sh
+ echo Hello World3 
Hello World3
+ ls -la 
total 16
drwxr-xr-x   2 JENKIN2  SYS1           0 Mar 12 09:53 .
drwxr-xr-x   4 JENKIN2  SYS1        8192 Mar 12 09:53 ..
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

z/OSのUSS上で指定したシェルのコマンドが実行されたのが確認できました!

ちなみに、Piplineで実行するシェル・コマンドにsleepを入れてz/OS側のファイル構造を覗いてみると、こんな感じで実行されていました。

TAGUCHI:/u/JENKIN2/agent/wazi-test01/workspace: >ls -laR

.:
total 48
drwxr-xr-x   4 JENKIN2  SYS1        8192 Mar 12 18:53 .
drwx------   5 JENKIN2  SYS1        8192 Mar 12 18:53 ..
drwxr-xr-x   2 JENKIN2  SYS1           0 Mar 12 18:53 Tag_pipeline_hello
drwxr-xr-x   3 JENKIN2  SYS1        8192 Mar 13 10:46 Tag_pipeline_hello@tmp

./Tag_pipeline_hello:
total 16
drwxr-xr-x   2 JENKIN2  SYS1           0 Mar 12 18:53 .
drwxr-xr-x   4 JENKIN2  SYS1        8192 Mar 12 18:53 ..

./Tag_pipeline_hello@tmp:
total 48
drwxr-xr-x   3 JENKIN2  SYS1        8192 Mar 13 10:46 .
drwxr-xr-x   4 JENKIN2  SYS1        8192 Mar 12 18:53 ..
drwxr-xr-x   2 JENKIN2  SYS1        8192 Mar 13 10:46 durable-f42e8941

./Tag_pipeline_hello@tmp/durable-f42e8941:
total 66
drwxr-xr-x   2 JENKIN2  SYS1        8192 Mar 13 10:46 .
drwxr-xr-x   3 JENKIN2  SYS1        8192 Mar 13 10:46 ..
-rw-r--r--   1 JENKIN2  SYS1         135 Mar 13 10:46 jenkins-log.txt
-rw-r--r--   1 JENKIN2  SYS1           2 Mar 13 10:46 jenkins-result.txt
-rw-r--r--   1 JENKIN2  SYS1          92 Mar 13 10:46 script.sh
TAGUCHI:/u/JENKIN2/agent/wazi-test01/workspace: >cat *tmp/d*/script.sh

               echo 'Hello World3'
               sleep 20
               ls -la

workspace以下にtempのディレクトリが作成されて、pipelineのstepで指定されたシェル・コマンドがscript.shというファイルとして作成されていました。
Pipeline実行後はこれらのファイルは削除されています。

まとめ

今回の試した内容は以下のイメージです。
image.png

シンプルな例なので非常に分かりやすいですね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?