Jenkins - z/OS連携: (1) 概要

# はじめに
COBOLやPL/Iなどで記述されたメインフレーム・アプリケーションの開発環境としては、いまだにPCOMなどの3270端末エミュレーターが使われているケースも多いようです。昨今では管理系のツールも含めてUIとしてEclipseやVSCode、ブラウザーベースなど新しい技術がどんどん提供されてきています。DevOpsやCI/CDという文脈で使われるOSSベースの各種ツールについても、z/OS上のアプリケーションの開発/運用に使えるようカスタマイズがされていたり関連ツールが提供されていたりします。
ここでは、Jenkinsに着目してメインフレーム・アプリケーションの管理がどのように行えるかを見ていきたいと思います。

## 関連記事
[Jenkins - z/OS連携: (1) 概要](https://qiita.com/tomotagwork/items/d2c90c1f29e07d3b7c19)
[Jenkins - z/OS連携: (2) Pipelineの利用](https://qiita.com/tomotagwork/items/6d0481d58cdd10e44def)
[Jenkins - z/OS連携: (3) Pipeline+Gitの利用](https://qiita.com/tomotagwork/items/16b38599be3f8a134580)
[Jenkins - z/OS連携: (4) Pipeline+Git+Webhookの利用](https://qiita.com/tomotagwork/items/25eb40e56f1a5125e4fc)
[Jenkins - z/OS連携: (5) Pipeline+Git+DBBの利用](https://qiita.com/tomotagwork/items/0b25bbb9a72e37f4d98c)
[Jenkins - z/OS連携: (6) Jenkins Pipeline利用シナリオ](https://qiita.com/tomotagwork/items/9d2b3f697f31f23fd682)

# 全体像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/d4c2412e-f94c-f318-c0a2-2ad8efee178f.png)

※図中の矢印はTCP/IPのコネクションを張りに行く方向を示しています。

アプリケーションはGitのリポジトリで管理している想定です。開発者がコードの修正や追加を行ってプル・リクエストをし、レビュー担当者がメインのブランチにマージしたとして、その後の処理をJenkinsのPipelineで自動化してみましょう、というイメージです。
今回の話の手前の部分の個別の修正については、以下の記事参照のこと。
参考: [VSCodeを使用したメインフレーム・アプリケーション開発 - (4)ソース管理ツール/ビルドツール連携](https://qiita.com/tomotagwork/items/4bdd0b5a7284b5102d10)

- **Jenkins Server**: アプリケーションのビルドやその後の処理のフローをPipelineとして管理します。z/OSのテスト環境をJenkinsの管理対象のノードの1つとして扱います。
- **テスト環境(z/OS)**: テスト環境として利用するz/OSの1区画です。アプリケーションのビルド(コンパイル/リンク)やテストなどが行われる環境のイメージです。オンプレ上の実際のIBM Zの場合もあると思いますし、ZD&TやWaziなどのエミュレーターを利用することも考えられます。
- **Git Server**: ソース/バージョン管理を行うサーバーです。
- **DBB(Dependency Based Build)**: z/OSアプリケーションのビルドを支援するための有償ツールです。Groovyでビルド用のスクリプトが書けるライブラリなどを提供しているため、Jenkinsなど外部からビルドを管理するツールと連携する際に有用です。
- **アプリ開発用UI**: VSCodeやEclipseベースのツールを使用するとGit連携機能も提供されているため有用です。(当シリーズ記事ではここはあまりフォーカスしません。)

Jenkinsで自動化を図る場合、アプリケーションの変更をトリガーにして、ビルド、テスト、デプロイ、という流れをPipelineで実装する、ということになると思います。環境もテスト環境とステージング、本番環境など複数関わってくる可能性があります。しかし、いきなり範囲を広げすぎると大変なので、まず今回は"ビルド"の部分に着目してDBBのみを利用する構成を考えていきます。
一通り基本的な流れが確認できれば、あとはそれを拡張する形で、後続のテストやデプロイの自動化につなげていけばよいということになります。
(テストの自動化については、例えばIDz(IBM Developer for zSystem)のzUnit、Virtual Test Platforms、Galasaといったツール、また、デプロイについては、UrbanCode DeployやJFrog Artifactoryといったツールとの連携が考えられます。)

IBM Z におけるDevOpsの全体像は以下の資料が参考になります。
参考: [Automated Testing as a Part of a Pipeline(DevOps World 2020)](https://downloads.ctfassets.net/vtn4rfaw6n2j/3VGBiqzgvA7bHHqwtzVUOq/b6e9e71d8a89649967ed7f27dc6a6f57/TF72ED_-_Rosalind_Radcliffe_-_Automated_Testing_as_a_Part_of_Pipelines.pdf)

# 環境準備

## z/OS(テスト環境)
ここでは詳細な構成手順などには触れませんが、以下の環境を整えておく必要があります。

### コンパイル環境
この環境でアプリケーションのビルド(コンパイル/リンク)を実施する想定なので、当然のことながらLEやコンパイラ、使用するミドルウェア等の設定がされている必要があります。

### SSH
Jenkinsからz/OSを管理する際にSSH経由で接続されることになるため、SSHサーバーを稼働させておく必要があります。

### DBB toolkit

参考:
[IBM Dependency Based Build](https://www.ibm.com/docs/en/dbb/1.1.0)
[GitHub - DBB sample](https://github.com/IBM/dbb)

DBBが提供する機能の一部です。基本的にはz/OS上にインストールして使用するもので、Groovyでビルド用のスクリプトを記述することができます。
DBB Toolkitが提供するのは基本的にAPIやGroovy関連のライブラリなので、必ずしもz/OS側で何らかのサーバー機能を常駐させておく必要はありません。ただ、これらはJVM上で動くことになりJVMの起動には一般的に大きなコストがかかります。このJVM起動に関するパフォーマンスを改善させるために、DBB Daemonを常駐させておいてビルド指示の度にJVM起動が走ることを回避する、といった使い方をすることもできます。その場合はDBB Daemonの構成をしてDaemonを起動させておく必要があります。
参考: [Improving performance with ZD&T or Java startup by using DBB daemon](https://www.ibm.com/docs/en/dbb/1.1.0?topic=improving-performance-by-using-dbb-daemon)

### zAppBuild
参考: [GitHub - dbb-zappbuild](https://github.com/IBM/dbb-zappbuild)

DBBという製品は、VSCodeやEclipseなどオープン系の開発ツールと連携しやすいように、Groovyでビルドのスクリプトを書ける仕組みを提供してくれています。ただ、それはつまり、これまでJCLで書いていたコンパイル/リンクなどの一連の操作を別のスクリプトで書かないといけないということになります。一からそのようなスクリプトを作るのは大変なので、zAppBuildという汎用的に使えるビルドのスクリプトやプロパティーファイルの雛形を提供してくれています。これはGitHubで公開されておりダウンロードして自由に利用可能です( Apache-2.0 License)。
これは、z/OSのUSS上に展開して利用します。

### Rocket Git
参考: [Git for z/OS](https://www.rocketsoftware.com/platforms/ibm-z/git-for-zos)

Rocket社が提供しているz/OS版のGitクライアントです。無償でダウンロードして利用可能です。USS上からgitコマンドが発行できます。

### Jenkins Agent
これはJenkinsの構成としてz/OSを管理対象のノードとして構成すると自動的に設定されるので、明示的に構成する必要はありません。JenkinsからSSH経由でAgentが実行されるので、Jenkins用のユーザー、Work用のUSS上のファイルシステムなどは用意しておく必要があります。

## Jenkins Server
メインとなる自動化の処理フローを管理するためのサーバーです。一般的な構成でJenkins Serverを立てればよいです。git, git client, ssh slaves あたりのpluginが入っていればよいでしょう。

## Git Server
ソース管理を行うためにリモートのリポジトリーを提供するGit Serverを用意します(GitHub、GitLab、Bitbucketなど)。z/OS、Jenkins ServerがGitクライアントになることを想定しているので、そこからアクセスできる必要があります。Proxyを立ててProxy経由でアクセスすることも可能です。

## DBB Server
参考: [Installing and configuring the DBB server](https://www.ibm.com/docs/en/dbb/1.1.0?topic=dbb-installing-configuring-server)

DBBが提供する機能の1つです。ビルドを行う際、変更が入ったソースに関連するモジュールを再ビルドする必要がありますが、前回のビルドからの差分や依存関係を判断するためのメタデータを管理します。実体はLinux上にLiberty+Derby(or Db2)で構成されます。こちらもz/OSからアクセスできるようにしておく必要があります。

# Jenkins Pipeline補足
参考: [Jenkins User Handbook - Pipeline](https://www.jenkins.io/doc/book/pipeline/)

以降の記事ではJenkins Pipelineを中心に試していく予定のため、Pipelineについて少し補足しておきます。
Pipelineは自動化したい一連の処理を専用の言語(Groovyベース)で記述するものです。
Pipeline記述の作法としてはDeclarative Pipeline、Scripted Pipelinの2種類があるようです。比較的Declarativeの方が新しいようで、その名前の通り宣言的な記述なので見た目にシンプルに記述ができるようです。Dclarativeの記述の仕方でも、scriptというstepを使うことでScriptedの記述を含めることも可能です。
基本的に、Pipeline{...}ではじまるものはDeclarative, node{...}ではじまるものはScriptedと判断できそうです。当記事ではなるべくDeclarativeを使用します。

Pipeline全体のSyntaxは以下から確認できます。
参考: [Pipeline Syntax](https://www.jenkins.io/doc/book/pipeline/syntax/)
inputによるユーザーの判断の挿入やwhenによる条件分岐などの制御が行えます。

Pipelineの記述では対象の管理ノードに対して処理の指示を送るための様々な機能がプラグインとして用意されています。
参考: [Pipeline Steps Reference](https://www.jenkins.io/doc/pipeline/steps/)
例えば、[Pipeline: Basic Steps](https://www.jenkins.io/doc/pipeline/steps/workflow-basic-steps/)としてecho(メッセージ出力)、writeFile(ファイルへの書き出し)といった機能が用意されています。また、[Pipeline: Nodes and Processes](https://www.jenkins.io/doc/pipeline/steps/workflow-durable-task-step/)としてsh(シェルスクリプト実行)などの機能が提供されます。

基本的にはshにより実行されるシェル・スクリプトがPipelineに記述する処理の中ではキーになってくると思います。管理対象がz/OSの場合、shで記述される処理はUSS上で実行されることになるためUSS上のシェル・スクリプトからビルドなどの管理ができることが重要です。DBBはまさにシェル・スクリプトからビルド操作を行いやすい仕組みを提供してくれているので、Jenkinsとの相性がよいということが言えます。

# おわりに
とりあえずこれからやろうとしていることの全体像と必要な環境を見てきました。次回から、具体的な例を挙げてStep by Stepで動かしていきたいと思います。