Xia*_*ing 15 cookbook chef-infra
我正在开发一本食谱来部署一个简单的ROR应用程序.我写了一个app_helper.rb并把它放到我的cookbook的libraries目录中,这里是内容:
module AppHelper
def self.find_gem
if File.exists?("/usr/local/rvm/bin/rvm")
return `/usr/local/rvm/bin/rvm default exec which gem`.chomp
else
return "/usr/bin/gem"
end
end
end
Run Code Online (Sandbox Code Playgroud)
在recipes/default.rb中,我将上面的模块混合到Chef :: Recipe类中
class Chef::Recipe
include AppHelper
end
Run Code Online (Sandbox Code Playgroud)
如您所知,可以从配方的任何位置调用find_gem函数.
当我试图在我的ruby_block中使用find_gem函数时,如下所示:
ruby_block "find gem" do
block do
gem_bin = Chef::Recipe::find_gem
# or gem_bin = find_gem
end
end
Run Code Online (Sandbox Code Playgroud)
我得到了一个NoMethodError:未定义的方法'find_gem'.
还尝试将模块混合到Chef :: Resource :: RubyBlock中,它既不起作用也不起作用.
class Chef::Resource::RubyBlock
include AppHelper
end
ruby_block "find gem" do
block do
gem_bin = Chef::Resource::RubyBlock::find_gem
# or gem_bin = find_gem
end
end
Run Code Online (Sandbox Code Playgroud)
有没有办法从ruby_block调用模块中的函数?或者是否有一个厨师变量来定位库中的文件,以便我能够在ruby_block中需要该模块.
谢谢!
set*_*rgo 17
根据加载顺序,您可能会将模块包含在匿名的Ruby类中,而不是您的想法.
如果要在配方中使用方法,请在配方顶部执行此操作:
include AppHelper
Run Code Online (Sandbox Code Playgroud)
您也可以:send在库的末尾使用:
Chef::Recipe.send(:include, AppHelper)
Run Code Online (Sandbox Code Playgroud)
这是不同的,因为如果Chef::Recipe没有定义它将引发异常(而如果它不存在则创建一个新类).
除非你想使用帮助器not_if和only_if防护装置,否则你需要做的就是这一切.然后,您需要在资源中包含帮助程序:
Chef::Resource.send(:include, AppHelper)
Run Code Online (Sandbox Code Playgroud)
好的,既然我解释了所有这些,它实际上对你没有帮助.Ruby Block提供程序只是调用块 - 它不会实例化它.因此,在资源中包含帮助程序不会做任何事情.
因此,在这个实例中你需要使用单例对象(这是我能够可靠地想到的唯一解决方案).您定义方法的方式,可以直接从全局命名空间调用它:
AppHelper.find_gem('...')
Run Code Online (Sandbox Code Playgroud)
所以:
ruby_block "find gem" do
block do
gem_bin = AppHelper.find_gem('...')
end
end
Run Code Online (Sandbox Code Playgroud)