我试图通过在帮助程序库中收集常见的 Ruby 逻辑来更好地组织一些 Chef Recipe 。我已经看到在库中声明一个类(即类 Chef::Recipe::MyHelper)的示例,其中包含一些可重用的方法。我还看到了以类似方式使用模块的示例。就我而言,我想在其中一些方法中使用资源。
例如,假设我想提供一个辅助方法,它采用一组服务名称并循环使用服务资源停止每个服务名称。我想尽可能多地清理配方文件,并通过调用“stopServices(serviceList)”方法来保留一些逻辑。
如果我像这样定义帮助程序库:
class Chef::Recipe::MyHelper
def self.stopServices(serviceList)
serviceList.each do |svc|
service "#{svc}" do
action :stop
end
end
end
end
然后在我的 Recipe 中我使用:
MyHelper.stopServices(serviceList)
我收到错误消息:“Chef::Recipe::MyHelper:Class 的未定义方法‘服务’”。
有没有一种简单的方法可以像这样使用图书馆中的资源? (库是否包含 MyHelper 作为类或模块)?这只是我违反的一种不好的做法吗?我做了很多搜索,找不到任何人问类似的问题,这让我相信我可能正在做一些我不应该做的事情,所以任何替代建议也将不胜感激。
最佳答案
Libraries是一种从 Recipe Recipe 中抽象出复杂的 Ruby 代码的方法。
要对资源进行分组(Chef DSL 代码),您应该使用
service
可以使用的资源 :start
、 :stop
、 :restart
等;或 package
可以使用的资源 :install
、 :upgrade
、 :remove
, ETC)。 更新
可以解决您的示例问题的定义:
# 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 仅用于
Classes
和 Modules
在 Ruby 代码中。我建议阅读 style guide .Obs3:即使您要在库中实现该代码,您也可能不想使用
Class
.你永远不会实例化 MyHelper
, 所以你想要的是 Module
反而。
关于chef-infra - 如何在库模块中使用 Chef 资源? (或者我应该……)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23021159/