Skip to content

Installing Jenkins

Ben Heasly edited this page Jan 23, 2017 · 27 revisions

One good use for MatlabJobSupport will be to run automated tests and validations on a remote Jenkins server. This page is about how to install Jenkins and integrate with GitHub and Matlab.

See Creating Jenkins Tests for more about setting up tests for specific projects.

Work in progress. Coming soon...

EC2 Instance

We need a server to run Jenkins. In order for Jenkins to run MatlabJobSupport jobs, the server also needs to have Matlab and Docker installed.

In the Brainard Lab AWS account, we have machine image all set up for this. It's the AMI called RTB Jobs 9.

For these instructions, I will refer to an instance that I just now set up and I hope to leave running. Here are its stats:

  • AMI RTB Jobs 9
  • instance type m4.large
  • IAM role ecsInstanceRole
  • 50GB "GP2" SSD root volume
  • Name = Jenkins
  • security sroups all-ssh and web
  • SSH key pair named render-toolbox
  • elastic IP address 50.112.42.141

I can SSH to this instance with:

ssh -i render-tooblox.pem ubuntu@50.112.42.141

Jenkins Setup

To set up Jenkins on this instance, I am following the Jenkins wiki. I used the sections "Installation" and "Using Linux iptables for port 80 -> 8080", just as written.

Installation

wget -q -O - https://pkg.jenkins.io/debian/jenkins-ci.org.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt-get update
sudo apt-get install jenkins

Using Linux iptables for port 80 -> 8080

#Requests from outside
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
#Requests from localhost
sudo iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080

Browser Test

Then I was able to access Jenkins at its elastic IP address. Here.

Initial Password

Jenkins starts with a special initial password. I was able to discover this from the SSH terminal using either of these commands:

# either
sudo cat /var/lib/jenkins/secrets/initialAdminPassword

# or
cat /var/log/jenkins/jenkins.log

Jenkins Startup

After entering the initial password, I followed the Jenkins startup wizard. I chose the default set of plugins and created an admin user with a strong password.

Docker Group

For MatlabJobSupport, we want Jenkins to be able to invoke Docker commands. So we need to put the jenkins user into the docker group. This requires a restart of Jenkins and Docker (but not the whole system).

sudo gpasswd -a jenkins docker
sudo service docker restart
sudo service jenkins restart

Jenkins Plugins

Finally, I installed some more Jenkins plugins that will come in handy.

  • choose Manage Jenkins -> Manage Plugins -> Available
  • check Embeddable Build Status Plugin
  • check TAP Plugin
  • check Role-based Authorization Strategy
  • choose Install without Restart

GitHub Integration

Now that Jenkins is set up, I am connecting it to GitHub. I'm taking advice from a blog called The Right Code, and the Jenkins GitHub plugin

Create SSH Key Pair for jenkins User

We need an SSH key pair for the jenkins user so that Jenkins can authenticate with GitHub.

sudo passwd jenkins
# enter a password
su jenkins
# enter that password
ssh-keygen -t rsa -b 4096 -C "render.toolbox@gmail.com"
# enter that password
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa
# enter that password
exit

Put the SSH public key on GitHub

Now that we have the key pair, we can register the public key with GitHub.

I am using our "render.toolbox" GitHub account. But there is nothing special about that account. The same should work with any account that has access to our GitHub organizations.

su jenkins
# enter that password
cat ~/.ssh/id_rsa.pub
# copy it
exit
# GitHub log in as render.toolbox@gmail.com
# paste in new ssh key

Now log in to GitHub as "render.toolbox@gmail.com"

  • choose Settings -> SSH and GPG Keys
  • choose New SSH key
  • Title "Jenkins"
  • paste in the key from above
  • choose Add SSH key

Create a GitHub Access Token for Jenkins

From GitHub, create a Person Access Token for Jenkins to use. This will allow Jenkins to get notified about GitHub commits and and to set build statuses that we can see at GitHub.

Log in to GitHub as "render.toolbox@gmail.com"

  • choose Settings -> Personal access tokens
  • choose Generate new token
  • Token description "Jenkins"
  • Select scopes:
    • repo
    • admin:org
    • admin:repo_hook
    • admin:org_hook
    • notifications
  • choose Generate token
  • copy the new token to the clipboard

Put Access Token into Jenkins

Now put the token generated above into Jenkins

  • choose Manage Jenkins -> Configure System -> GitHub -> Add GitHub Server
  • choose Credentials -> Add -> Jenkins
  • choose Kind -> Secret Text
  • Secret, paste in the token copied above
  • ID "GitHub"
  • choose Add
  • in Credentials drop-down, select "GitHub"
  • choose Test Connection
  • choose Save

Matlab Integration

We can get Matlab-based tests to work well with Jenkins. Mathworks has several blog posts on this topic:

From all this, I took away two things:

  1. Our Matlab test code needs to set the Matlab exit() status to be consistent with the test results:
  • all tests pass -> exit(0)
  • any test fails -> exit(-1), or any non-zero exit code
  1. We can get detailed test results by asking Matlab to write a file that follows the Test Anything Protocol, aka TAP

Setting the exit() Status

MatlabJobSupport includes a utility mjsRunJobAndExit(). This executes a Job, then exits Matlab with an appropriate exist status: 0, if the job finished normally, -1 if the job threw an exception.

Writing TAP Results

For an example of getting Matlab to write test results to a TAP file, see tbAssertTestsPass() from the ToolboxToolbox. Since ToolboxToolbox is included with MatlabJobSupport, this function will be available to all our test jobs.

tbAssertTestsPass() will work well with mjsRunJobAndExit(). If all tests pass, the assertion will succeed, the test job will finish normally, and Matlab will exit with status 0. If any test fails, the assertion will fail, the test job will throw an exception, and Matlab will exit with status -1.

See Creating Jenkins Tests for more about setting up tests using tbAssertTestsPass() and mjsRunJobAndExit().

Viewing TAP Results

Above, we installed the Jenkins TAP plugin installed. This will allow Jenkins to read the TAP test results produced by Matlab and display them nicely to us in the browser.

Status Badges

Jenkins can generate status "badges" that indicate the success or failure of tests. These are nice things to display on other web sites. For example, we can put them in our GitHub README files to show the build status on the repo home page.

Jenkins provides an image link for the status badge for each project. It's up to Jenkins to update the image with the current build status. Other sites just have show the image like any other.

We already installed the Embeddable Build Status Plugin, above.

Getting a Status Badge

To get the status badge image link for a project:

  • choose a job from the Jenkins dashboard
  • choose Embeddable Build Status
  • choose any "protected" URL
  • paste the URL into eg GitHub README

Making Badges Public

I found that I had to do a little configuration to make status badges readable by the public.

First I choose a security strategy that we can configure:

  • choose Manage Jenkins -> Configure Global Security
  • choose Access Control -> Authorization -> Role-Based Strategy
  • choose Save

Then I created an "anonymous" role that is allowed to view status badges:

  • choose Manage Jenkins -> Manage and Assign Roles -> Manage Roles
  • under Global Roles, enter in Role to add "anonymous"
  • choose Add
  • under Global Roles -> anonymous, check "ViewStatus"
  • choose Save

The I assigned this "anonymous" role to public aka "Anonymous" users

  • Manage Jenkins -> Manage and Assign Roles -> Assign Roles
  • under Global Roles -> Anonymous, check "anonymous"
  • choose Save

Clone this wiki locally