Remote access API

Hudson provides machine-consumable remote access API to its functionalities. Currently it comes in three flavors:

  1. XML
  2. JSON with JSONP support
  3. Python

Remote access API is offered in a REST-like style. That is, there is no single entry point for all features, and instead they are available under the ".../api/" URL where "..." portion is the data that it acts on.

For example, if your Hudson installation sits at http://deadlock.netbeans.org/hudson/, http://deadlock.netbeans.org/hudson/api/ will give you HTML lists of all available functionalities that act on the Hudson root. For example, from here you can access all the jobs on Hudson via XML/JSON. Or if you want to access information about a particular build at http://deadlock.netbeans.org/hudson/job/trunk/lastSuccessfulBuild/, then go to http://deadlock.netbeans.org/hudson/job/trunk/lastSuccessfulBuild/api/ and you'll see the list of functionalities for the build.

The work on this front is on-going, so if you find missing features, please file an issue.

What can you do with it?

Remote API can be used to do things like these:

  1. retrieve information from Hudson for programmatic consumption.
  2. trigger a new build
  3. create/copy jobs

Submitting jobs

For a job with no parameters, you need merely go an HTTP GET on

HUDSON_URL/job/JOBNAME/build?token=TOKEN

where TOKEN is set up in the job configuration.

If you have parameters, you need to send JSON. Here's a snipped of shell, with
a few extra newlines to be more readable.

json="{\"parameter\": [{\"name\": \"taskfile\", \"value\": \"$taskfile\"}, 
{\"name\": \"task\", \"value\": \"$task\"}, 
{\"name\": \"jobParameters\", \"value\": \"$jobargs\"}], \"\": \"\"}"
url=http://hudson.basistech.net/job/benson-segmentation-training/build
curl -X POST $url -d token=zorn --data-urlencode json="$json" 

Remote API and security

When your Hudson is secured, you can use HTTP BASIC authentication to authenticate remote API requests. See Authenticating scripted clients for more details.

Sample code

A simple client is available to demonstrate how you can invoke the XML from Java (Java source)

XPath selection

The XML API supports a selection by XPath by using the query parameter 'xpath'. This is convenient for extracting information in environments where XML manipulation is tedious (such as shell script.) See issue #626 for an example of how to use this.
See .../api/ on your Hudson server for more up-to-date details.

XPath exclusion

Similar to the 'xpath' query parameter above, you can use (possibly multiple) 'exclude' query patterns to exclude nodes from the resulting XML. All the nodes that match the specified XPath will be removed from the XML.
See .../api/ on your Hudson server for more up-to-date details.

Depth control

Sometimes the remote API doesn't give you enough information in one call. For example, if you'd like to find out all the last successful build of a given view, you'd realize that the invocation to the remote API of the view won't give you this, and you'd have to recursively call the remote API of each project to find this out. The depth control, introduced in 1.167, solves this problem. To understand this feature, it's good to start with how the remote API works.

The data model that Hudson maintains internally can be thought of as a big tree structure, and when you make a remote API call, you are getting a small subtree of it. The subtree is rooted at the object for which you made a remote API call, and the sub-tree is cut beyond certain depth to avoid returning too much data. You can adjust this cut-off behavior by specifying the depth query parameter. When you specify a positive depth value, the subtree cut-off happens that much later.

So the net result is, if you specify a bigger depth value, you'll see that the remote API will now return more data. Because of the algorithm, this works in such a way that the data returned by a bigger depth value includes all the data returned by smaller
depth value.

See .../api/ on your Hudson server for more up-to-date details.

Detecting Hudson version

To check the version of Hudson, load the top page and check for the "X-Hudson" response header. This contains the version number of Hudson, like "1.358" This is also a good way to check if an URL is a Hudson URL.

Discovering Hudson on the network

Hudson instances listen on UDP port 33848. Whenever a UDP packet is received, it will respond with a short XML fragment that shows the connection information. This XML has the following format:

<hudson>
  <version>1.380</version>           <!-- version of Hudson -->
  <url>http://somwhere/hudson/</url> <!-- HTTP URL. Not available if not configured -->
  <slave-port>12345</slave-port>     <!-- if TCP slave listener port is configured, its number -->
</hudson>

By using this, a client can use a UDP broadcast to try to discover nearby Hudson instances. This is primarily useful for a self-organizing build cluster.

Labels:

Enter labels to add to this page:
Wait Image 
Looking for a label? Just start typing.
  1. Oct 27, 2009

    Alejandro Pérez García says:

    Spanish tutorial about how to launch a build from a Subversion's hook, using the...

    Spanish tutorial about how to launch a build from a Subversion's hook, using the remote API

    http://www.adictosaltrabajo.com/tutoriales/tutoriales.php?pagina=hudsonSubversionPush

  2. Apr 11, 2010

    Gabor Engler says:

    On the Parameterized Build page (http://wiki.hudson-ci.org/display/HUDSON/Parame...

    On the Parameterized Build page (http://wiki.hudson-ci.org/display/HUDSON/Parameterized+Build) you can find other useful information about remote API feature:

    e.g.: Remote build with multiple parameters: http://server/job/myjob/buildWithParameters?PARAM1=Value1&PARAM2=Value2

    1. Oct 27, 2010

      holger horn says:

      I tried to trigger remotly by URL a job with multiple parameters like this : ht...

      I tried to trigger remotly by URL a job with multiple parameters like this :

      http://server/job/myjob/buildWithParameters?PARAM1=Value1&PARAM2=Value2

      exactly this is not working, what am I doing wrong?

      is someone there who has tried it with success?

      I tried also to send same request with JSON, like described above. no success too... I used this URL:

      Unable to render embedded object: File (parameter.BMP) not found.

      can someone help me? what am I doing wrong?

  3. Apr 30, 2010

    Joel Beaudoin says:

    Is there any way to use this API to tell Hudson to "keep this build forever" for...

    Is there any way to use this API to tell Hudson to "keep this build forever" for a particular build. I am working on some automation for publishing a particular build to an FTP site and this is one of the steps I would like performed. So far, I haven't been able to figure out a programmatic way to mark a given build as "keep" in Hudson. Ideas?

    1. Jul 14, 2010

      Joel Beaudoin says:

      After looking into this a bit closer, I figured out how to do this. A simple wge...

      After looking into this a bit closer, I figured out how to do this. A simple wget/curl of something like:

      http://company.com/hudson/view/ViewNameHere/job/JobNameHere/nn/toggleLogKeep

      or outside of a view like

      http://company.com/hudson/job/JobNameHere/nn/toggleLogKeep

      Replacing ViewNameHere and JobNameHere as appropriate and specifying the build number in place of 'nn'. Obvious after viewing the HTML, but it would be cool to have a page documenting this type of thing. Just an idea ... I sure don't have the time to do it 8-(

      1. Jul 22, 2010

        Joel Beaudoin says:

        Here is a simple python example to do this toggling. Most of the logic is to dea...

        Here is a simple python example to do this toggling. Most of the logic is to deal with the 403 that Hudson returns to request authorization:

        
        import urllib2
        import base64
        
        class HudsonToggleKeep:
        
            def __init__(self):
                self.username = 'username'
                self.password = 'password'
                self.server   = 'https://server.com'
        
                pass_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
                pass_mgr.add_password(None, self.server, self.username, self.password)
        
                b_auth = urllib2.HTTPBasicAuthHandler(pass_mgr)
                d_auth = urllib2.HTTPDigestAuthHandler(pass_mgr)
        
                self.url_opener = urllib2.build_opener(b_auth, d_auth,
                                                       self.HudsonFormLoginHandler(self))
        
                urllib2.install_opener(self.url_opener)
        
        
            class HudsonFormLoginHandler(urllib2.BaseHandler):
                def __init__(self, parent):
                    self.p = parent
        
                def http_error_403(self, req, fp, code, msg, headers):
                    for h in self.p.url_opener.handlers:
                        if isinstance(h, self.p.HTTPOpenHandlerBasicAuthNoChallenge):
                            return
        
                    self.p.url_opener.add_handler(
                        self.p.HTTPOpenHandlerBasicAuthNoChallenge(self.p.username,
                                                                   self.p.password))
                    fp.close()
                    return self.p.url_opener.open(req)
        
            class HTTPOpenHandlerBasicAuthNoChallenge(urllib2.BaseHandler):
        
                auth_header = 'Authorization'
        
                def __init__(self, username, password):
                    raw = "%s:%s" % (username, password)
                    self.auth = 'Basic %s' % base64.b64encode(raw).strip()
        
                def default_open(self, req):
                    req.add_header(self.auth_header, self.auth)
        
        
        
        if __name__ == "__main__":
            hp = HudsonToggleKeep()
            req = urllib2.Request("https://server.com/hudson/view/MyView/job/MyJob/15/toggleLogKeep")
            d = urllib2.urlopen(req).read()
        
  4. Jul 20, 2010

    William Luo says:

    python sample code of hudson remote api #!/usr/bin/env python # this script ...

    python sample code of hudson remote api

    #!/usr/bin/env python
    
    # this script is only demo purpose which is designed to get properties of job, queue, like
    # nextBuildNumber. But note the logistics might not be correct
    
    import urllib2
    
    #call api of job 'git_plugin_test'
    url="http://localhost:9001/job/git_plugin_test/api/python?depth=0"
    response=urllib2.urlopen(url)
    build_dict=eval(response.read())
    
    #call api of job 'queue' of hudson (global but not specific for one job)
    url="http://localhost:9001/queue/api/python?depth=0"
    response=urllib2.urlopen(url)
    queue_dict=eval(response.read())
    
    print ''*40,'build dict',''*40
    #print properties of job
    for eachKey in build_dict:
        print eachKey,build_dict[eachKey]
        print
    
    print ''*40,'queue dict',''*40
    #look through items in queue and can be extended to forecast the job build
    #number in for one item in queue
    for index in range(1,len(queue_dict['items'])):
        print ''*40,'queue hash',''*40
        qi_action=queue_dict['items'][index]['actions']
        list_para=qi_action[0]['parameters']
        for index1 in range(0,len(list_para)):
            print list_para[index1]
            if list_para[index1]['name'] == 'SLEEP_TIME' and list_para[index1]['value'] == '62':
                print "OK"
    
    #only valid when no more than one build found in queue
    if build_dict['inQueue']:
        build_number=int(build_dict['nextBuildNumber']) + 1
    else:
        build_number=int(build_dict['nextBuildNumber'])
    print "Hudson Build URL:",build_dict['url']+str(build_number)
    print "Current build tree:"+build_dict['builds'][0]['url']
    
  5. Jan 04, 2011

    Christopher Marsh-Bourdon says:

    Is there any way to access the configuration of the Jobs, I tried the following,...

    Is there any way to access the configuration of the Jobs, I tried the following, but with no success:

    http://company.com/hudson/job/JOBNAME/configure/api/xml

    This just yielded a 404, so either this functionality doesn't exist, or I have erred on the URL.

    1. Jan 04, 2011

      Joel Beaudoin says:

      You can access a job's configuration via: http://company.com/hudson/job/JOBNAME...

      You can access a job's configuration via:

      http://company.com/hudson/job/JOBNAME/config.xml

      You can find out this and other cool things via:

      http://company.com/hudson/job/JOBNAME/api/

      Hope this helps,
      Joel

      1. Jan 04, 2011

        Christopher Marsh-Bourdon says:

        A big thanks Joel; that was exactly what I was after.

        A big thanks Joel; that was exactly what I was after.

      2. Nov 17, 2011

        guowei says:

        this url can't update parent_job? thanks

        this url can't update parent_job? thanks

  6. Feb 03, 2011

    Victor Calvello says:

    Hi Guys! Just in case you need to use the secured java client as in demo (http:/...

    Hi Guys!
    Just in case you need to use the secured java client as in demo (http://java.net/projects/hudson/sources/svn/content/trunk/hudson/extras/client-demo/src/main/java/org/jvnet/hudson/client_demo/SecuredMain.java?rev=38455), the url to post credentials is wrong. Replace 'j_security_check' by 'j_acegi_security_check' and it will work like a charm!

    Hope this helps,
    Vic

  7. Nov 17, 2011

    guowei says:

    Hi all; how to update parent_job? thanks!

    Hi all;

    how to update parent_job?

    thanks!