April 11th 2016

Parsing Jenkins log output to determine job status

I recently made the same mistake a number of times when adding new hosts to my Ansible configuration and decided to ensure it couldn't happen again. The specifics of this particular issue were that whilst I had added the hostname to inventory file, I had neglected to add the host to the relevant group in my playbook:

oldhost
newhost

[mygroup]
oldhost
# missing newhost here

ansible-playbook would output no hosts matched but crucially return with an successful exit code. My continuous integration system (Jenkins) would infer that the task was successful and not notify me that anything was wrong:

$ ansible-playbook deploy-mygroup.yml --limit-hosts=newhost
<snip>
PLAY [deploy] *************************************************
skipping: no hosts matched

PLAY RECAP ****************************************************

[ERROR]: No plays were matched by any host.

$ echo $?
0

This seemed to violate a few principles to me (at the very least due of the "loud" use of ERROR without the corresponding return code) so I filed a pull request against Ansible that added an optional --error-if-no-plays-matched switch:

$ ansible-playbook [..] --error-if-no-plays-matched
<snip>
[ERROR]: No plays were matched by any host.

$ echo $?
1

In the end, upstream decided to pass on it as it could be implemented via a plugin system and desiring an immediate and potentially more-general solution I briefly looked into parsing the ansible-playbook output before moving onto parsing the Jenkins log itself.

This turned out to be straightforward; using the Text-Finder plugin, I configured my Jenkins job to simply error if the log contained the string skipping: no hosts matched:

https://lamby-www.s3.amazonaws.com/yadt/blog.Image/image/original/26.jpeg

I am using the Job DSL plugin so that my configuration is backed onto revision control (highly recommended) so I actually used its textFinder publisher rather than the interface above:

publishers {
  textFinder(/^skipping: no hosts matched$/, '', true, false, false)
}

This results in the job "correctly" failing and alerting me:

+ ansible-playbook deploy-mygroup.yml --limit-hosts=newhost
<snip>

PLAY [deploy] *************************************************
skipping: no hosts matched

PLAY RECAP ****************************************************

[ERROR]: No plays were matched by any host.

Checking console output
/var/lib/jenkins/jobs/deploy-mygroup/builds/126/log:
skipping: no hosts matched
Build step 'Jenkins Text Finder' changed build result to FAILURE
Finished: FAILURE



You can subscribe to new posts via email or RSS.