Continuous Integration using Jenkins and More…

I recently attended an online meeting with the MAGIC user group which showed how to install and set up Jenkins on the IBM i for Continuous Integration purposes. The installation and configuration all seemed very easy when explained by Wim Jongman of Remain Software and his explanation of how to set things up seemed to make it very easy. However something that Wim kept saying really resonated with me, he kept calling it a job scheduler on steriods! So I thought I would explore not only how I can implement Jenkins on the IBM i but also how to use it as a possible advanced job scheduler.

Another chink in the plan was how to do this based using our current development environment and platforms. We use Linux very heavily for a lot of our development processes even where IBM i is involved, this is because a lot of the interfaces we develop are based on PHP with NGINX as the web server of choice. We do not use PHP or NGNIX on IBM i (although the recent Power 9 systems may make that a more inviting option if the system has been tuned to run the scripting languages a lot better??) at this time so we wanted to ensure we could have a single implementation of Jenkins and farm out the work across other platforms where appropriate. Compiling ILE code on IBM i is one of those things we need to farm out while our Linux development projects (node.js, C etc) can be farmed out to other Linux servers or run on the ‘Master’ Jenkins server

Jenkins has the ability to farm out the jobs across the network using slave nodes. I was unsure how the slave node was implemented so we set about building the Jenkins environment so that we could test it. First we created a new VM that would run Jenkins, this was a Debian instance running under ProxMox.

First prerequisite for Jenkins is Java, there are a number of issues with Java these days because of the new licensing requirements placed by Oracle. We simply wanted the jdkopen-8-jdk which is installed using following command

apt install default-jre 

Check java installed before moving onto the next part.

Installing Jenkins can be carried out by either installing the .war file or by setting up the Debian apt sources list to allow automatic install and update. We decided to setup apt so it could automatically install by using the following commands after changing to root (su command). First we need to add the key for the Jenkins repository so it can be added to the authorized downloads.

wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | apt-key add

Now we can update the sources and install Jenkins

apt-get update
apt-get install jenkins

One installed you may need to change the default http port (8080) and restart. The instructions to set the password and enable Jenkins are all well documented so we will not go through them again here. Jenkins does not come with SSH installed by default so you will need to go through and install the SSH plugin before SSH connections can be made.

Once you have set up the ‘Master’ Jenkins server we need to add our IBM i as a slave to the Master, but before we do that we need to ensure the IBM i has all of the required software and add a directory which will be used by the Jenkins server. As the IBM i will be contacted via SSH we need the SSHD server to be running, if you do not have SSHD installed there are a couple of ways to install it (Openssl or 5733-SC1 options) so you need to decide which is best for you. Next we will need to create the directory, I just used ‘/usr/local/jenkins’ but you can use any directory which suits such as ‘/home/’MYUSERNAME’/jenkins’ where MYUSERNAME is the user name you use on the IBM i.

Java is required on the IBM i to allow the request to be processed so ensure it has been set up correctly. Also if you are going to run compiles as we are you will need the relevant compilers installed.

Now that the IBM is set up and the SSHD server is running we can configure a slave definition within the Jenkins Master. We do not need to install Jenkins on the IBM i for this to work. To configure the slave we will go to the Jenkins Main Menu => Manage Jenkins => Manage Nodes => New Node.

Give the Node a new Name, we used the system name but you can give it any name you wish. This will be a Permanent Agent then click OK.

Add a description that suits and set the remote directory to the one you created on the IBM i (in our case it was /usr/local/jenkins). One IMPORTANT piece of information is the label, this not only shows in the job information but allows us to push jobs to the remote location based on that label. In our case we simply entered ‘ibmi’, if we had more than one slave we could use something like ibmi-a, ibmi-b etc.

The host information needs to be added to allow the remote host to be contacted, the information you put here depends on your network configuration.

Add the credential information you want to use, we simply used a userid and password but if you have key management you can use your key information for the connection. Its very simply to add the userid and password and as this is on a closed network we did not worry about how secure it is. We also set it as non verifying verification strategy to make things easy, if you need security to be a lot tighter than we do read up on the various security measures and secure accordingly. We did not change anything else so press enter and the node will be generated. As part of the setup it will connect to the remote IBM i to collect information and store the remoting software, if you see any errors you need to figure out what is wrong and fix it. Once it successfully completes you are ready to add your first job.

We are going to add a compile of a module to the job list that will go out and compile the module on the IBM i. From the main menu select add a new item (by default you should see it already displayed but if not select from the options on the main menu). Type in a description (Test Compile in our instance) and select Freestyle Project, click OK.

Give it a simple description, select the restrict where it can be run option before typing in the label expression ibmi. Then go all the way to the bottom to Build and select the Execute shell option. In here you will type in the command to execute ( we are compiling a simple C module genuuid_c so our command is ‘system -kn “CRTCMOD MODULE(CHLIB/GENUUID_C) SRCFILE(CHLIB/QCSRC)”‘, you can enter any IBM i system command you want). Press enter and the entry will be added.

The build will now show up in the main dashboard, as we have not scheduled a run we can click the build now option and the job should be sent to the remote IBM i and run, if all goes well it will compile the object and return a positive response. One thing we did notice is the information returned in the log from the compiler is in EBCDIC so we need to figure out if that can be overcome?

That’s all there is to setting up the Jenkins Server on a Linux system and allowing it to run commands on the remote IBM i where Jenkins is not installed. Next we are going to work out how to implement some kind of job scheduler using Jenkins from the Linux System to the IBM i (and other computing nodes), this will eventually lead to a possible network level scheduler that will run over different computing nodes?

Chris…