你如何中止/结束厨师运行?

时间:2013-01-12 04:59:51

标签: chef continuous-deployment

在某些情况下,我需要中止/结束一个非零状态代码的Chef运行,然后通过我们的部署链传播回来,最终传给Jenkins,导致一个巨大的红色球。

最好的方法是什么?

5 个答案:

答案 0 :(得分:108)

对于将来可能不熟悉Chef的问题和答案的读者,Chef会运行“收敛”节点,或者使其符合正在运行的配方中声明的策略。这也称为“收敛”。这有两个阶段,“编译”和“执行”。编译阶段是Chef评估(“编译”)食谱的Ruby代码,寻找要添加到资源集合的资源。完成后,它会“执行”每个资源的操作,使其进入所需的状态。系统命令运行等。

Erik Hollensbe写了一篇优秀的来了解how this works in 2013

现在,答案是:

有几种方法可以结束Chef运行,或退出Chef食谱,具体取决于你想要的方式,因为Chef食谱是Ruby代码。

如果您的目标是根据条件停止处理配方,但继续运行其余部分,则使用return Ruby关键字。例如:

file '/tmp/ponies' do
  action :create
end

return if node['platform'] == 'windows'

package 'bunnies-and-flowers' do
  action :install
end

我们假设如果系统是Windows,它没有可以安装bunnies-and-flowers包的包管理器,所以我们从那里返回。

如果您希望完全取消Chef的运行

Tl; dr:使用raise。如果出现错误,最好在中止Chef运行。

也就是说,如果在运行中的任何地方遇到未处理的异常,那么chef-client会退出。例如,如果模板资源找不到其源文件,或者运行chef-client的用户没有权限执行诸如创建目录之类的操作。这就是为什么使用raise也可以用来结束运行。

你把raise问题放在哪里。如果在ruby_block资源中使用它,它将仅在收敛的执行阶段引发。如果您在上述return示例之外的资源之外使用它,它将在编译阶段发生。

file '/tmp/ponies' do
  action :create
end

raise if node['platform'] == 'windows'

package 'bunnies-and-flowers' do
  action :install
end

也许我们在Windows上有一个包管理器,我们希望安装这个包。加薪将导致厨师致命退出并给出堆栈跟踪。

在过去的几年里,另一种方法是使用Chef::Application.fatal! - 正如我在这个答案中所写的那样。时间已经改变,这是 NOT RECOMMENDED 。不要再这样做了。如果您正在这样做,请切换到raise,如上所述,如果您的需求更复杂,请编写您自己的异常处理程序(请参阅下文)。

更优雅的错误处理

由于配方是Ruby,您还可以使用begin..rescue块优雅地处理错误条件。

begin
  dater = data_bag_item(:basket, "flowers")
rescue Net::HTTPServerException
  # maybe some retry code here?
  raise "Couldn't find flowers in the basket, need those to continue!"
end

data_bag_item在Chef服务器上发出数据包的HTTP请求,如果服务器出现问题(404未找到,403未授权等),则返回Net::HTTPServerException。我们可能会尝试重试或进行其他处理,然后再回到raise

报告错误

如果您从命令行运行Chef,只需退出并抛出堆栈跟踪即可。但是,如果您在cron中运行它,或者作为一个守护程序在几台甚至几十台或几百台机器上运行,这不是一个在出现问题时保持理智的好方法。

输入Chef's report/exception handler feature。您可以为Chef运行使用处理程序。所有报告处理程序都在Chef运行结束时运行。异常处理程序在中止Chef运行结束时运行。跟踪运行的状态,并且可以在处理程序中进行检查,因此您可以编写一个处理两种运行(成功/完成或不成功/中止)的程序。

documentation告诉你如何写一个。它还包括可用于各种服务的可用open source handlers列表,包括:

  • 通过SMTP发送电子邮件
  • IRC
  • 石墨
  • HipChat

还有更多。

答案 1 :(得分:7)

中止或编辑Chef运行的推荐方法是引发异常。这是一个例子:

ruby_block "some tricky operation" do
  block do
    OperationFoo
    raise "Operation Foo Failed" if some_condition
  end
end

答案 2 :(得分:4)

厨师:: Application.fatal!应该做你想要的。以下是我们的代码库中可能有用的示例。

cipher = case key.length
    when 16 then "AES-128-ECB"
    when 24 then "AES-192-ECB"
    when 32 then "AES-256-ECB"
else
    Chef::Application.fatal!("AES Key must be 16, 24, or 32 characters in length but key #{key} has length of #{key.length}")
end

答案 3 :(得分:-2)

如果希望chef在某些操作后完成,请使用以下语句:

throw :end_client_run_early

它会在没有任何错误的情况下退出。

答案 4 :(得分:-4)

在厨师独奏期间做一个不干净的退出,试试这个:

bash 'exit' do
    code 'killall -9 chef-solo'
end