如何在厨师ruby_block中要求我的图书馆 [英] how to require my library in chef ruby_block

查看:62
本文介绍了如何在厨师ruby_block中要求我的图书馆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发用于部署简单ROR应用程序的食谱。我编写了一个app_helper.rb并将其放入我的食谱的库目录中,内容如下:

I'm developing a cookbook to deploy a simple ROR application. I write an app_helper.rb and put it into the libraries directory of my cookbook, here is the content:

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

在配方/default.rb中,我将上述模块混入Chef :: Recipe类

In the recipes/default.rb, I mix in the above module into Chef::Recipe class

class Chef::Recipe
  include AppHelper
end

如您所知,可以在配方的任何位置调用find_gem函数。

As you know, the find_gem function can be called from anywhere of the recipe.

当我尝试在自己的计算机中使用find_gem函数时ruby_block像这样:

when I'm trying to use the find_gem function in my ruby_block like this:

ruby_block "find gem" do
   block do
    gem_bin = Chef::Recipe::find_gem
    # or gem_bin = find_gem
  end
end

我有一个NoM ethodError:未定义的方法'find_gem'。

I got a NoMethodError: undefined method 'find_gem'.

也尝试将模块混入Chef :: Resource :: RubyBlock中,这两种方法都不起作用。

Also try to mix in the module into Chef::Resource::RubyBlock, it doesn't work neither.

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

有没有办法从ruby_block调用模块中的函数?或者是否有Chef的变量来在库中定位文件,以便我可以在ruby_block中要求该模块。

Is there any way to call the function in the module from the ruby_block? Or Is there an variable of chef to location the files in the libraries, so that I can be able to require the module in the ruby_block.

谢谢!

推荐答案

根据加载顺序,您可能会

Depending on load order, you might be including your module into an anonymous Ruby class instead of what you think.

如果要在配方中使用方法,请在配方顶部执行以下操作:

If you want to use your method in a recipe, do this at the top of your recipe:

include AppHelper

您也可以在库的末尾使用:send

You could alternatively use :send at the end of your library:

Chef::Recipe.send(:include, AppHelper)

这是不同的,因为它如果未定义 Chef :: Recipe (如果不存在则在创建新类),则将引发异常。

This is different because it will raise an exception if Chef::Recipe is not defined (whereas you are creating a new class if it doesn't exist).

这就是您需要做的,除非您想在 not_if only_if 中使用帮助器。守卫。然后,您需要在资源中包含帮助程序:

That's all you should need to do unless you want to use the helper in not_if and only_if guards. Then you need to include the helper in the resource:

Chef::Resource.send(:include, AppHelper)






好吧,既然我已经解释了所有这些,它将不会不能真正帮助您。 Ruby Block提供者只需调用该块-它不会实例评估它。因此,在资源中包含帮助程序不会做任何事情


Okay, now that I explained all of that, it won't actually help you. The Ruby Block provider simply calls the block - it doesn't instance eval it. So including the helper in the resource doesn't do anything.

因此,在这种情况下,您需要使用单例对象(这是我能可靠想到的唯一解决方案)。定义方法的方式可以直接从全局命名空间调用:

So, you'll need to use a singleton object in this instance (it's the only solution I can reliably think of). The way you've defined your method, you can call it directly from the global namespace:

AppHelper.find_gem('...')

所以:

ruby_block "find gem" do
  block do
    gem_bin = AppHelper.find_gem('...')
  end
end

这篇关于如何在厨师ruby_block中要求我的图书馆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆