在厨师中,如何更新配方中的环境属性?

时间:2015-07-29 13:02:53

标签: chef chef-recipe

我在环境文件中定义了环境属性,用于覆盖节点中的默认设置。 在我的情况下,我想更新配方中的环境属性,以便在chef-client上运行b_node_name时,环境属性将从此更改:

default_attributes "hosts" => ["a_node_name"]

到此:

default_attributes "hosts" => ["a_node_name", "b_node_name"]

执行此操作我希望我运行b_node_name的新chef-client添加到数组中,以便所有节点都会获得新chef-client次运行的更新列表。

这可能吗?我是否应该使用数据包来使所有节点读取并从那里更新该信息?我正在寻找实现这一目标的最佳方法。 我真的很感激任何帮助。

更新 我在食谱中添加了以下几行:

Chef::Log.info("---> Before update. hosts=#{node.hosts}")
node.override['hosts'] = ["a_hostname", "b_hostname"] 
Chef::Log.info("---> After update. hosts=#{node.hosts}")

我得到了这个输出:

第一位厨师 - 客户在b_hostname中运行:

#chef-client --log_level info

[2015-07-29T14:29:13+00:00] INFO: ---> Before update. hosts=["a_hostname"]
[2015-07-29T14:29:13+00:00] INFO: ---> After update. hosts=["a_hostname", "b_hostname"]

第二位厨师 - 客户在b_hostname中运行:

#chef-client --log_level info
[2015-07-29T14:30:33+00:00] INFO: ---> Before update. hosts=["a_hostname"]
[2015-07-29T14:30:33+00:00] INFO: ---> After update. hosts=["a_hostname", "b_hostname"]

因此b_hostname读取的主机值为hosts=["a_hostname"],我希望第二次运行时hosts=["a_hostname", "b_hostname"]hosts

如果我通过Chef Server UI查看节点并检查["a_hostname", "b_hostname"]属性,我会看到主机设置为hosts=["a_hostname"]而不是hosts=["a_hostname"]

为什么我在chef-client运行期间收到node.set

更新2: 使用node.default代替node.overridec_hostname会使值保持不变,但仅适用于我运行chef-client(并非所有节点)的节点,因此上述方案有效,但不是以下方案:

第一位厨师 - 客户在[2015-07-29T14:58:51+00:00] INFO: ---> Before update. hosts=["a_hostname"] [2015-07-29T14:58:51+00:00] INFO: ---> After update. hosts=["a_hostname", "b_hostname"] 中运行:

b_hostname

我希望看到主机数组设置为[" a_hostname"," b_hostname"]由在context['user_query'] = True # False in the other view return render(request,'chart2.html', context) 中运行的chef-client完成

3 个答案:

答案 0 :(得分:1)

Chef每次运行都会重置属性,因此您所看到的行为是有意的 - 请检查https://docs.chef.io/attributes.html

如果要在运行之间保持节点属性更改,请使用node.set - 在您的情况下

node.set['hosts'] = ['a_node_name', 'b_node_name']

在厨师客户端运行期间更改节点属性时要小心 - 厨师客户端首先编译属性以预先确定节点属性值然后运行配方,这样如果要在运行时动态更改值,则可能需要放置node.set在红宝石块中

答案 1 :(得分:1)

更新以允许按时间添加排序。

您需要使用搜索。不是使用属性来确定列表,而是使用属性来指示给​​定节点属于列表。

node.set['include_me'] = Time.now

然后搜索已设置此项的所有节点,对它们进行排序,并获取其fqdn:

sorted = search(:node, 'include_me:*').sort_by { |node| node['include_me'] }
hostnames = sorted.map{ |node| node.fqdn }

这将为您提供一个按添加日期排序的fqdns hostnames数组。需要注意的是,它只包含已完成运行的节点。因此,如果您有并行构建的节点,它们将不会彼此看到。此外,当前节点将不会在其首次运行时显示。因此,您需要更多逻辑来搜索当前节点,然后将其添加到列表中(如果缺少)。

答案 2 :(得分:0)

在配方中,执行此操作以动态更改属性的值。

person