diff --git a/salt/client/mixins.py b/salt/client/mixins.py index eb391d8ec6..dcb7fc24e4 100644 --- a/salt/client/mixins.py +++ b/salt/client/mixins.py @@ -168,7 +168,7 @@ class SyncClientMixin(object): return ret['data']['return'] - def cmd(self, fun, arg=None, pub_data=None, kwarg=None): + def cmd(self, fun, arg=None, pub_data=None, kwarg=None, print_event=True): ''' Execute a function @@ -228,7 +228,7 @@ class SyncClientMixin(object): low = {'fun': fun, 'args': args, 'kwargs': kwargs} - return self.low(fun, low) + return self.low(fun, low, print_event) @property def mminion(self): @@ -236,7 +236,7 @@ class SyncClientMixin(object): self._mminion = salt.minion.MasterMinion(self.opts, states=False, rend=False) return self._mminion - def low(self, fun, low): + def low(self, fun, low, print_event=True): ''' Execute a function from low data Low data includes: @@ -272,12 +272,18 @@ class SyncClientMixin(object): opts=self.opts, listen=False) + if print_event: + print_func = self.print_async_event \ + if hasattr(self, 'print_async_event') \ + else None + else: + # Suppress printing of return event (this keeps us from printing + # runner/wheel output during orchestration). + print_func = None namespaced_event = salt.utils.event.NamespacedEvent( event, tag, - print_func=self.print_async_event - if hasattr(self, 'print_async_event') - else None + print_func=print_func ) # TODO: document these, and test that they exist # TODO: Other things to inject?? diff --git a/salt/modules/saltutil.py b/salt/modules/saltutil.py index add178a3f1..ca35f8eb74 100644 --- a/salt/modules/saltutil.py +++ b/salt/modules/saltutil.py @@ -1122,7 +1122,7 @@ def runner(name, **kwargs): if 'saltenv' in aspec.args: kwargs['saltenv'] = saltenv - return rclient.cmd(name, kwarg=kwargs) + return rclient.cmd(name, kwarg=kwargs, print_event=False) def wheel(name, *args, **kwargs): @@ -1191,7 +1191,8 @@ def wheel(name, *args, **kwargs): ret = wheel_client.cmd(name, arg=args, pub_data=pub_data, - kwarg=valid_kwargs) + kwarg=valid_kwargs, + print_event=False) except SaltInvocationError: raise CommandExecutionError( 'This command can only be executed on a minion that is located on ' diff --git a/salt/output/highstate.py b/salt/output/highstate.py index 9f4193bf7b..1828534ad3 100644 --- a/salt/output/highstate.py +++ b/salt/output/highstate.py @@ -208,7 +208,8 @@ def _format_host(host, data): .format(ret.get('duration', 0))) tcolor = colors['GREEN'] - schanged, ctext = _format_changes(ret['changes']) + orchestration = ret.get('__orchestration__', False) + schanged, ctext = _format_changes(ret['changes'], orchestration) nchanges += 1 if schanged else 0 # Skip this state if it was successful & diff output was requested @@ -461,15 +462,37 @@ def _format_host(host, data): return u'\n'.join(hstrs), nchanges > 0 -def _format_changes(changes): +def _nested_changes(changes): ''' - Format the changes dict based on what the data is + Print the changes data using the nested outputter ''' global __opts__ # pylint: disable=W0601 + opts = __opts__.copy() + # Pass the __opts__ dict. The loader will splat this modules __opts__ dict + # anyway so have to restore it after the other outputter is done + if __opts__['color']: + __opts__['color'] = u'CYAN' + __opts__['nested_indent'] = 14 + ret = u'\n' + ret += salt.output.out_format( + changes, + 'nested', + __opts__) + __opts__ = opts + return ret + + +def _format_changes(changes, orchestration=False): + ''' + Format the changes dict based on what the data is + ''' if not changes: return False, u'' + if orchestration: + return True, _nested_changes(changes) + if not isinstance(changes, dict): return True, u'Invalid Changes data: {0}'.format(changes) @@ -483,18 +506,7 @@ def _format_changes(changes): changed = changed or c else: changed = True - opts = __opts__.copy() - # Pass the __opts__ dict. The loader will splat this modules __opts__ dict - # anyway so have to restore it after the other outputter is done - if __opts__['color']: - __opts__['color'] = u'CYAN' - __opts__['nested_indent'] = 14 - ctext = u'\n' - ctext += salt.output.out_format( - changes, - 'nested', - __opts__) - __opts__ = opts + ctext = _nested_changes(changes) return changed, ctext diff --git a/salt/runner.py b/salt/runner.py index b9f30b1609..8054879960 100644 --- a/salt/runner.py +++ b/salt/runner.py @@ -119,6 +119,16 @@ class RunnerClient(mixins.SyncClientMixin, mixins.AsyncClientMixin, object): reformatted_low = self._reformat_low(low) return mixins.SyncClientMixin.cmd_sync(self, reformatted_low, timeout) + def cmd(self, fun, arg=None, pub_data=None, kwarg=None, print_event=True): + ''' + Execute a function + ''' + return super(RunnerClient, self).cmd(fun, + arg, + pub_data, + kwarg, + print_event) + class Runner(RunnerClient): ''' diff --git a/salt/states/saltmod.py b/salt/states/saltmod.py index 42e8dc6a4c..a367ac1ed8 100644 --- a/salt/states/saltmod.py +++ b/salt/states/saltmod.py @@ -598,6 +598,7 @@ def runner(name, **kwargs): ret['result'] = True ret['comment'] = "Runner function '{0}' executed.".format(name) + ret['__orchestration__'] = True if out: ret['changes'] = out @@ -630,6 +631,7 @@ def wheel(name, **kwargs): ret['result'] = True ret['comment'] = "Wheel function '{0}' executed.".format(name) + ret['__orchestration__'] = True if out: ret['changes'] = out diff --git a/salt/wheel/__init__.py b/salt/wheel/__init__.py index fab13b9d81..57e9318cae 100644 --- a/salt/wheel/__init__.py +++ b/salt/wheel/__init__.py @@ -112,7 +112,7 @@ class WheelClient(mixins.SyncClientMixin, mixins.AsyncClientMixin, object): fun = low.pop('fun') return self.async(fun, low) - def cmd(self, fun, arg=None, pub_data=None, kwarg=None): + def cmd(self, fun, arg=None, pub_data=None, kwarg=None, print_event=True): ''' Execute a function @@ -121,7 +121,11 @@ class WheelClient(mixins.SyncClientMixin, mixins.AsyncClientMixin, object): >>> wheel.cmd('key.finger', ['jerry']) {'minions': {'jerry': '5d:f6:79:43:5e:d4:42:3f:57:b8:45:a8:7e:a4:6e:ca'}} ''' - return super(WheelClient, self).cmd(fun, arg, pub_data, kwarg) + return super(WheelClient, self).cmd(fun, + arg, + pub_data, + kwarg, + print_event) Wheel = WheelClient # for backward-compat diff --git a/tests/unit/states/saltmod_test.py b/tests/unit/states/saltmod_test.py index 9406ba3bca..9374f20e33 100644 --- a/tests/unit/states/saltmod_test.py +++ b/tests/unit/states/saltmod_test.py @@ -171,7 +171,8 @@ class SaltmodTestCase(TestCase): name = 'state' ret = {'changes': True, 'name': 'state', 'result': True, - 'comment': "Runner function 'state' executed."} + 'comment': 'Runner function \'state\' executed.', + '__orchestration__': True} with patch.dict(saltmod.__salt__, {'saltutil.runner': MagicMock(return_value=True)}): @@ -186,7 +187,8 @@ class SaltmodTestCase(TestCase): name = 'state' ret = {'changes': True, 'name': 'state', 'result': True, - 'comment': "Wheel function 'state' executed."} + 'comment': 'Wheel function \'state\' executed.', + '__orchestration__': True} with patch.dict(saltmod.__salt__, {'saltutil.wheel': MagicMock(return_value=True)}):