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

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

做这个的最好方式是什么?

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

Erik Hollensbe 在2013年写了一篇很好的文章

现在,答案是:

由于厨师食谱是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软件包的软件包pipe理器,所以我们返回。

如果你想中止厨师完全运行

还有一些其他的事情可以做。 如果厨师在任何地方遇到未处理的exception,厨师将退出。 例如,如果一个模板资源找不到它的源文件,或者如果运行Chef的用户没有权限做类似make的目录。 这就是为什么使用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上有一个包pipe理器,我们希望安装这个包。 加注将导致厨师致命退出并给予堆栈跟踪。

另一种方法是使用Chef::Application.fatal! 。 这将fatal消息logging到厨师logging器和STDERR,并退出应用程序。 你也可以给它一个返回码(也许你有一个脚本检查这些?)。

 Chef::Application.fatal!("Didn't expect the Spanish Inquistion", 42) if spanish_inquisition 

(当然spanish_inquisition通常是零,因为没有人期望…我离题了…)

这将导致Chef退出,发送日志消息以及来自进程的返回码42。

注意 :这会导致整个应用程序退出,这意味着如果它作为守护程序服务运行,它将终止,并且取决于服务的pipe理方式,它可能会或可能不会再次启动。 例如,一个init.d服务将不会重新启动,但一个runit服务将会。

由于食谱是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 Server上的数据包发出HTTP请求,如果服务器出现问题(404未find,403未经授权等),将返回Net::HTTPServerException 。 我们可能会尝试重试或者做其他的处理,然后再回来raise

报告错误

如果从命令行运行Chef,只需简单地退出和扔栈跟踪就可以了。 但是,如果你用cron或者几台甚至几十台甚至几百台机器来运行它,当出现问题的时候,这并不是一种保持健全的好方法。

input厨师的报告/exception处理程序function 。 您可以使用您的厨师运行处理程序。 所有报告处理程序都在Chef运行结束时运行。 exception处理程序在中止的Chef运行结束时运行。 跟踪运行状态,并可以在处理程序中进行检查,因此可以编写一个处理两种运行(成功/已完成或未成功/已中止)的运行。

文档告诉你如何写一个。 它还包括可用于各种服务的可用开源处理程序的列表,其中包括:

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

还有更多。

推荐的方法是中止或编辑Chef run,引发exception。 这是一个例子:

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

厨师:: 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 

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

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