Chef infra 如何在库模块中使用厨师资源?(或者我应该……)?

Chef infra 如何在库模块中使用厨师资源?(或者我应该……)?,chef-infra,chef-recipe,Chef Infra,Chef Recipe,我试图通过在助手库中收集常见的Ruby逻辑来更好地组织一些厨师食谱。我已经看到了在库中声明一个类的示例(即class Chef::Recipe::MyHelper),其中包含一些可重用的方法。我还看到过以类似方式使用模块的示例。在我的例子中,我想在其中一些方法中使用资源 例如,假设我想提供一个helper方法,该方法通过停止每个使用服务资源的服务名称和循环来获取一个服务名称数组。我想通过调用“stopServices(serviceList)”方法,尽可能多地清理配方文件,并保留一些逻辑 如果我

我试图通过在助手库中收集常见的Ruby逻辑来更好地组织一些厨师食谱。我已经看到了在库中声明一个类的示例(即class Chef::Recipe::MyHelper),其中包含一些可重用的方法。我还看到过以类似方式使用模块的示例。在我的例子中,我想在其中一些方法中使用资源

例如,假设我想提供一个helper方法,该方法通过停止每个使用服务资源的服务名称和循环来获取一个服务名称数组。我想通过调用“stopServices(serviceList)”方法,尽可能多地清理配方文件,并保留一些逻辑

如果我像以下那样定义帮助器库:

class Chef::Recipe::MyHelper
  def self.stopServices(serviceList)
    serviceList.each do |svc|
      service "#{svc}" do
        action :stop
      end
    end
  end
end
然后在我的食谱中,我使用:

MyHelper.stopServices(serviceList)
我得到错误:“Chef::Recipe::MyHelper:Class的未定义方法‘service’”

有没有一种简单的方法可以使用这样一个库中的资源?(库是否包含MyHelper作为类或模块)?这只是我违反的坏习惯吗?我已经做了很多搜索,没有发现任何人问类似的问题,这让我相信我可能在做一些我不应该做的事情,因此任何其他建议都将非常感谢。

是一种从食谱中提取复杂Ruby代码的方法

要对资源进行分组(Chef DSL代码),您应该使用

  • (最简单的选择),你可以像普通厨师一样在食谱中使用;或
  • 它们更复杂,但支持不同的操作(想想你可以
    服务
    资源:启动
    停止
    :重新启动
    ,等等;或者你可以
    资源:安装
    :升级
    :删除
    ,等等)

更新

可以解决示例问题的定义:

# cookbooks/common/definitions/common_stop_services.rb
define :common_stop_services, :services => [] do
  params[:services].each do |svc|
    service svc do
      action :stop
    end
  end
end
然后像这样使用它:

# my_cookbook/recipes/my_recipe.rb
common_stop_services "my_recipe_services" do
  services [ 'svc1', 'svc2' ]
end
Obs:如果你真的想用一种通用的方法来包装多个服务中断,那么问问你自己可能是值得的。通常,服务操作由其他资源通知(典型示例是配置文件更改,通知重新配置的服务重新启动,但其他模式也适用)

Obs2:CamelCase仅用于Ruby代码中的
模块
。我建议你读这本书


Obs3:即使要在库中实现该代码,也可能不想使用
类。您永远不会实例化
MyHelper
,因此您需要的是一个
模块

谢谢您的回复,我认为LWRPs是我长期的选择。在短期内,我仍然想知道我所尝试的是否可行。为了清理食谱,我将这些方法中的许多方法移动到“通用”食谱中的库文件中,并使其他需要它们的食谱依赖于该食谱。我没有费心将这些方法包装在类或模块中,它可以像上面那样写得很好,只是没有类行(和“self”)但仍然从库中的方法调用资源。我希望将其包装在一个类中作为最佳实践,以避免污染默认名称空间,并通过使用“MyHelper.stopServices”而不仅仅是“stopServices”,使该方法在其他配方中的来源更加明显。似乎唯一的问题是,当我将其包装到一个类中时,它假定服务资源是该类的一部分。因此,这看起来像是一个简单的名称空间问题,但我尝试过的任何方法都无法解决这一问题。是否有某种方法可以完全限定资源名称,或者以其他方式指定它是什么,以便以这种方式使用它?同样,您正在颠覆使用库来进行Chef DSL调用。通过声明一个类,而该类的名称并没有告诉您它来自何处(也许
Common
会是一个更好的名称,因为它与它的烹饪书相匹配?)。我编辑了我的答案,以演示如何实现问题的定义。我还添加了一些从长远来看可以帮助您的观察结果。谢谢,我很欣赏这个例子。我显然有很多东西要学,但这个定义很有帮助。我将研究如何更好地使用LWRP,并通知需要停止/启动的服务资源。