web-dev-qa-db-ja.com

シェフRuby_blockで私のライブラリを要求する方法

単純なRORアプリケーションをデプロイするためのクックブックを開発しています。 app_helper.rbを作成し、クックブックのライブラリディレクトリに配置します。内容は次のとおりです。

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クラスにミックスします

class Chef::Recipe
  include AppHelper
end

ご存知のように、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

NoMethodError:undefined method'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

Ruby_blockからモジュール内の関数を呼び出す方法はありますか?または、Ruby_blockでモジュールを要求できるように、ライブラリ内のファイルを配置するchefの変数はありますか。

ありがとう!

15
Xiaoming

ロードの順序によっては、モジュールを、思っているものではなく、匿名のRubyクラスに含める場合があります。

レシピでメソッドを使用する場合は、レシピの上部で次のようにします。

include AppHelper

または、ライブラリの最後で:sendを使用することもできます。

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

これは、Chef::Recipeが定義されていない場合(存在しない場合は新しいクラスを作成する場合)に例外が発生するため、異なります。

not_ifおよびonly_ifガードでヘルパーを使用する場合を除いて、実行する必要があるのはこれだけです。次に、リソースにヘルパーを含める必要があります。

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

さて、私がそのすべてを説明したので、それは実際にはあなたを助けません。 Rubyブロックプロバイダーは単純に ブロックを呼び出す -インスタンス評価は行わないため、リソースにヘルパーを含めるはしません何もしません

したがって、このインスタンスではシングルトンオブジェクトを使用する必要があります(これが私が確実に考えることができる唯一のソリューションです)。メソッドを定義した方法で、グローバル名前空間から直接呼び出すことができます。

AppHelper.find_gem('...')

そう:

Ruby_block "find gem" do
  block do
    gem_bin = AppHelper.find_gem('...')
  end
end
17
sethvargo