Balaji Vajjala's Blog

A DevOps Blog from Trenches

Using jenkins-cli as job Gen

Well a common use case for doing stuff with Jenkins jobs / configuration [ for example: enabling jobs, disabling jobs, executing jobs etc] is to use Jenkins-cli.jar which is included in your jenkins distribution.

In a large company where branches are branched on a daily basis and you need a build for each branch, job creation could become a bottleneck [ so could branch creation – but that a different topic :) ].

So my use case was to create a Job Generator which would take an existing job from branch 1.0 and create a job ( & the ranch but as I said different topic ) for branch 2.0 with the corresponding name, so as I mentioned thank god for Jenkins in general, Jenkins-cli and in addition to that a shell script, sed, xmlstarlet and again jenkins job parameters.

I needed a script which would export the job configuration to an xml file, search and replace for the SCM url, create the job so lets see how its done:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
execJenkinsCli(){ # excute jenkins-cli jar 
        jenkins_clinet_jar=./jenkins-cli.jar
        # download only if it's newwer than the local version [ curl -z ], the cli jar should be ofthe smae jenkins version ...
        curl -s -z ./jenkins-cli.jar ${JENKINS_URL}/jnlpJars/jenkins-cli.jar -o ${jenkins_clinet_jar} || { echo "Echo  cannot obtain jenkins-cli.jar exiting"; exit 2;}
        cli_cmd=$1
        cmd_params=$2
        cmd_prefix="${JAVA_CMD} -jar ${jenkins_clinet_jar} -s ${JENKINS_URL}"

        ${cmd_prefix} who-am-i | grep 'Authenticated as: anonymous' &>/dev/null && anon=0
        #anon=$?
        if [ "$anon" != "0" ]; then
                #printf "[ $FUNCNAME ] using jenkins-cli with private key auth"
                exec ${cmd_prefix} ${cli_cmd} ${cmd_params}
        elif [ "x" = "x${JENKINS_USER}" ] || [ "x"  = "x${JENKINS_PASS}" ]; then
                printf "[ $FUNCNAME ] cannot determin jenkins credentials\n";
                exit 3;
        else
                exec ${cmd_prefix} ${cli_cmd} ${cmd_params} --username ${JENKINS_USER} --password ${JENKINS_PASS}
        fi
}

execJenkinsCli get-job ${tmpl_job_name}  | \
  ${XML} ed -O -S -P -u '//project/scm/locations/hudson.scm.SubversionSCM_-ModuleLocation/remote' -v ${scm_url} | \
  execJenkinsCli create-job ${new_job_name}

  execJenkinsCli enable-job ${new_job_name} # our template is usually disabled, thus the cloned one is too ...

The full jobGen wrapper script can be found here

Tieing it all together:

  1. Create a template job [preferably keep it disabled so if it has SCM triggers it doesn't start on any scm change …] – see this gist
  2. Create a job which will generate the jobs for you – ${PRODUCT_NAME}.JobGen – with parameters see this gist Job Gen Parameters

    • template_job [default value = ${PRODUCT_NAME}.Template]
    • new_job_name
    • scm_url [ if you don't know how to fund see this section ]
  3. Provide the required permision for this job (so only permitted people can generate jobs …)

 

A few workds about this script:

  1. It's just an implementation example (which I changed from the original which was working with perforce) – yet it could work wth git too :)
  2. The execJenkinsCli script does a few things here:
    • Download the latest jenkins-cli.jar file – useful if you update jenkins and you want (believe me you do) the client to be up2dat with the server (it will not download if its the same version …
    • Check to see if your using a private / public key auth [ available since jenkins 1.419 ] and will change the execution accordingly

Hope you find this useful.

HP