【问题标题】:Chef/Ruby: Reference to Definition in HashChef/Ruby:参考哈希中的定义
【发布时间】:2015-11-05 10:38:09
【问题描述】:

以下代码按预期工作并产生以下内容:

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

cookbooks/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

cookbooks/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

【问题讨论】:

    标签: ruby hash chef-infra definitions


    【解决方案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 块中。

    【讨论】:

    • 啊。没有意识到我是在调用定义而不是简单地为它们分配一个指针。
    猜你喜欢
    • 2018-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    相关资源
    最近更新 更多