2013-08-20 115 views
2

我正在研究厨师食谱,我需要根据代码的结果更新数据包中的某些信息。基本上我需要更新一个成功或失败的数据包。如何捕捉厨师异常

的代码看起来是这样的:

begin 
    node[:fileDeploy].each do |f| 
     if f[:deploy] 
      cookbook_file "#{f[:subdirectory]}/#{f[:targetFilename]}" do 
      owner users['tomcatUser'] 
      group users['tomcatGroup'] 
      mode "0755" 
      cookbook node[:cookbookName] 
      source "#{f[:sourceFilename]}" 
      end 
     end 
    end 
    # Update data bag: succeeded 
rescue Chef::Exceptions::FileNotFound => e 
    # Update data bag: failed 
end 

的问题是,即使有文件丢失,救援块不excecuted和数据包不会随之更新。 因此,当我在服务器上运行命令sudo chef-client时,它将以异常Chef::Exceptions::FileNotFound结束,但它不会由rescue块处理。是否有意义?任何帮助?

+0

您能否提供有关导致错误的信息。这可以帮助我们帮助您处理代码。 – screenmutt

回答

4

您的救援块没有捕获异常,因为引发异常的代码未在异常处理程序的作用域中执行。

在您的代码中,您声明了一个cookbook_file资源。声明进行得很好,资源被安排在收敛阶段执行。您的救援块可能会捕获在资源声明期间发生的异常,而不是实际执行的异常。

请参阅About the chef-client Run了解更多关于厨师跑的两个阶段,即资源收集的生成和后期收敛。

现在,您可以在收敛期间检查源文件存在的条件并据此做出相应决定。

一般来说,厨师的处理错误相当困难。这是设计的,因为您通常应该设计您的系统,使其与其他部分相对独立。因此,如果您需要目录或文件存在,则应该使用适当的资源明确创建该目录或文件。然后,您可以使用notifications通知其他资源在当前资源“已更改”(无论对于特定资源如何)中运行某个操作。

下面的代码试图实现类似于你显然想要的东西。在融合期间,它仍然没有发现异常,但试图不首先提出异常,但检查所需的条件并运行适当的资源。

node[:fileDeploy].each do |f| 
    if f[:deploy] 
    cookbook_file "#{f[:subdirectory]}/#{f[:targetFilename]}" do 
     owner users['tomcatUser'] 
     group users['tomcatGroup'] 
     mode "0755" 
     cookbook node[:cookbookName] 
     source f[:sourceFilename] 
     only_if{ Dir.exist?(File.base_name(f[:sourceFilename]) } 
     notifies :run, "execute[success #{f[:sourceFilename]}]", :immediately 
    end 

    # This one gets notified (and run) when the cookbook_file is successful 
    execute "success #{f[:sourceFilename]}" do 
     action :nothing 
     command "do whatever you like" 
    end 

    # This one runs only if f[:sourceFilename] doesn't exist by now 
    execute "error #{f[:sourceFilename]}" do 
     action :run 
     command "do whatever you like" 
     creates f[:sourceFilename] 
    end 
    end 
end 
+0

这几乎是我需要的答案,但资源执行“error#{f [:sourceFilename]}”每次都在执行。一旦它完成检查文件,资源执行“错误....”正在执行,因为它的动作是“运行”。有没有办法控制它并避免这种行为?是否有意义? –

+0

尽管该动作确实开始运行,但它并没有做任何事情,因为它所做的第一件事是检查标记文件是否存在(即在'creates'属性中指定的文件)。如果该文件存在,则该操作被中止。您可以通过运行带有调试日志级别的厨师来验证这一点,因为它会在调试时记录一条消息,如果它由于标记文件存在而中止“运行”操作。 –