你怎么能让一个盐执行模块在失败时返回一个非零的退出码

我试图使用jenkins运行一个盐执行模块命令; 如果任何仆从未能执行命令,我希望Jenkins作业失败。 jenkins只是遵循一般shell脚本实践失败的非零退出代码,所以使其工作盐也应该。

这就是我卡住的地方,运行像这样的预期工作:

root@salt-master:~# salt --batch-size 1 --failhard -G 'ec2_roles:stage' cmd.run 'exit 0' Executing run on ['stage-12'] jid: 20170209212325270060 retcode: 0 stage-12: Executing run on ['stage-13'] jid: 20170209212325423735 retcode: 0 stage-13: Executing run on ['stage-197'] jid: 20170209212325590982 retcode: 0 stage-197: root@salt-master:~# echo $? 0 root@salt-master:~# salt --batch-size 1 --failhard -G 'ec2_roles:stage' cmd.run 'exit 1' Executing run on ['stage-12'] {'stage-12': {'jid': '20170209212334018054', 'retcode': 1, 'ret': ''}} ERROR: Minions returned with non-zero exit code. root@salt-master:~# echo $? 1 

但是当我尝试像下面的testing运行一个执行模块:

 # mymodule.py from salt.exceptions import CommandExecutionError def testfailure(): raise CommandExecutionError('fail!') 

我得到以下结果:

 root@salt-master:~# salt --batch-size 1 --failhard -G 'ec2_roles:stage' mymodule.testfailure Executing run on ['stage-12'] jid: 20170210023059009796 stage-12: ERROR: fail! Executing run on ['stage-13'] jid: 20170210023059179183 stage-13: ERROR: fail! Executing run on ['stage-197'] jid: 20170210023059426845 stage-197: ERROR: fail! root@salt-master:~# echo $? 0 

我不知道你是如何处理你的模块中的错误,但无论如何,我想说明一下。

有一个dunder字典__context__ 。 在运行执行模块时, __context__字典在所有模块执行中保持__context__直到模块被刷新。 状态模块的行为相似。 字典可以为一个关键的'retcode' ,这似乎是指返回代码salt minion /客户端应该返回和你失踪。

我可以看到它在一些执行模块中使用。 nspawn模块的一个例子:

 def _make_container_root(name): ''' Make the container root directory ''' path = _root(name) if os.path.exists(path): __context__['retcode'] = salt.defaults.exitcodes.SALT_BUILD_FAIL raise CommandExecutionError( 'Container {0} already exists'.format(name) ) else: try: os.makedirs(path) return path except OSError as exc: raise CommandExecutionError( 'Unable to make container root directory {0}: {1}' .format(name, exc) 

现在,坏事。 我testing了它在旧的SaltStack 2015.8.12,它以某种方式工作,但没有使用exception:

 def testfailure(): __context__['retcode'] = 1 

执行模块返回高于0错误代码:

  salt my_minion mymodule.testfailure; echo $? my_minion: None ERROR: Minions returned with non-zero exit code 11 

当你引发一个exception时,它停止工作,它总是返回0

 # mymodule.py from salt.exceptions import CommandExecutionError def testfailure(): __context__['retcode'] = 1 raise CommandExecutionError('fail') 

执行模块返回错误代码等于0但它不应该:

 salt my_minion mymodule.testfailure; echo $? my_minion: ERROR: fail! 0 

我还testing了最新的可用版本2016.11.3,并且行为是相同的。 国际海事组织,这是一个错误。 我在这里汇报

AFAIK退出代码是Salt的一个普遍问题。 有关这个问题的Github bug跟踪器中有一套门票。 find盐州是否成功应用的最好方法我见过的就是盐厨所使用的 。 简而言之,salt命令只是一个简单的包装器,可以输出特定的消息。 grep命令如下:

 grep -e Result.*False -e Data.failed.to.compile -e No.matching.sls.found.for 

在你的情况下,你也可以添加匹配stringERROR: 。 当find匹配项时,您可能还需要反转grep的退出代码,因为它是0 。 你可以用这个问题中解释的一个简单的技巧做到这一点 。 所以最后你的盐命令可能看起来像:

 salt <your options go here> | tee grep -q -e Result.*False -e Data.failed.to.compile -e No.matching.sls.found.for -e ERROR: ; test $? -eq 1 

这将显示salt的全部输出,如果find任何错误消息,则抑制grep输出并返回grep含义1的反向返回代码,如果不是,则返回0

对于任何人仍然试图解决这个问题,你可以做到以下几点:

salt * state.highstate --retcode-passthrough

要么

salt-call * state.highstate --retcode-passthrough