# Improving default output

**URL:** <https://forum.ansible.com/t/improving-default-output/22123>\
**Category:** Ansible Developer\
**Tags:** kubernetes\
**Created:** [July 26, 2016, 11:29am UTC](https://forum.ansible.com/t/improving-default-output/22123 "2016-07-26T11:29:11Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![James\_Pic](https://avatars.discourse-cdn.com/v4/letter/j/73ab20/32.png) [@James\_Pic](https://forum.ansible.com/u/James_Pic)\
**Post date:** [July 26, 2016, 11:29am UTC](https://forum.ansible.com/t/improving-default-output/22123/1 "2016-07-26T11:29:11Z")

</div>

Hi all !

When supporting openshift-ansible, users share pastes like (ie. on IRC)::

TASK: [openshift\_serviceaccounts | Grant the user access to the privileged scc] \*\*\*  
changed: [[li1491-86.members.linode.com](http://li1491-86.members.linode.com)] =\> (item=[‘router’, {‘cmd’: [‘oc’, ‘get’, ‘scc’, ‘privileged’, ‘-o’, ‘yaml’], ‘end’: ‘2016-05-05 13:31:50.216857’, ‘stderr’: u’‘, ‘stdout’: ‘allowHostDirVolumePlugin: true\nallowHostIPC: true\nallowHostNetwork: true\nallowHostPID: true\nallowHostPorts: true\nallowPrivilegedContainer: true\nallowedCapabilities: null\napiVersion: v1\ndefaultAddCapabilities: null\nfsGroup:\n type: RunAsAny\ngroups:\n- system:cluster-admins\n- system:nodes\nkind: SecurityContextConstraints\nmetadata:\n annotations:\n [kubernetes.io/description:](http://kubernetes.io/description:) 'privileged allows access to all privileged and host\n features and the ability to run as any user, any group, any fsGroup, and with\n any SELinux context. WARNING: this is the most relaxed SCC and should be used\n only for cluster administration. Grant with caution.'\n creationTimestamp: 2016-05-05T13:30:06Z\n name: privileged\n resourceVersion: “371”\n selfLink: /api/v1/securitycontextconstraints/privileged\n uid: 7ae22005-12c5-11e6-9bc5-06174e73e52a\npriority: null\nreadOnlyRootFilesystem: false\nrequiredDropCapabilities: null\nrunAsUser:\n type: RunAsAny\nseLinuxContext:\n type: RunAsAny\nsupplementalGroups:\n type: RunAsAny\nusers:\n- system:serviceaccount:openshift-infra:build-controller\n- system:serviceaccount:management-infra:management-admin\n- system:serviceaccount:management-infra:inspector-admin\nvolumes:\n- '_'‘, ‘item’: ‘privileged’, ‘changed’: False, ‘rc’: 0, ‘failed’: False, ‘warnings’: [], ‘delta’: ‘0:00:00.264340’, ‘invocation’: {‘module\_name’: u’command’, ‘module\_complex\_args’: {}, ‘module\_args’: u’oc get scc privileged -o yaml’}, ‘stdout\_lines’: [‘allowHostDirVolumePlugin: true’, ‘allowHostIPC: true’, ‘allowHostNetwork: true’, ‘allowHostPID: true’, ‘allowHostPorts: true’, ‘allowPrivilegedContainer: true’, ‘allowedCapabilities: null’, ‘apiVersion: v1’, ‘defaultAddCapabilities: null’, ‘fsGroup:’, ’ type: RunAsAny’, ‘groups:’, ‘- system:cluster-admins’, ‘- system:nodes’, ‘kind: SecurityContextConstraints’, ‘metadata:’, ’ annotations:‘, " [kubernetes.io/description:](http://kubernetes.io/description:) ‘privileged allows access to all privileged and host", ’ features and the ability to run as any user, any group, any fsGroup, and with’, ’ any SELinux context. WARNING: this is the most relaxed SCC and should be used’, " only for cluster administration. Grant with caution.‘", ’ creationTimestamp: 2016-05-05T13:30:06Z’, ’ name: privileged’, ’ resourceVersion: “371”‘, ’ selfLink: /api/v1/securitycontextconstraints/privileged’, ’ uid: 7ae22005-12c5-11e6-9bc5-06174e73e52a’, ‘priority: null’, ‘readOnlyRootFilesystem: false’, ‘requiredDropCapabilities: null’, ‘runAsUser:’, ’ type: RunAsAny’, ‘seLinuxContext:’, ’ type: RunAsAny’, ‘supplementalGroups:’, ’ type: RunAsAny’, ‘users:’, ‘- system:serviceaccount:openshift-infra:build-controller’, ‘- system:serviceaccount:management-infra:management-admin’, ‘- system:serviceaccount:management-infra:inspector-admin’, ‘volumes:’, "- '_’"], ‘failed\_when\_result’: False, ‘start’: ‘2016-05-05 13:31:49.952517’}])  
changed: [[li1491-86.members.linode.com](http://li1491-86.members.linode.com)] =\> (item=[‘registry’, {‘cmd’: [‘oc’, ‘get’, ‘scc’, ‘privileged’, ‘-o’, ‘yaml’], ‘end’: ‘2016-05-05 13:31:50.216857’, ‘stderr’: u’', ‘stdout’: ‘allowHostDirVolumePlugin: true\nallowHostIPC: true\nallowHostNetwork: true\nallowHostPID: true\nallowHostPorts: true\nallowPrivilegedContainer: true\nallowedCapabilities: null\napiVersion: v1\ndefaultAddCapabilities: null\nfsGroup:\n type: RunAsAny\ngroups:\n- system:cluster-admins\n- system:nodes\nkind: SecurityContextConstraints\nmetadata:\n annotations:\n [kubernetes.io/description:](http://kubernetes.io/description:) 'privileged allows access to all privileged and host\n features and the ability to run as any user, any group, any fsGroup, and with\n any SELinux context. WARNING: this is the most relaxed SCC and should be used\n only for cluster administration. Grant with caution.'\n creationTimestamp: 2016-05-05T13:30:06Z\n name: privileged\n resourceVersion: “371”\n selfLink: /api/v1/securitycontextconstraints/privileged\n uid: 7ae22005-12c5-11e6-9bc5-06174e73e52a\npriority: null\nreadOnlyRootFilesystem: false\nrequiredDropCapabilities: null\nrunAsUser:\n type: RunAsAny\nseLinuxContext:\n type: RunAsAny\nsupplementalGroups:\n type: RunAsAny\nusers:\n- system:serviceaccount:openshift-infra:build-controller\n- system:serviceaccount:management-infra:management-admin\n- system:serviceaccount:management-infra:inspector-admin\nvolumes:\n- '_'‘, ‘item’: ‘privileged’, ‘changed’: False, ‘rc’: 0, ‘failed’: False, ‘warnings’: [], ‘delta’: ‘0:00:00.264340’, ‘invocation’: {‘module\_name’: u’command’, ‘module\_complex\_args’: {}, ‘module\_args’: u’oc get scc privileged -o yaml’}, ‘stdout\_lines’: [‘allowHostDirVolumePlugin: true’, ‘allowHostIPC: true’, ‘allowHostNetwork: true’, ‘allowHostPID: true’, ‘allowHostPorts: true’, ‘allowPrivilegedContainer: true’, ‘allowedCapabilities: null’, ‘apiVersion: v1’, ‘defaultAddCapabilities: null’, ‘fsGroup:’, ’ type: RunAsAny’, ‘groups:’, ‘- system:cluster-admins’, ‘- system:nodes’, ‘kind: SecurityContextConstraints’, ‘metadata:’, ’ annotations:‘, " [kubernetes.io/description:](http://kubernetes.io/description:) ‘privileged allows access to all privileged and host", ’ features and the ability to run as any user, any group, any fsGroup, and with’, ’ any SELinux context. WARNING: this is the most relaxed SCC and should be used’, " only for cluster administration. Grant with caution.‘", ’ creationTimestamp: 2016-05-05T13:30:06Z’, ’ name: privileged’, ’ resourceVersion: “371”‘, ’ selfLink: /api/v1/securitycontextconstraints/privileged’, ’ uid: 7ae22005-12c5-11e6-9bc5-06174e73e52a’, ‘priority: null’, ‘readOnlyRootFilesystem: false’, ‘requiredDropCapabilities: null’, ‘runAsUser:’, ’ type: RunAsAny’, ‘seLinuxContext:’, ’ type: RunAsAny’, ‘supplementalGroups:’, ’ type: RunAsAny’, ‘users:’, ‘- system:serviceaccount:openshift-infra:build-controller’, ‘- system:serviceaccount:management-infra:management-admin’, ‘- system:serviceaccount:management-infra:inspector-admin’, ‘volumes:’, "- '_’"], ‘failed\_when\_result’: False, ‘start’: ‘2016-05-05 13:31:49.952517’}])

This is absolutely not readable.

I made a PR on openshift-ansible to override the output from the default callback plugin: [https://github.com/openshift/openshift-ansible/pull/1861](https://github.com/openshift/openshift-ansible/pull/1861)

But now I’d like to contribute this upstream, basically the idea is that with -v we get:

- indented json
- std{err,out} printed apart with proper newlines

What’s your opinion ?

Is there anything to consider before I get started ?

Thanks

Best

---

<div class="post-metadata">

**Author:** ![alikins](https://avatars.discourse-cdn.com/v4/letter/a/d07c76/32.png) [@alikins](https://forum.ansible.com/u/alikins)\
**Post date:** [July 26, 2016, 1:54pm UTC](https://forum.ansible.com/t/improving-default-output/22123/2 "2016-07-26T13:54:32Z")

</div>

> This is absolutely not readable.

Agreed 100%.

> I made a PR on openshift-ansible to override the output from the default  
> callback plugin: [https://github.com/openshift/openshift-ansible/pull/1861](https://github.com/openshift/openshift-ansible/pull/1861)
> 
> But now I'd like to contribute this upstream, basically the idea is that  
> with -v we get:
> 
> - indented json  
> - std{err,out} printed apart with proper newlines
> 
> What's your opinion ?

I agree.

> Is there anything to consider before I get started ?

- looks like skippy.py and actionable.py callbacks subclass  
default.CallbackModule, so they  
&nbsp;&nbsp;could be affected, though I didn't see anything obvious that would  
break so may not matter.

- possibly using escape\_decode() on output

When debugging, especially when attempting to reproduce bug reports  
with lots of v's (-vvvvv),  
I usually end up using some variant of:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg, \_ = codecs.escape\_decode(msg.encode('utf8'))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg = msg.decode()

in display.py:Display.display() to get a readable output, especially  
for errors that include a dict  
with a item in it with the traceback as a string. (For example in  
context, the wip pr at  
[https://github.com/ansible/ansible/pull/16649/files](https://github.com/ansible/ansible/pull/16649/files) includes this so  
that error messages from  
ssh are displayed in a readable fashion.  
[https://github.com/ansible/ansible/pull/16649#issuecomment-231431899](https://github.com/ansible/ansible/pull/16649#issuecomment-231431899)  
has  
some examples)

At least as a quick output prettifier, it seems to work. There may be  
lower level ways to avoid the need for that  
(likely involving more use of objects with custom repr()'s...)

- display callbacks could display more context info \_if\_ they track some state

The current default.py callback doesn't really keep any state (which  
playbook it is running, etc) and  
that is reasonable. A lot of that info does get passed to callbacks if  
you dig into the objects far enough.  
A callback could try to keep track of more of it (or alternative, the  
callback api gets revved to pass in more of it).

Two examples:  
&nbsp;&nbsp;&nbsp;- my 'stdlog\_callback' at  
[https://github.com/alikins/ansible/tree/stdlog\_callback](https://github.com/alikins/ansible/tree/stdlog_callback)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The main gist there is the callback uses stdlib logging, but to  
improve the output it also tries to track some  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state, so that it knows which playbooks are involved for  
including in the message. The code that tries to  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;figure that out isn't perfect yet, but its close enough to help  
me with debugging.

- the 'junit.py' callback in devel/

&nbsp;&nbsp;&nbsp;It has some similar state tracking code to keep track of which task  
is running.

&nbsp;&nbsp;Ideally, the callback wouldn't need to track any state to do that,  
but changing that likely means breaking or revving  
&nbsp;&nbsp;the version of the callback api.

alikins
