diff --git a/salt/modules/aptpkg.py b/salt/modules/aptpkg.py index 8f8c7fffcc..581bd0c2e3 100644 --- a/salt/modules/aptpkg.py +++ b/salt/modules/aptpkg.py @@ -269,7 +269,8 @@ def latest_version(*names, **kwargs): cmd.extend(repo) out = __salt__['cmd.run_all'](cmd, output_loglevel='trace', - python_shell=False) + python_shell=False, + env={'LC_ALL': 'C', 'LANG': 'C'}) candidate = '' for line in out['stdout'].splitlines(): if 'Candidate' in line: diff --git a/salt/modules/gpg.py b/salt/modules/gpg.py index 3a2b85d483..c9d92985b3 100644 --- a/salt/modules/gpg.py +++ b/salt/modules/gpg.py @@ -819,7 +819,10 @@ def trust_key(keyid=None, if not fingerprint: if keyid: - key = get_key(keyid) + if user: + key = get_key(keyid, user=user) + else: + key = get_key(keyid) if key: if 'fingerprint' not in key: ret['res'] = False diff --git a/salt/states/service.py b/salt/states/service.py index 490ec431e2..668d123e5f 100644 --- a/salt/states/service.py +++ b/salt/states/service.py @@ -109,6 +109,9 @@ def _enable(name, started, result=True, **kwargs): ret['comment'] = exc.strerror return ret + # Set default expected result + ret['result'] = result + # Check to see if this minion supports enable if 'service.enable' not in __salt__ or 'service.enabled' not in __salt__: if started is True: @@ -147,10 +150,9 @@ def _enable(name, started, result=True, **kwargs): return ret if __salt__['service.enable'](name, **kwargs): - after_toggle_enable_status = __salt__['service.enabled'](name, - **kwargs) # Service has been enabled ret['changes'] = {} + after_toggle_enable_status = __salt__['service.enabled'](name, **kwargs) # on upstart, certain services like apparmor will always return # False, even if correctly activated # do not trigger a change @@ -168,16 +170,14 @@ def _enable(name, started, result=True, **kwargs): return ret # Service failed to be enabled + ret['result'] = False if started is True: - ret['result'] = False ret['comment'] = ('Failed when setting service {0} to start at boot,' ' but the service is running').format(name) elif started is None: - ret['result'] = False ret['comment'] = ('Failed when setting service {0} to start at boot,' ' but the service was already running').format(name) else: - ret['result'] = False ret['comment'] = ('Failed when setting service {0} to start at boot,' ' and the service is dead').format(name) return ret @@ -199,6 +199,9 @@ def _disable(name, started, result=True, **kwargs): ret['comment'] = exc.strerror return ret + # Set default expected result + ret['result'] = result + # is enable/disable available? if 'service.disable' not in __salt__ or 'service.disabled' not in __salt__: if started is True: @@ -213,8 +216,8 @@ def _disable(name, started, result=True, **kwargs): ' service {0} is dead').format(name) return ret - before_toggle_disable_status = __salt__['service.disabled'](name) # Service can be disabled + before_toggle_disable_status = __salt__['service.disabled'](name) if before_toggle_disable_status: # Service is disabled if started is True: @@ -240,8 +243,6 @@ def _disable(name, started, result=True, **kwargs): # Service has been disabled ret['changes'] = {} after_toggle_disable_status = __salt__['service.disabled'](name) - # Service has been disabled - ret['changes'] = {} # on upstart, certain services like apparmor will always return # False, even if correctly activated # do not trigger a change @@ -267,7 +268,6 @@ def _disable(name, started, result=True, **kwargs): ret['comment'] = ('Failed when setting service {0} to not start' ' at boot, but the service was already running' ).format(name) - return ret else: ret['comment'] = ('Failed when setting service {0} to not start' ' at boot, and the service is dead').format(name) @@ -368,12 +368,10 @@ def running(name, enable=None, sig=None, init_delay=None, **kwargs): ret.update(_enable(name, False, result=False, **kwargs)) elif enable is False: ret.update(_disable(name, False, result=False, **kwargs)) - else: - ret['comment'] = 'Started Service {0}'.format(name) - if enable is True: - ret.update(_enable(name, True, **kwargs)) - elif enable is False: - ret.update(_disable(name, True, **kwargs)) + return ret + + if init_delay: + time.sleep(init_delay) # only force a change state if we have explicitly detected them after_toggle_status = __salt__['service.status'](name) @@ -382,17 +380,27 @@ def running(name, enable=None, sig=None, init_delay=None, **kwargs): else: after_toggle_enable_status = True if ( - (before_toggle_enable_status != after_toggle_enable_status) or - (before_toggle_status != after_toggle_status) + (before_toggle_enable_status != after_toggle_enable_status) or + (before_toggle_status != after_toggle_status) ) and not ret.get('changes', {}): - ret['changes'][name] = func_ret + ret['changes'][name] = after_toggle_status + + if after_toggle_status: + ret['comment'] = 'Started Service {0}'.format(name) + else: + ret['comment'] = 'Service {0} failed to start'.format(name) + + if enable is True: + ret.update(_enable(name, after_toggle_status, result=after_toggle_status, **kwargs)) + elif enable is False: + ret.update(_disable(name, after_toggle_status, result=after_toggle_status, **kwargs)) if init_delay: - time.sleep(init_delay) ret['comment'] = ( '{0}\nDelayed return for {1} seconds' .format(ret['comment'], init_delay) ) + return ret @@ -423,7 +431,6 @@ def dead(name, enable=None, sig=None, **kwargs): # Check if the service is available try: if not _available(name, ret): - ret['result'] = True return ret except CommandExecutionError as exc: ret['result'] = False @@ -437,6 +444,8 @@ def dead(name, enable=None, sig=None, **kwargs): before_toggle_enable_status = __salt__['service.enabled'](name) else: before_toggle_enable_status = True + + # See if the service is already dead if not before_toggle_status: ret['comment'] = 'The service {0} is already dead'.format(name) if enable is True and not before_toggle_enable_status: @@ -445,12 +454,12 @@ def dead(name, enable=None, sig=None, **kwargs): ret.update(_disable(name, None, **kwargs)) return ret + # Run the tests if __opts__['test']: ret['result'] = None ret['comment'] = 'Service {0} is set to be killed'.format(name) return ret - # be sure to stop, in case we mis detected in the check func_ret = __salt__['service.stop'](name) if not func_ret: ret['result'] = False @@ -459,12 +468,8 @@ def dead(name, enable=None, sig=None, **kwargs): ret.update(_enable(name, True, result=False, **kwargs)) elif enable is False: ret.update(_disable(name, True, result=False, **kwargs)) - else: - ret['comment'] = 'Service {0} was killed'.format(name) - if enable is True: - ret.update(_enable(name, False, **kwargs)) - elif enable is False: - ret.update(_disable(name, False, **kwargs)) + return ret + # only force a change state if we have explicitly detected them after_toggle_status = __salt__['service.status'](name) if 'service.enabled' in __salt__: @@ -472,10 +477,23 @@ def dead(name, enable=None, sig=None, **kwargs): else: after_toggle_enable_status = True if ( - (before_toggle_enable_status != after_toggle_enable_status) or - (before_toggle_status != after_toggle_status) + (before_toggle_enable_status != after_toggle_enable_status) or + (before_toggle_status != after_toggle_status) ) and not ret.get('changes', {}): - ret['changes'][name] = func_ret + ret['changes'][name] = after_toggle_status + + # be sure to stop, in case we mis detected in the check + if after_toggle_status: + ret['result'] = False + ret['comment'] = 'Service {0} failed to die'.format(name) + else: + ret['comment'] = 'Service {0} was killed'.format(name) + + if enable is True: + ret.update(_enable(name, after_toggle_status, result=not after_toggle_status, **kwargs)) + elif enable is False: + ret.update(_disable(name, after_toggle_status, result=not after_toggle_status, **kwargs)) + return ret diff --git a/salt/utils/jinja.py b/salt/utils/jinja.py index 1775bf1cf6..19cf900cce 100644 --- a/salt/utils/jinja.py +++ b/salt/utils/jinja.py @@ -387,8 +387,8 @@ class SerializerExtension(Extension, object): def format_yaml(self, value, flow_style=True): yaml_txt = yaml.dump(value, default_flow_style=flow_style, Dumper=OrderedDictDumper).strip() - if yaml_txt.endswith('\n...\n'): - yaml_txt = yaml_txt[:len(yaml_txt-5)] + if yaml_txt.endswith('\n...'): + yaml_txt = yaml_txt[:len(yaml_txt)-4] return Markup(yaml_txt) def format_yaml_safe(self, value, flow_style=True): diff --git a/tests/unit/states/service_test.py b/tests/unit/states/service_test.py index 8bb036b587..5073c1dada 100644 --- a/tests/unit/states/service_test.py +++ b/tests/unit/states/service_test.py @@ -58,7 +58,10 @@ class ServiceTestCase(TestCase): 'result': True}, {'changes': {}, 'comment': 'The service salt is already running', - 'name': 'salt', 'result': True}] + 'name': 'salt', 'result': True}, + {'changes': 'saltstack', + 'comment': 'Service salt failed to start', 'name': 'salt', + 'result': True}] tmock = MagicMock(return_value=True) fmock = MagicMock(return_value=False) @@ -134,6 +137,22 @@ class ServiceTestCase(TestCase): ): self.assertDictEqual(service.running("salt", True), ret[4]) + with contextlib.nested( + patch.dict(service.__opts__, {'test': False}), + patch.dict( + service.__salt__, { + 'service.status': + MagicMock(side_effect=[False, False]), + 'service.enabled': + MagicMock(side_effect=[True, True]), + 'service.start': + MagicMock(return_value="stack")}), + patch.object( + service, '_enable', + MagicMock(return_value={'changes': 'saltstack'})) + ): + self.assertDictEqual(service.running("salt", True), ret[6]) + def test_dead(self): ''' Test to ensure that the named service is dead @@ -149,8 +168,8 @@ class ServiceTestCase(TestCase): 'comment': 'Service salt was killed', 'name': 'salt', 'result': True}, {'changes': {}, - 'comment': 'Service salt was killed', 'name': 'salt', - 'result': True}, + 'comment': 'Service salt failed to die', 'name': 'salt', + 'result': False}, {'changes': 'saltstack', 'comment': 'The service salt is already dead', 'name': 'salt', 'result': True}] @@ -176,6 +195,7 @@ class ServiceTestCase(TestCase): patch.object(service, '_enable', mock) ): self.assertDictEqual(service.dead("salt", True), ret[5]) + with contextlib.nested( patch.dict(service.__opts__, {'test': False}), patch.dict( @@ -203,7 +223,7 @@ class ServiceTestCase(TestCase): {'service.enabled': MagicMock(side_effect=[True, True, False]), 'service.status': - MagicMock(side_effect=[True, True, False]), + MagicMock(side_effect=[True, False, False]), 'service.stop': MagicMock(return_value="stack")}), patch.object( service, '_enable', diff --git a/tests/unit/templates/jinja_test.py b/tests/unit/templates/jinja_test.py index c09bdcec3c..8974f71f13 100644 --- a/tests/unit/templates/jinja_test.py +++ b/tests/unit/templates/jinja_test.py @@ -477,6 +477,12 @@ class TestCustomExtensions(TestCase): rendered = env.from_string('{{ dataset|yaml }}').render(dataset=dataset) self.assertEqual(dataset, yaml.load(rendered)) + def test_serialize_yaml_str(self): + dataset = "str value" + env = Environment(extensions=[SerializerExtension]) + rendered = env.from_string('{{ dataset|yaml }}').render(dataset=dataset) + self.assertEqual(dataset, rendered) + def test_serialize_python(self): dataset = { "foo": True,