Improving default output

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] => (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: '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: ‘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] => (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: '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: ‘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

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

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

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
  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:

        msg, _ = codecs.escape_decode(msg.encode('utf8'))
        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 includes this so
that error messages from
ssh are displayed in a readable fashion.
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:
   - my 'stdlog_callback' at
https://github.com/alikins/ansible/tree/stdlog_callback

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

- the 'junit.py' callback in devel/

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

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

alikins