Wednesday, October 22, 2014

Calling a jenkins job with a bash script

I don't care to use a mouse when I'm working on a project unless I have to. As nice as Jenkins is, if you have to re-run a job often, clicking through their UI can get old fast. I had trouble getting the API access working with a script, so I better write down what I did.

First things, you need to enable script triggers at the job level. Configure the job and under Build Triggers, select "Trigger builds remotely" and add an API key. See my earlier post for one or two options to generate a job token.

Next thing you need to do is set/get your personal API token from Jenkins. You could create another account if you choose to, but you will need an account that has access to execute the action you want to do e.g. have a script to run a job. Click on your login name and then configure > API Token > Show API Token

I took this from one of the jenkins posts but I don't remember which one. I use curl instead of wget and handle parameter jobs or parameterless jobs. There's more you could do to clean this up, but it works.



#!/bin/bash ########################################################################
# This is an example how to call a jenkins job using bash
#
# PreReqs:
# 1: Add a token to your jenkins job. Configure job,
# "Build Triggers - Trigger builds remotely (e.g. from scripts)"
# One way to generate a job token
#
# $> r="";for e in $(seq 1 5); do r="${r}$(od -vAn -N4 -tu4 < /dev/urandom|sed 's| ||g')"; done;echo $r|openssl sha1 -sha256
#
# 2: Go get your own personal token
# You can click on your name, 'Configure > API Token > Show API Token
#
# 3: Run your job e.g. run one that has parameters
# ./run-jenkins-job.sh login <persoal-token> jenkins-job-name <job-token> 'PARAMA=value&PARAMB=value'
#
# run one without params
# ./run-jenkins-job.sh <login> <login-token> <jenkins-job-name> <job-token>
#
# Add any job parameters there.
########################################################################
USER="$1"
TOKEN="$2"
JOB="$3"
JTOKEN="$4"
PARAMS="$5"
function usage {
echo "$0 <jenkins-login> <jenkins-login-token> <jenkins-job> <job-token> 'job_param_a=value&job_param_b=value'"
}
if [ "" == "${USER}" ]; then
usage
exit 1
fi
if [ "" == "${TOKEN}" ]; then
usage
exit 1
fi
if [ "" == "${JOB}" ]; then
usage
exit 1
fi
if [ "" == "${JTOKEN}" ]; then
usage
exit 1
fi
# jobs that have params need a different url and the params need to be on the query string
if [ "" == "${PARAMS}" ]; then
NOTIFY_URL="job/${JOB}/build"
else
NOTIFY_URL="job/${JOB}/buildWithParameters?${PARAMS}"
fi
CRUMB_ISSUER_URL='crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'
function notifyCI {
CISERVER=$1
# Check if "[X] Prevent Cross Site Request Forgery exploits" is activated
# so we can present a valid crumb or a proper header
HEADER="Content-Type:text/plain;charset=UTF-8"
CRUMB=$(curl --user ${USER}:${TOKEN} ${CISERVER}/${CRUMB_ISSUER_URL} 2>/dev/null)
if [ "$CRUMB" != "" ]; then
HEADER=$CRUMB
fi
curl -X POST ${CISERVER}/${NOTIFY_URL} --header "${HEADER}" --data-urlencode "token=${JTOKEN}" --user "${USER}:${TOKEN}"
echo "Done"
}
# The code above was placed in a function so you can easily notify multiple Jenkins/Hudson servers:
notifyCI "http://jenkins-server"


Sunday, October 19, 2014

Generating a token

I found a couple of ways to quickly generate a token for use with APIs. I needed a unique token for my Jenkins jobs and found these two useful.

r="";for e in $(seq 1 5); do r="${r}$(od -vAn -N4 -tu4 < /dev/urandom|sed 's| ||g')"; done;echo $r|openssl sha1 -sha256

d81697b6322a81a7fb19e0ef1141f534da0634244e76b5590332a1a186c7c4a9

r="";for e in $(seq 1 10); do r="$r${RANDOM}"; done; echo $r|openssl sha1 -sha256