在厨师食谱中做一点烘干的最好方法是什么?也就是说,只是打破了Ruby代码的一小部分,所以我不会一遍又一遍地复制粘贴它。
当然,下面的代码会失败,因为:
NoMethodError: undefined method `connect_root' for Chef::Resource::RubyBlock我可能在一个配方中有多个ruby_blocks,因为它们做不同的事情,需要有不同的not_if块才能成为真正的幂等块。
def connect_root(root_password)
m = Mysql.new("localhost", "root", root_password)
begin
yield m
ensure
m.close
end
end
ruby_block "set readonly" do
block do
connect_root node[:mysql][:server_root_password] do |connection|
command = 'SET GLOBAL read_only = ON'
Chef::Log.info "#{command}"
connection.query(command)
end
end
not_if do
ro = nil
connect_root node[:mysql][:server_root_password] do |connection|
connection.query("SELECT @@read_only as ro") {|r| r.each_hash {|h|
ro = h['ro']
} }
end
ro
end
end发布于 2013-03-28 04:38:43
正如您已经了解到的,您不能在配方中定义函数。为此,提供了库。您应该在您的食谱中的库文件夹中创建一个包含以下内容的文件(例如mysql_helper.rb ):
module MysqlHelper
def self.connect_root( root_password )
m = Mysql.new("localhost", "root", root_password)
begin
yield m
ensure
m.close
end
end
endIt 必须是一个模块,而不是一个类。另请注意,我们将其定义为静态(使用self.method_name)。然后,您将能够使用模块名称和方法名称在您的配方中使用此模块中定义的函数:
MysqlHelper.connect_root node[:mysql][:server_root_password] do |connection|
[...]
end发布于 2013-03-24 13:02:46
根据记录,我刚刚创建了一个包含以下内容的库。但对于一个文件中的DRY来说,这似乎有点过头了。我也不知道如何让模块使用其他的命名空间来工作。
class Chef
class Resource
def connect_root(root_password)
...https://stackoverflow.com/questions/15595144
复制相似问题