Chef Recipes - 在ruby_block中设置节点属性

dan*_*ash 5 ruby dsl scope chef-infra

我有一个多节点Web服务的Chef配方,每个节点都需要获取其他节点的主机名和IP,以将其置于自己的本地配置中.

代码如下所示.问题是,当如图所示在ruby_block中进行node.set [] []赋值时,当创建依赖于它们的模板时,这些值为空.如果我想创建该模板,我必须将所有ruby_block代码移到外面,并在配方中"松散".这使得使用Chefspec等进行单元测试变得更加困难.

任何厨师大师都可以让我直截了当吗?在ruby_block中这样做node.set []是不是不可能吗?如果是这样,为什么不在文档中这样说呢

$cm = { :name => "web", :hostname => "" , :ip_addr => "" }
$ca = { :name => "data", :hostname => "" , :ip_addr => "" }
$cg = { :name => "gateway", :hostname => "" , :ip_addr => "" }
$component_list = [$cm, $ca, $cg]

ruby_block "get host addresses" do
  block do
    for cmpnt in $component_list
       # do REST calls to external service to get cmpnt.hostname, ip_addr
       # .......
       node.set[cmpnt.name]['name'] = cmpnt.name
       node.set[cmpnt.name]['host'] = cmpnt.hostname
       node.set[cmpnt.name]['ip'] = cmpnt.ip_addr   
    end
  end
end

template "/etc/app/configuration/config.xml" do
  source "config.xml.erb"
  variables( :dataHost => node['data']['host'],
       :webHost =>  node['web']['host'],
       :gatewayHost =>  node['gateway']['host'] )
  action :create
end
Run Code Online (Sandbox Code Playgroud)

我还补充道

  subscribes  :create, "ruby_block[get host addresses]", :immediately
Run Code Online (Sandbox Code Playgroud)

到模板定义,以确保在创建模板之前运行ruby_block.这没有什么区别.

Ala*_*lan 5

我意识到这是一篇旧文章,但是为了将来的参考,我只是遇到了这个要点,它给出了Compile vs. Converge阶段中节点变量赋值的一个很好的例子.要根据您的示例调整要点,您需要在以下代码中添加以下代码ruby_block:

       template_r = run_context.resource_collection.find(:template => "/etc/app/configuration/config.xml")

       template_r.content node['data']['host']
       template_r.content node['web']['host']
       template_r.content node['gateway']['host']
Run Code Online (Sandbox Code Playgroud)

对于Chef 11,也请参阅Lazy Attribute Evaluation.


小智 2

问题似乎是模板资源定义中的属性值在实际调用任何资源之前进行评估。即,该文件首先作为简单的 Ruby 执行,编译资源,并且仅调用资源操作。到那时,已经太晚了。当我尝试将某些属性操作封装到资源中时,我遇到了同样的问题。它根本不起作用。如果有人知道这个问题的解决方案,我将非常感激。

编辑:

b = ruby_block...
...
end
b.run_action(:create)
Run Code Online (Sandbox Code Playgroud)

可能会成功。它立即调用资源。