【问题标题】:Abort Chef recipe at run time not during compilation在运行时而不是在编译期间中止 Chef 配方
【发布时间】:2014-12-23 00:43:04
【问题描述】:

我想根据特定条件在运行时中止配方,但使用 raiseChef::Application.fatal!,如本文@987654321 中所述@我的配方仅在编译时退出。

这是我正在尝试的(我的脚本的一部分):

execute "Execute somehthing" do
  cwd node['abc']['dir']
  command "something >> #{results}"
  node.default['success'] = "false"
  notifies :run, "ruby_block[jobFailure]", :delayed
  not_if "cd #{node['abc']['dir']} && somecommand >> #{results}"
end

ruby_block "jobFailure" do
  raise "Exiting the script as the job has failed" if (node.default['success'] == "false")
  action :nothing
end

但是在运行上述脚本时,我收到了错误,因为 Chef 在编译时退出,只给出以下错误:

Running handlers:
[2014-10-27T17:17:03+00:00] ERROR: Running exception handlers
Running handlers complete
[2014-10-27T17:17:03+00:00] ERROR: Exception handlers complete
[2014-10-27T17:17:03+00:00] FATAL: Stacktrace dumped to c:/Users/manish.a.joshi/
.chef/local-mode-cache/cache/chef-stacktrace.out
Chef Client failed. 0 resources updated in 12.400772 seconds
[2014-10-27T17:17:03+00:00] FATAL: RuntimeError: Exiting the script as the job has failed

谁能告诉我是否有办法只根据条件执行 raise 命令?

【问题讨论】:

  • 不清楚你的情况。您能否编辑您的问题以澄清您正在检查的条件是什么?

标签: continuous-integration chef-infra


【解决方案1】:

所以首先,Chef 不会像这样工作,这段代码无论如何也不会像你期望的那样工作,但你必须将代码放在 ruby​​_block 的实际块中:

ruby_block "jobFailure" do
  block do
    raise "Exiting the script as the job has failed" if (node.default['success'] == "false")
  end
  action :nothing
end

无论命令的状态如何,您在执行资源中的node.default['success'] = "false" 都会发生,并且会在编译时发生。 Chef 资源没有这种方式的返回值。

【讨论】:

  • 您可以将 only_if 添加到 job_failure ruby_block 并在那里测试您的成功条件。
  • 这不会改变任何事情,执行资源的成功或失败不是您可以轻松地与另一个资源进行通信的事情。如果执行资源失败,Chef 将中止。做这种事情一般需要写一个LWRP,直接使用shell_out。
  • 我很清楚,但我不认为 OP 打算这样做。我的印象是退出条件和执行结果是两个不同的东西。当“条件”仍然失败时,执行可能会成功。如果是这种情况,那么可以将条件作为 ruby​​ 块上的条件进行测试。
  • 上面的答案对我有用。因为我正在执行的命令是“some command”>>“output.file”所以即使命令由于某种原因失败它也会被捕获在输出中文件,但厨师不会像厨师一样退出,命令是将结果放入输出文件中。然后基于执行块,我在厨师食谱的末尾执行raise,因为我知道如果执行块由厨师运行,则意味着其中的 not_if 命令失败,因此我需要中止我的脚本.. . 感谢@coderanger的回答
【解决方案2】:

听起来你只想在你的条件失败时执行你的execute 块。如果是这种情况,您可以使用单一资源来完成这两项任务。

execute "Execute somehthing" do
  cwd node['abc']['dir']
  command "something >> #{results} && exit 1"
  node.default['success'] = "false"
  notifies :run, "ruby_block[jobFailure]", :delayed
  not_if "cd #{node['abc']['dir']} && somecommand >> #{results}"
end

添加&& exit 1 将导致execute 资源失败,从而终止厨师运行。

当然,这仅在您想立即终止时才有效。您当前的代码使用:delayed 通知,这意味着您的厨师运行将继续,直到所有资源都已执行,然后在延迟通知期间失败。这可能也可能不是您想要的。

如果你真的想在通知期间终止,那么试试这个(注意设置节点属性没有帮助)

execute "Execute somehthing" do
  cwd node['abc']['dir']
  command "something >> #{results}"
  notifies :run, "ruby_block[jobFailure]", :delayed
  not_if "cd #{node['abc']['dir']} && somecommand >> #{results}"
end

ruby_block "jobFailure" do
  block
    raise "Exiting the script as the job has failed"
  action :nothing
end

【讨论】:

  • 谢谢,我真的很想在所有厨师资源运行后终止会话,因此我使用了:delayed,但我喜欢你使用&& exit 1; 的想法,因为在我的另一个如果条件失败但它不起作用,我试图使用:immediately 立即调用 ruby​​ 部分.. 似乎是一个不同的问题,但你知道为什么immediately 没有立即调用 ruby​​ 块,而是仅在结尾很像delayed
  • 我需要更多信息。没有理由不立即发出 :immediate 通知。
猜你喜欢
  • 2014-11-16
  • 1970-01-01
  • 2011-10-27
  • 2012-12-26
  • 1970-01-01
  • 2020-10-19
  • 2020-02-14
  • 1970-01-01
  • 2015-04-08
相关资源
最近更新 更多