如何在一个厨师食谱的ruby_block中包含include_recipe

时间:2015-03-03 19:24:59

标签: chef chef-recipe

我有一个配方在ruby_block中设置变量,需要使用该变量作为配方的输入属性。 如何在执行ruby_block后使用include_recipe?

由于

ruby_block "evaluate_config" do #~FC014
 block do

  file = File.read('/opt/config/baselogging.json')
  data = JSON.parse(file)

  node.default['kibana']['apache']['basic_auth_username'] = data['KibanaUser']
  node.default['kibana']['apache']['basic_auth_password'] = data['KibanaPassword']

  include_recipe 'kibana'

 end
end

3 个答案:

答案 0 :(得分:11)

要包含ruby_block中的配方,必须使用run_context调用它。

例如:

ruby_block "evaluate_config" do #~FC014
 block do
   ...
   #include_recipe 'kibana'
   run_context.include_recipe "cookbook::recipe"
 end
end

答案 1 :(得分:1)

您可以从ruby块中读取和设置属性,然后可以包含以下配方:

ruby_block "evaluate_config" do #~FC014
 block do   
  file = File.read('/opt/config/baselogging.json')
  data = JSON.parse(file)

  node.set['kibana']['apache']['basic_auth_username'] = data['KibanaUser']
  node.set['kibana']['apache']['basic_auth_password'] = data['KibanaPassword']   
 end
end

include_recipe 'kibana'

答案 2 :(得分:0)

看起来这里的问题是kibana cookbook有一个默认配方,它使用lazy {}和密码节点属性时没有node['kibana']['apache']['basic_auth_username']个修饰符。

看起来这里有很多工作要做懒惰的事情并使用ruby_block,原因是我不明白。更好的方法是不使用ruby_block:

file = File.read('/opt/config/baselogging.json')
data = JSON.parse(file)

node.default['kibana']['apache']['basic_auth_username'] = data['KibanaUser']
node.default['kibana']['apache']['basic_auth_password'] = data['KibanaPassword']

include_recipe 'kibana'

如果厨师自己负责生成baselogging.json并且您正在尝试生成baselogging.json,然后从baselogging.json读取我想出的解决方案将是重构和删除的是:

data = ... stuff to populate the data ...

file "/opt/config/baselogging.json" do
  content JSON.generate(data)
end

[...]

node.default['kibana']['apache']['basic_auth_username'] = data['KibanaUser']
node.default['kibana']['apache']['basic_auth_password'] = data['KibanaPassword']

include_recipe 'kibana'

即使某个地方有remote_file资源创建了baselogging.json,你最好还是做这样的事情:

# "cheat" and download the file at compile-time
remote_file "/opt/config/baselogging.json" do
   source "http://example.org/baselogging.json"
   action :nothing
end.run_action(:create)

file = File.read('/opt/config/baselogging.json')
data = JSON.parse(file)

node.default['kibana']['apache']['basic_auth_username'] = data['KibanaUser']
node.default['kibana']['apache']['basic_auth_password'] = data['KibanaPassword']

include_recipe 'kibana'

这里更重要的一点是,lazy {}越来越多地制造了一场军备竞赛,如果你在控制之外消费烹饪书,那就变得更加丑陋和丑陋。整个问题有很多“代码嗅觉”,迫使事情发生在以后,后来就是为了解决所有事情的架构。你最好回去重构你的假设,这样你就可以在厨师运行中更多地前进。

通常,您将尝试在属性文件解析阶段编译节点属性中的所有信息。在食谱代码中设置属性会导致像这样的问题,并且在您发现自己想要将PR提交到现有的每个社区食谱中时,它们会延迟使用它们的所有属性。使用资源驱动的库烹饪书而不是属性和配方驱动程序库烹饪书可以帮助回避整个过程。除非您尽早组装节点数据,否则您不必懒惰地对节点数据进行所有访问。

如果必须在配方代码中构造节点数据,则必须在编译时构造该数据。尝试在配方收敛时设置节点数据是一个让你有点迷失的症状。