0

以下のコードは期待どおりに動作し、次の結果を生成します。

==> default: foo_definition: a
==> default: foo_definition: foo
==> default: foo_definition: fiz
==> default: bar_definition: b
==> default: bar_definition: bar
==> default: bar_definition: biz

クックブック/foobar/recipes/default.rb:

node.default[:configs][:a][:def_name] = 'foo_name'
node.default[:configs][:a][:message] = 'fiz'
node.default[:configs][:b][:def_name] = 'bar_name'
node.default[:configs][:b][:message] = 'biz'

#def_map = {
#       'foo_name' => foo_definition,
#       'bar_name' => bar_definition
#}

for config_name in node[:configs].keys do
        def_name = node[:configs][config_name][:def_name]

        if def_name == 'foo_name'
                foo_definition config_name do
                        config_name config_name
                end
        elsif def_name == 'bar_name'
                bar_definition config_name do
                        config_name config_name
                end
        else
                raise Exception('Unknown def #{def_name}')
        end
end

クックブック/foobar/definitions/default.rb:

define :foo_definition, :config_name => nil do
        config_name = params[:config_name]
        print("foo_definition: #{config_name}")
        print("foo_definition: #{node[:configs][config_name][:def_name]}")
        print("foo_definition: #{node[:configs][config_name][:message]}")
end

define :bar_definition, :config_name => nil do
        config_name = params[:config_name]
        print("bar_definition: #{config_name}")
        print("bar_definition: #{node[:configs][config_name][:def_name]}")
        print("bar_definition: #{node[:configs][config_name][:message]}")
end

ハッシュを使用して、構成で指定された特定の定義を検索したいと思います。しかし、def_map のコメントを外すと、Chef は次のように文句を言います。

==> default: NoMethodError
==> default: -------------
==> default: undefined method `[]' for nil:NilClass
==> default: 
==> default: 
==> default: Cookbook Trace:
==> default: ---------------
==> default: /tmp/vagrant-chef/2e4e554824398d9416eee0b4bd47e8b9/cookbooks/foobar/definitions/default.rb:4:in 'block in from_file'

理由を説明できる人はいますか?

最終的には、レシピで次のようなことができるようにしたいと考えています。

node.default[:configs][:a][:def_name] = 'foo_name'
node.default[:configs][:a][:message] = 'fiz'
node.default[:configs][:b][:def_name] = 'bar_name'
node.default[:configs][:b][:message] = 'biz'

def_map = {
        'foo_name' => foo_definition,
        'bar_name' => bar_definition
}

for config_name in node[:configs].keys do
        def_name = node[:configs][config_name][:def_name]
        if def_map.key?(def_name)
                named_def = def_map[def_name]
                named_def config_name do
                        config_name config_name
                end
        else
                raise Exception('Unknown def #{def_name}')
        end
end
4

1 に答える 1

1

あなたの定義は :config_name という名前の引数を取ります

define :foo_definition, :config_name => nil do

そして、あなたは引数なしでそれを呼び出しますdef_map:

 'foo_name' => foo_definition,

したがって、定義がそこで(マップ内で)呼び出されると、config_nameはnilになり、この行

print("foo_definition: #{node[:configs][config_name][:def_name]}")

は次のように呼ばれます:

print("foo_definition: #{node[:configs][nil][:def_name]}")

回避策は、この種のコードを使用することです (テストされていません)。

for config_name in node[:configs].keys do
        def_name = node[:configs][config_name][:def_name]
        send(def_name) config_name do
                        config_name config_name
        end
end

定義がレシピ コンテキストで不明な場合、これにより例外が発生します。実行を中止せずにログに記録するだけの場合は、try/catch ブロックでラップすることができます。

于 2015-11-05T13:25:55.187 に答える