Installing Node.js on the Mainframe (both Linux and z/OS) to run Zowe CLI

Petr Plavjaník
Feb 10 · 7 min read

We have seen how to run Java on Linux on System z in a previous story:

What about other popular platforms like Node.js?

Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine.

Here I will show how to get Node.js installed on Linux on System z and to z/OS as well. We will install Zowe CLI a powerful command-line interface that lets application developers interact with the mainframe in a familiar format and we will create a simple web server application using Express.

Node.js is used by many enterprises to develop web applications and REST API services. Node.js on z/OS can take advantage of the co-location of your data and existing applications on IBM Z to significantly increase throughput and reduce response time.

Node.js logo

Node.js on Linux on z

We are using a LinuxONE instance from IBM LinuxONE Community Cloud.

Node.js is not installed on RHEL 7.6 by default:

[linux1@plape ~]$ node
-bash: node: command not found

The latest LTS version is 12 and you can find it on https://nodejs.org/en/:

Latest LTS version of Node.js

To download version for s390x architecture, you need to click on https://nodejs.org/en/download/ and choose :

Node.js works on many platforms

Login to your Linux on System z system and download the package with Node.js:

curl -OL https://nodejs.org/dist/v12.15.0/node-v12.15.0-linux-s390x.tar.xz

Unpack the archive to any directory you want to install Node, for example/opt/nodejs :

VERSION=v12.15.0
DISTRO=linux-s390x
sudo mkdir -p /opt/nodejs
sudo tar -xJvf node-$VERSION-$DISTRO.tar.xz -C /opt/nodejs

Open the profile fike using vi ~/.profile and add this at the end:

# Node.js
VERSION=v12.15.0
DISTRO=linux-s390x
export PATH=/opt/nodejs/node-$VERSION-$DISTRO/bin:$PATH

Refresh profile:

. ~/.profile

Test the installation using:

 node -v; npm version; npx -vv12.15.0
{
npm: '6.13.4',
ares: '1.15.0',
brotli: '1.0.7',
cldr: '35.1',
http_parser: '2.9.3',
icu: '64.2',
llhttp: '2.0.4',
modules: '72',
napi: '5',
nghttp2: '1.40.0',
node: '12.15.0',
openssl: '1.1.1d',
tz: '2019c',
unicode: '12.1',
uv: '1.33.1',
v8: '7.7.299.13-node.16',
zlib: '1.2.11'
}
6.13.4

There is no other choice than this build of Node.js for s390x architecture. But I still wanted to see LinuxONE is much better for Node.js than my Mac. In the case of Java, it was a remarkable difference. The tests that I have when I wrote https://medium.com/@plape/getting-java-and-jenkins-working-on-linux-on-mainframe-d2a8736f2469 were 7 times faster on LinuxONE.

For Node.js, I have used:

npx benchmark-octane

It was less than 10 % faster than my Mac and some of the tests have failed because the mainframe is a big-endian system and the test did not expect that.

Zowe CLI

Zowe CLI is a command-line interface that lets application developers interact with the mainframe in a familiar format. Zowe CLI helps to increase overall productivity, reduce the learning curve for developing mainframe applications, and exploit the ease-of-use of off-platform tools. Zowe CLI lets application developers use common tools such as shell commands, bash scripts, and build tools for mainframe development. It provides a set of utilities and services for application developers that want to become efficient in supporting and building z/OS applications quickly.

Linux on System z is an ideal platform for running such tools. The Linux on System z is a real Linux system with ASCII encoding. It is better than z/OS UNIX system services that do not feel like Linux at all.

Let’s install it. The Node.js was installed globally as root, so we have to be root when installing Zowe CLI:

sudo suVERSION=v12.15.0
DISTRO=linux-s390x
export PATH=/opt/nodejs/node-$VERSION-$DISTRO/bin:$PATH
npm install -g --ignore-scripts @zowe/cli
exit

In the end, you should see a message like:

+ @zowe/cli@6.7.2

You can type zowe to see the command groups the Zowe CLI provides:

Welcome screen of Zowe CLI

The first step is to connect to your mainframe with z/OSMF. This is an example, you will need to provide correct information about your mainframe system, z/OSMF, and user credentials:

zowe profiles create zosmf-profile mf --host mf.acme.net --port 443 --user USERID --pass "PASSWORD" --reject-unauthorized true

Then you can issue commands the interact with the z/OS system:

$ zowe files list data-set "USERID.ASM"
USERID.ASM.LOADLIB
USERID.ASM.SOURCE

For more details about Zowe CLI and information on how to obtain access to z/OSMF and what you can do with Zowe, see:

Node on z/OS

In an older story, we have learned how to install Node.js 6 on z/OS and build native extensions.

Version 6 is quite an ancient version, let’s see if there are a newer Node.js for z/OS.

The home page of Node.js on z/OS is: https://developer.ibm.com/mainframe/products/ibm-sdk-for-node-js-z-os/

Home page of IBM SDK for Node.js — z/OS

If you have mainframe press if not you can stop reading this story but you can click on and get access to z/OS for a few days.

We assume that you have access to the z/OS system.

Hit button again and after login with your IBM ID or creating a new one, you will see a list:

Node.js version 12.13 IS available for z/OS in PAX format

There is v12.13 at the end. IBM has made great progress since the last year when it was two LTS releases behind. Today it is only two minor versions!

Create zFS Filesystem for Node.js

It is recommended to allocate a new zFS filesystem for Node.js. You can use the following job template and replace ${jobcard} and ${prefix} variables with your job card and the prefix for the data sets with the zFS file system.

JCL that creates a zFS filesystem on z/OS

You can download this JCL and then submit easily using Zowe CLI:

curl -O https://gist.githubusercontent.com/plavjanik/fbf4fbf4318a1b7a44ac0381a1a39717/raw/19cc8feabd757549e719bb6c1e49b1dc9f6d9986/create_zfs.jcl

Edit the file in your favorite text editor and replace the variables. More more details about the parameters, see DEFINE CLUSTER.

Then you can submit it and check its status:

$ zowe zos-jobs submit local-file create_zfs.jcljobid:   JOB41333
retcode: null
jobname: PLAPE03Z
status: ACTIVE
$ zowe zos-jobs view job-status-by-jobid JOB41333jobid: JOB41333
retcode: CC 0000
jobname: PLAPE03Z
status: OUTPUT

The 0000 return code means that the zFS is allocated and we need to login to z/OS using SSH or telnet and then issue following commands to mount the zFS filesystem:

export ZOWE_HOME=
mkdir ${ZOWE_HOME}
/usr/sbin/mount -f .ZFS ${ZOWE_HOME}
cd ${ZOWE_HOME}
mkdir downloads

We have a big filesystem so we can upload the Node.js package using the Zowe CLI:

zowe zos-files upload file-to-uss --binary ~/Downloads/ibm-node-v12.13.0-os390-s390x_11212019.pax.Z /z/masserv/node12/downloads/ibm-node-v12.13.0-os390-s390x_11212019.pax.Z

In the z/OS shell:

cd 
pax -rzf downloads/ibm-node-v12.13.0-os390-s390x_11212019.pax.Z -p p

Let’s create a file that sets the environment for Node.js. Type vi nodeenv.sh and insert these lines into it:

export _BPXK_AUTOCVT=ON
export _CEE_RUNOPTS="FILETAG(AUTOCVT,AUTOTAG) POSIX(ON)"
export PATH=/node-v12.13.0-os390-s390x/bin/:$PATH

After saving and leaving Vi (:wq), you activate the environment:

chmod a+x *.sh
. nodeenv.sh

Let’s test the installation:

$ node -v; npm version; npx -vv12.13.0
{
npm: '6.12.0',
ares: '1.15.0',
brotli: '1.0.7',
cldr: '35.1',
http_parser: '2.8.0',
icu: '64.2',
llhttp: '1.1.4',
modules: '72',
napi: '5',
nghttp2: '1.39.2',
node: '12.13.0',
openssl: '1.1.1d',
tz: '2019a',
unicode: '12.1',
uv: '1.32.0',
v8: '7.7.299.13-node.12',
zlib: '1.2.11'
}
6.12.0

You can find the Node.js for z/OS documentation at:

https://www.ibm.com/support/knowledgecenter/SSTRRS_12.0.0/com.ibm.nodejs.zos.v12.doc/welcome.html

Let’s install Zowe CLI:

npm install -g @zowe/cli

Zowe CLI works in the same way as on other platforms, you can follow the steps listed in the previous sections.

Simple HTTP Server

Let’s develop a simple service using the Express framework.

Login to z/OS UNIX session and initiate an empty project and install Express into it:

mkdir server
cd server
npm init -f
npm install express --save

We need to create a source code file in ASCII encoding:

touch index.js
chtag -t -c ISO8859-1 index.js
vi index.js

With the following content. You should change the port to an available one:

const express = require('express')
const app = express()
const port = 10055
app.get('/', (req, res) => res.send('Hello World!'))app.listen(port, () => console.log(`Example app listening on port ${port}!`))

We can start it and see if it was bound to the port:

$ node index.js
Example app listening on port 10055!

We can connect to it using an HTTP client (for example HTTPie):

http GET "http://mfhost.acme.net:10055/"HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 12
Content-Type: text/html; charset=utf-8
Date: Fri, 07 Feb 2020 22:06:45 GMT
ETag: W/"c-Lve95gjOVATpfV8EL5X4nxwjKHE"
X-Powered-By: Express
Hello World!

Summary

Node.js is easy to install on z/OS and Linux on System z. On both platforms, it is using ASCII so you do not need to fight with EBCDIC when you develop applications in Node.js.

In the next story, we will try to get Go working on the mainframe and see how it compares to Node.js.

Petr Plavjaník

Written by

Petr’s main areas of expertise are mainframes and automation, and using modern development tools and languages such as Java, Python, and Node.js on z/OS.

More From Medium

More from Petr Plavjaník

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade