Chef infra 如何在厨师菜谱的ruby_块中包含_菜谱

Chef infra 如何在厨师菜谱的ruby_块中包含_菜谱,chef-infra,chef-recipe,Chef Infra,Chef Recipe,我有一个在ruby_块中设置变量的配方,需要将该变量用作配方的输入属性。 在执行ruby_块之后,如何使用include_配方 谢谢 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_usernam

我有一个在ruby_块中设置变量的配方,需要将该变量用作配方的输入属性。 在执行ruby_块之后,如何使用include_配方

谢谢

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

您可以从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'

要包含ruby_块中的配方,必须使用run_上下文调用它

例如:

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

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

看起来这里有很多工作要做,为了我不理解的原因,我们需要延迟所有的事情,并使用
ruby_块。更好的方法是不使用ruby_块:

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'
如果chef自己负责生成
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_文件
资源在某处创建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{}
制造了一场越来越多的针对懒散行为的军备竞赛,如果你在自己无法控制的范围内消费烹饪书,那么它就会变得越来越丑陋。整个问题有很多“代码味道”,迫使事情发生得越来越晚,最终导致一切都是如何构建的。你最好回去重构你的假设,这样你就可以在厨师长的工作中推进更多的工作

通常,您会尝试在属性文件解析阶段编译节点属性中的所有信息。在菜谱代码中设置属性会导致类似这样的问题,最终您会发现自己想要将PRs提交给现有的每个社区菜谱,以延迟它们使用的所有属性。使用资源驱动库cookbooks而不是属性和配方驱动库cookbooks可以帮助避免整个过程。尽管如此,您还是应该尽早组装节点数据,这样就不必延迟对节点数据的所有访问


如果必须在配方代码中构造节点数据,则必须在编译时构造该数据。试图在指定时间设置节点数据是您丢失了一点的症状。

请查看加密的数据包,其中包含加密的密码
ruby_块
是在资源收集后执行的代码的一部分,所以下一步只需将
include_recipe
放在这个块之外。这不会起作用。include_recipe将在编译阶段实例化,并将使用默认的basic_auth_用户名和basic_auth_密码值。在收敛阶段,将执行ruby_块并设置值,但不会对包含的_配方产生影响。按原样运行代码时会发生什么?它会抛出错误吗?您可能需要在ruby块中包含厨师配方代码。@JoseOlcese您能接受我的答案吗?这行不通。include_recipe将在编译阶段实例化,并将使用默认的basic_auth_用户名和basic_auth_密码值。在收敛阶段,将执行ruby_块并设置值,但不会对包含的_recipe.Ohh产生影响,我发现这似乎与您的问题有关Lazya属性求值也是一个很好的选择问题是我不必修改“kibana”配方来指定惰性属性(无论在何处使用),也不必知道使用run_context.resource_collection.find(…)的内部结构。配方应该是独立的。你能解释一下你的答案吗?要包含来自ruby_块的配方,你必须使用run_上下文来调用它。在答案本身中,它更好;)