Example 3: Handle custom status of playbook

Playbook

Generate random success or failure of the script (9,15) and register the results (10,16). Put the rc codes into the dictionary my_rc (11,17). Put the the dictionary into the custom status of the playbook (23).

 1shell> cat private6/project/playbook.yml
 2- hosts:
 3    - test_01
 4    - test_02
 5    - test_03
 6  ignore_errors: true
 7
 8  tasks:
 9    - shell: '[ "$(jot -r 1 0 100)" -gt "50" ] && true || false'
10      register: result
11    - set_fact:
12        my_rc: "{{ my_rc|default({})|
13                   combine({inventory_hostname:
14                           {'script1': result.rc}}, recursive=True) }}"
15    - shell: '[ "$(jot -r 1 0 100)" -gt "50" ] && true || false'
16      register: result
17    - set_fact:
18        my_rc: "{{ my_rc|default({})|
19                   combine({inventory_hostname:
20                           {'script2': result.rc}}, recursive=True) }}"
21    - set_stats:
22        data:
23          my_rc: "{{ my_rc }}"
24        per_host: false

Enable custom status

1shell> cat private6/env/envvars
2ANSIBLE_SHOW_CUSTOM_STATS: true

Wrapper ansible-runner

[arwrapper.bash]

 1#!/bin/bash
 2
 3# All rights reserved (c) 2020, Vladimir Botka <vbotka@gmail.com>
 4# Simplified BSD License, https://opensource.org/licenses/BSD-2-Clause
 5
 6version="1.0.0"
 7runner=$HOME/bin/ansible-runner
 8project=$PWD/$2
 9param=${3:-all.yml}
10usage="$(basename "$0") ver $version
11
12Usage:
13  $(basename "$0") <cmd> project [param]
14
15Where:
16  cmd ....... One of the commands: run, runid, stdout, custom, clean, test
17  project ... Private data directory. See ansible-runner.
18  param ..... Command specific parameter. See commands.
19
20Commands:
21  run project playbook.yml ......... Run playbook.yml in project
22  runid project playbook.yml ....... The same as run plus display artifact id
23  stdout project id ................ Display project/id/stdout
24  custom project id ................ Display custom stat from project/id/stdout
25  clean project .................... Delete project/artifacts
26  test project playbook.yml ........ Test playbook.yml in project
27
28Examples:
29  arwrapper run priv9 t9.yml ....... Run playbook t9.yml in priv9
30  arwrapper test priv9 t9.yml ...... Test playbook t9.yml in priv9
31  arwrapper clean priv9 ............ Delete pri9/artifacts
32  arwrapper stdout priv9 id1 ....... Display priv9/artifacts/id1/stdout
33  arwrapper custom priv9 id1........ Display custom stat from stdout\n"
34
35case "$1" in
36    test)
37	echo $(date '+%Y-%m-%d %H:%M:%S') $runner run $project -p $param
38	;;
39    run|runid)
40	echo $(date '+%Y-%m-%d %H:%M:%S') $0
41	if [ -f "$HOME/.ssh/environment" ]; then
42	    source $HOME/.ssh/environment
43	fi
44	$runner run $project -p $param
45	if [ "$1" = "runid" ]; then
46	    ls -t $project/artifacts | head -1
47	fi
48	;;
49    stdout)
50	cat $project/artifacts/$param/stdout
51	;;
52    custom)
53	cat $project/artifacts/$param/stdout | \
54        sed -n '/PLAY RECAP/,$p' | \
55        sed -n '/CUSTOM STATS/,$p' | \
56        tail -n +2 | \
57	cut -d ":" -f2-
58	;;
59    clean)
60	rm -rf $project/artifacts
61	;;
62    *)
63	printf "$usage\n"
64	exit 1
65	;;
66esac
67exit

Run the playbook and display the artifacts’ directory

Run the playbook with the wrapper command runid (1). Last line of the output is the directory of the artifacts (59)

 1shell> arwrapper.bash runid private6 playbook.yml
 22020-09-26 19:23:45 ./arwrapper.bash
 3
 4PLAY [test_01,test_02,test_03] *************************************************
 5
 6TASK [Gathering Facts] *********************************************************
 7ok: [test_02]
 8ok: [test_01]
 9ok: [test_03]
10
11TASK [shell] *******************************************************************
12...ignoring
13fatal: [test_01]: FAILED! => {"changed": true, "cmd": "[ \"$(jot -r 1 0 100)\" -gt \"50\" ] && true || false", "delta": "0:00:00.025406", "end": "2020-09-26 19:18:52.908024", "msg": "non-zero return code", "rc": 1, "start": "2020-09-26 19:18:52.882618", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
14...ignoring
15...ignoring
16fatal: [test_02]: FAILED! => {"changed": true, "cmd": "[ \"$(jot -r 1 0 100)\" -gt \"50\" ] && true || false", "delta": "0:00:00.025532", "end": "2020-09-26 19:18:52.912931", "msg": "non-zero return code", "rc": 1, "start": "2020-09-26 19:18:52.887399", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
17...ignoring
18changed: [test_03]
19
20TASK [set_fact] ****************************************************************
21ok: [test_02]
22ok: [test_01]
23ok: [test_03]
24
25TASK [shell] *******************************************************************
26changed: [test_02]
27fatal: [test_01]: FAILED! => {"changed": true, "cmd": "[ \"$(jot -r 1 0 100)\" -gt \"50\" ] && true || false", "delta": "0:00:00.022179", "end": "2020-09-26 19:18:53.258569", "msg": "non-zero return code", "rc": 1, "start": "2020-09-26 19:18:53.236390", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
28...ignoring
29fatal: [test_03]: FAILED! => {"changed": true, "cmd": "[ \"$(jot -r 1 0 100)\" -gt \"50\" ] && true || false", "delta": "0:00:00.023787", "end": "2020-09-26 17:18:53.261070", "msg": "non-zero return code", "rc": 1, "start": "2020-09-26 17:18:53.237283", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
30...ignoring
31
32TASK [set_fact] ****************************************************************
33ok: [test_02]
34ok: [test_01]
35ok: [test_03]
36
37TASK [set_stats] ***************************************************************
38ok: [test_02]
39ok: [test_01]
40ok: [test_03]
41
42test_01: ok=6    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=2
43test_02: ok=6    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=1
44test_03: ok=6    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=1
45
46CUSTOM STATS: ******************************************************************
47
48
49PLAY RECAP *********************************************************************
50test_01: ok=6    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=2
51test_02: ok=6    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=1
52test_03: ok=6    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=1
53
54
55CUSTOM STATS: ******************************************************************
56
57RUN: { "my_rc": {  "test_01": {   "script1": 1,   "script2": 1  },  "test_02": {   "script1": 1,   "script2": 0  },  "test_03": {   "script1": 0,   "script2": 1  } }}
58
599f27dbaf-45e2-44c7-bf2f-c84f081cbc17

Display the custom status from the artifacts

1shell> arwrapper.bash custom private6 9f27dbaf-45e2-44c7-bf2f-c84f081cbc17
2
3{ "my_rc": {  "test_01": {   "script1": 1,   "script2": 1  },  "test_02": {   "script1": 1,   "script2": 0  },  "test_03": {   "script1": 0,   "script2": 1  } }}

Select results of the first script

1shell> arwrapper.bash custom private6 9f27dbaf-45e2-44c7-bf2f-c84f081cbc17 | jq .my_rc[].script1
21
31
40