About Anthony Dahanne

Anthony Dahanne is a Java software developer for 8 years, his favorite topics are Android, building tools, Continuous Integration and, of course, core Java development. Working for Terracotta, he currently implements the REST management interface for EhCache.

Using Jenkins / Hudson remote API to check jobs status

While working on my talk Writing a Hudson / Jenkins plugin (for EclipseCon NA 2014), I wanted to publish blog posts about the ideas mentioned in the talk; in this post I explain how you can interact with your CI server without using the web interface.

The Jenkins / Hudson remote API can be very convenient to quickly gather jobs status (and even to create or launch jobs ! but I won’t cover that aspect in this blog post); let’s have a look at some examples.

Have a look at the CLI to automate Jenkins configuration tasks.

It’s available at http://hudson-or-jenkins/cli : download the hudson-cli.jar or jenkins-cli.jar and get started with this first command :

 $ java -jar jenkins-cli.jar -s http://jenkins.terracotta.eur.ad.sag:8080/ help

Recently, I had to replace 50 jobs with a matrix job : once I created the matrix job, we decided to de activate the previous 50 jobs (before removing them for good)

Using the CLI, I could quickly login :

 $ java -jar jenkins-cli.jar -s http://jenkins.xx:8080/ login --username anthony --password password

then get the list of jobs :

 $ java -jar jenkins-cli.jar -s http://jenkins.xx:8080/ list-jobs

I saved the list of the 50 jobs I wanted to de activate in a text file, and I looped through this list :

 $ while read p; do java -jar jenkins-cli.jar -s http://jenkins.xx:8080/ disable-job $p; done < list_of_jobs.txt

More efficient than going through the UI, isn’t it ?

Every URL can be represented as XML or JSON

As explained in the Jenkins documentation and Hudson documentation, you just need to append /api/xml or /api/json or /api/python to any Jenkins URL to see the corresponding representation

You can configure the responses adding few arguments to the URL :

Depth

The default depth is 0, to get more details about your jobs, builds, etc, set the depth to 1 : http://ci.jruby.org/api/xml?depth=1

This argument can be harmful to your CI server when bigger than 1 (it gets really deep past 1 …) since the responses tend to become really large.

Tree

The tree argument allows you to select some portion of the response http://ci.jruby.org/api/xml?depth=1&tree=jobs[displayName,lastBuild[result]]

xpath and exclude (XML only)

Those arguments are probably the most powerful ones, sadly they are only available for xml responses :

If I only want to display jobs that were not successful, I can simply use this url : http://ci.jruby.org/api/xml?depth=1&tree=jobs[displayName,lastBuild[result]]&exclude=hudson/job[lastBuild[result='SUCCESS']]

And if I only want to see jobs with a name starting with “jruby”, I can apply Xpath functions to the url : http://ci.jruby.org/api/xml?xpath=hudson/job[starts-with(name,'jruby')]&wrapper=mywrap

Few Jenkins and Hudson public instances URLs

It’s pretty easy to find some public Jenkins and Hudson instances to practice your latest URL filtering (google for “Hudson Dashboard” or “Jenkins Dashboard”), but it’s harder to find up to date and meaningful (few jobs) instances :

Jenkins :

Hudson :

That said, try your local instance first!

Jenkins and Hudson remote API scripts

The main interest of the Jenkins/Hudson remote API is to interact with it from your own software : I gather here some examples in few scripting languages

Groovy Script to parse Jenkins Hudson build results

class BuildParser {
  static void main(String[] args) {
    if (args.length != 1) {
      println("Please run the script with a Jenkins or Hudson url as the only argument\n Example : groovy BuildParser.groovy http://ci.jruby.org");
      return;
    }
    def url = args[0];
    def xmlInputFilteringSuccess = new XmlParser().parse(url + "/api/xml?depth=1&tree=jobs[displayName,lastBuild[result]]&exclude=hudson/job[lastBuild[result=%27SUCCESS%27]]");
    def xmlInputNoFilter = new XmlParser().parse(url + "/api/xml?depth=1&tree=jobs");
 
    def jobs = xmlInputFilteringSuccess.job;
    println(jobs.size() + " jobs out of " + xmlInputNoFilter.job.size() + " are currently failing")
    jobs.each(
        {
          println(
              it.displayName.text() +
              " result is " + it.lastBuild.result.text())
        }
    )
  }
}

Python Script to parse Jenkins Hudson build results

import ast
import urllib
import sys

if len(sys.argv) != 2:
  print "Please run the script with a Jenkins or Hudson url as the only argument\n Example : python BuildParser.py http://ci.jruby.org"
  sys.exit(1)

url = str(sys.argv[1])
print url

xml_input_no_filter = ast.literal_eval(urllib.urlopen(url + "/api/python?depth=1&tree=jobs[displayName,lastBuild[result]]").read())

all_jobs = xml_input_no_filter['jobs']
non_successful_jobs = [row for row in all_jobs if 'SUCCESS' != row['lastBuild']['result']]

print(str(len(non_successful_jobs)) + " jobs out of " + str(len(all_jobs)) + " are currently failing")

for (i, item) in enumerate(non_successful_jobs):
  print "Job name : " + item['displayName'] + "Result : " + item['lastBuild']['result']

JavaScript code to parse Jenkins Hudson build results

<!-- Strongly inspired by https://gist.github.com/alexschwartz/912787 -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
  <title>Build Parser</title>
 
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js" type="text/javascript"></script>
 
  <script type="text/javascript">
    $(document).ready(function(){
      var baseUrl;
      $('button').click(function(){
        baseUrl = $("#baseUrl").val();
        $("#jobUrl").html(baseUrl)
 
        var success = function(json) {
          var allJobs = json["jobs"];
          var nonSuccessfulJobs = allJobs.filter(function( job ) {
            return job["lastBuild"] != null && job["lastBuild"]["result"] != "SUCCESS";
          });
 
          $("#downstream").html(nonSuccessfulJobs.length + " out of " + allJobs.length + " are currently failing");
          $.each(nonSuccessfulJobs, function( index, value ) {
            $("#downstream").append("<br />Job name : " + value["displayName"] + " : "+ value["lastBuild"]["result"] );
          });
        };
 
        $.ajax({
          url: baseUrl + "/api/json",
          data: "depth=1&tree=jobs[displayName,lastBuild[result]]&jsonp=callBack",
          jsonpCallback: "callBack",
          dataType: 'jsonp',
 
          success: success
        });
      });
    });
  </script>
</head>
<body marginwidth="50" marginheight="50" topmargin="50" leftmargin="50">
<h3>Input Data</h3>
 
Hudson/Jenkins Base URL:
<input type="text" id="baseUrl" value="https://hudson.eclipse.org/hudson/" size="80" /><br/>
 
<button>update</button><br />
 
<h2>Output</h2>
 
<h3>Failing Jobs</h3>
<div id="downstream">
</div>
 
</body></html>

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

Leave a Reply


− 1 = one



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close