How to Automate z/OS Data Set Allocation Using Zowe & JSON
Last time I described migrating a “Hello World” assembler project based purely in z/OS data sets to Git and GitHub using VS Code and Zowe CLI.
I ended with a statement “Team members just need to clone the project… and they’re setup to contribute”. This was a tad misleading; lots of manual intervention is still needed for a new team member.
The Problem
The problem is that the project requires each team member to have several data sets to build and run the project from. For example, see this snippet of JCL:
Each team member can go create data sets, but creating data sets on z/OS is nothing like creating files and folders on your PC. It sometimes involves googling “how many cylinders do I need” (while ignoring results about car engines 😄).
We could also adjust the JCL and/or use temporary data sets to accomplish something similar, but I’d like to keep artifacts around a bit longer (for debugging, re-linking, or re-executing).
Tools Recap
Before actually fixing the problem, here are some of the tools I’ll be covering and what they’re used for:
- npm → task runner
- Zowe CLI → mainframe interaction
- Node-conifg → configuration
- Typescript → script language
- mustache → templating
Templating
I’ll further mustache my JCL for team members’ high-level qualifiers(HLQ), assembler options, and macro libraries:
The new template values are added to my default.json (and optionally overridden via local.json):
"settings": {
"hlq": "PUBLIC.TEMPLATE"
},
"assemble": {
"options": [
"ADATA",
"RENT",
"MACHINE(ZSERIES-5)",
"LIST(133)"
],
"maclib": [
"SYS1.MACLIB",
"SYS1.MODGEN",
"ASMA.SASMMAC2",
"CBC.SCCNSAM",
"TCPIP.AEXAMAC1"
],
},
...
From here, team members set their own HLQ under settings.hlq
(in their local.json so it’s not shared). Then they run $ npm run genjcl
to create JCL customized with their HLQ:
Allocation
The build JCL is now more generic than before in that it’s fully customized per user. However, the backing data sets do not actually exist yet, and so we have to create them. Otherwise, this JCL fails quickly:
IEFA107I KELDA16$ ASSEMBLE SYSADATA - DATA SET BEST.HLQ.EVER.ADATA NOT FOUND
IEF272I KELDA16$ ASSEMBLE - STEP WAS NOT EXECUTED.
Since I use Zowe CLI for most of the mainframe interaction (behind the scenes within scripts), I check to see what the CLI needs in order to create a PDS:
$ zowe files create --help
Shows:
The output displays some convenience commands to create data sets without specifying all DCB info. But I’m a true mainframer and want complete, explicit control 😉. I’ll use the zowe create pds
command and supply my own DCB info.
That means, I transform this:
To this (while adjusting some attributes):
"dataSets": {
"ASMPGM": {
"blockSize": 3120,
"directoryBlocks": 20,
"recordFormat": "FB",
"recordLength": 80,
"dataSetType": "LIBRARY",
"size": "10CYL"
},
...
I create JSON config objects like this for every data set needed by the project (they’re not all shown here).
Moar Scripts
We’ll need a few more scripts to wrap up. Most importantly: a script to allocate data sets for a given HLQ using the appropriate DCB attributes in the JSON config.
First, I’ll add one TypeScript interface to map the JSON object (for type-checking and IntelliSense in VS Code):
Then, I create the allocate
script that loops through config objects and allocates all necessary data sets using Zowe CLI:
The invocation of this script is encapsulated in package.json:
"scripts": {
"allocate: "node ./scripts/lib/allocate",
...
I’ll also create a similar script to deallocate/delete data sets related to the project (although it’s a little risky to loop and delete z/OS assets 😅). The details for this script can be seen within the repo which is linked to below.
Final Adjustments
The folder structure of the project was based on the data sets from which the project originated, something like /kelda16/work/asmpgm/template.asm
. Since the data sets are now specific to a user's settings.hlq
, we’ll make the folder structure generic, e.g. /zossrc/asmpgm/template.asm
.
Documentation is never fun for a developer, but a simple write-up of the full set of scripts in README.md isn’t too painful:
End Result
A new team member would clone the project, install dependencies, and add their config (2 setup steps in total):
Setup
$ git clone https://github.comd/dkelosky/assembler-template && cd assembler-template && git checkout v2 && npm install
- Create a local.json for their HLQ, jobname, and job account number
{
settings: {
hlq: "<HLQ_HERE>"
},
job: {
name: "<JOBNAME_HERE>",
account: "<JOB_ACCOUNT_NUMBER_HERE>"
}
}
Allocate
Next, they allocate their data sets $ npm run allocate
:
Repeat as Necessary
With data sets allocated, contributors can upload source and build$ npm run genjcl && npm run upload && npm run build
. That’s it!
Alternatively, you can click buttons in VS Code if you dislike issuing commands:
Summary
Now (and for real this time), a team member can clone the project, configure, and they’re setup to contribute, making use of some simple automation to generate JCL, allocate data sets, upload source, build, and download their output.
The updated project can be found here: https://github.com/dkelosky/assembler-template/tree/v2