我试图使用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