Chef/Ruby: 引用哈希中的定义
Chef/Ruby: Reference to Definition in Hash
下面的代码按预期工作并生成以下内容:
==> 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,大厨会抱怨:
==> 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
您的定义采用名为 :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 块中它。
下面的代码按预期工作并生成以下内容:
==> 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,大厨会抱怨:
==> 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
您的定义采用名为 :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 块中它。