Hacking Jenkins

Miro Cupak (DNAstack), Oliver Gondza (Red Hat)

2015-02-07

Today's topics

  1. REST API
  2. CLI
  3. Scripting
  4. Groovy jobs

Environment Setup


wget http://www.fi.muni.cz/~xcupak/download/hacking-jenkins-offline.zip # or copy from USB keys
unzip hacking-jenkins-offline.zip
cd hacking-jenkins-offline
./start.sh # Jenkins should be available a http://localhost:8080/
                        
Section 1

REST API

Jenkins Exported API

  • Jenkins data exposed in machine readable format
  • available on most Jenkins URLs
  • support for json, xml and python

Jenkins REST API

  • numerous endpoints to interact with Jenkins
  • configuration exposed via config.xml endpoint
Task 1.1

Trigger actions in Jenkins

Task 1.1

Goal

Use REST API to trigger build using curl.

Task 1.1

Solution

curl -v -X POST http://localhost:8080/job/example_job/build
Task 1.2

Manipulate configuration using REST API

Task 1.2

Goal

Update number of executors on given node via REST API.

Hints

  • fetch config.xml, modify by hand and send it back
Task 1.2

Solution


curl http://localhost:8080/computer/example_slave/config.xml > example_slave.xml
vi example_slave.xml
curl -X POST http://localhost:8080/computer/example_slave/config.xml -d @example_slave.xml
                        
Section 2

Command-line interface

Jenkins CLI

Task 2.1

Using CLI commands

Task 2.1

Background

Jenkins master does not respond through UI. It needs to be shut down before whole machine can be restarted.

Task 2.1

Goal

Use Jenkins CLI to safely shutdown master.

Hints

  • have a look at safe-shutdown command
Task 2.1

Solution

java -jar jenkins-cli.jar -s http://localhost:8080 safe-shutdown
Task 2.2

Using CLI to manipulate configuration

Task 2.2

Goal

Create copy of existing node using nothing but Jenkins CLI.

Hints

  • Fetch config.xml and use it to create new node.
  • Commands get-node and create-node.
Task 2.2

Solution


java -jar jenkins-cli.jar -s http://localhost:8080 get-node example_slave > example_slave.xml
java -jar jenkins-cli.jar -s http://localhost:8080 create-node new_slave < example_slave.xml
                        
Section 3

Scripting

Jenkins Script Console

  • run arbitrary scripts on master and slave nodes
  • useful for users, developers, administrators
  • UI: Manage Jenkins > Script Console
  • CLI:
    java -jar jenkins-cli.jar -s http://jenkins/ groovysh
  • HTTP POST:
    curl -d "script=myscript.groovy" http://jenkins/script
Task 3.1

Executing scripts on slaves

Task 3.1

Background

Our build is failing upon initialization. We suspect the machine running the slave does not have enough free memory.

Task 3.1

Goal

Use example_slave's script console to find out how much free RAM it has.

Hints

Task 3.1

Solution


println "free -m".execute().text
Task 3.2

Executing scripts on master

Task 3.2

Background

Labels are basically the only way to distinguish slaves in Jenkins. A good idea is to use feature labels, i.e. tag slaves according to what they provide (e.g. "rhel7 32b mem16g").

Task 3.2

Goal

Use the script console to mark all Linux slaves as development machines, i.e. add "dev" label to all slaves with "linux" label.

Hints

  • a good place to start is the root of the Jenkins tree - Jenkins.instance
  • look at Javadoc of jenkins.model.Jenkins to find out how to obtain the list of slaves
  • slave labels are stored as a single space-delimited string
  • don't forget to persist your changes
Task 3.2

Solution


Jenkins.instance.getLabel("linux").nodes.each {
  it.labelString += " dev"
}

j.save()
Section 4

Groovy jobs

Groovy jobs

  • freestyle projects with a Groovy build step
  • provided by Groovy plugin
  • 2 types of build steps:
    • groovy scripts
      • run in the slave's JVM
      • like running groovy command with a script
    • system groovy scripts
      • run inside master's JVM
      • have access to all the internal objects of Jenkins and can alter its state
  • similar to script console
Task 4

Creating system jobs

Background

We're running a small Jenkins instance with a small number of slaves. Occasionally, slaves crash or need to undergo maintenance. We want to make sure that we have at least one online slave at any given time.

Task 4

Goal

Create a job monitoring the number of active slaves. The job should run on master every hour and send an email to you whenever there are no online slaves.

Hints

  • see Javadoc of hudson.model.Computer
  • use Mailer plugin to send the notifications
  • unlike the script console, jobs don't do any automagic imports - this should do the trick:
    
    import jenkins.model.*
    import hudson.model.*
    
Task 4

Solution


import jenkins.model.*
import hudson.model.*

def online = 0
for(computer in Jenkins.instance.computers){
  if(computer.isOnline()){
    online++
  }
}

return !(online<1)

Thank you.

Feedback: http://devconf.cz/f/152.
Slides: http://mcupak.github.io/hacking-jenkins-workshop/.