在 Chef 中,如何从食谱更新环境属性?
In chef, how do I update environment attributes from a recipe?
我在环境文件中定义了环境属性,用于覆盖节点中的默认设置。
在我的例子中,我想更新配方中的环境属性,所以当 运行ning chef-client
on b_node_name
时,环境属性将从这个改变:
default_attributes "hosts" => ["a_node_name"]
对此:
default_attributes "hosts" => ["a_node_name", "b_node_name"]
这样做我想将我 运行 chef-client
添加到数组中的新 b_node_name
这样所有节点都将获得新 chef-client
[=73 的更新列表=]s.
这可以吗?我是否应该使用数据包来让所有节点从那里读取和更新该信息?我正在寻找实现这个的最佳方法。
我真的很感激任何帮助。
更新:
我在我的食谱中添加了以下几行:
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"]
。
如果我通过 Chef Server UI 到达节点并检查 hosts
属性,我会看到主机设置为 ["a_hostname", "b_hostname"]
而不是 hosts=["a_hostname"]
为什么我在 chef-client
运行 期间得到 hosts=["a_hostname"]
?
更新 2:
使用 node.set
而不是 node.default
或 node.override
使值持续存在,但仅适用于我 运行 chef-client 所在的节点(不是所有节点),因此上述情况有效但不是以下一个:
c_hostname
中的第一个主厨客户 运行:
[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"]
我希望看到主机数组设置为 ["a_hostname","b_hostname"] 由 chef-client 运行 在 b_hostname
中完成
在配方中,执行此操作以动态更改属性值。
node.default['hosts'] = ['a_node_name', 'b_node_name']
Chef 每次 运行 都会重置属性,因此您看到的行为是有意的 - 检查 https://docs.chef.io/attributes.html
如果您想在 运行 之间保留节点属性更改,请使用 node.set - 在您的情况下
node.set['hosts'] = ['a_node_name', 'b_node_name']
在 Chef 客户端 运行s 期间更改节点属性时要小心 - Chef 客户端首先编译属性以预先确定节点属性值,然后 运行s 食谱,所以如果你想动态更改值在 运行 期间,您可能需要将 node.set 放入 ruby 区块
已更新以允许按添加时间排序。
您需要使用搜索。与其使用属性来确定列表,不如使用属性来指示给定节点属于列表。
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
。需要注意的是,它将仅包括已完成 运行 的节点。因此,如果您有并行构建的节点,它们将看不到彼此。此外,当前节点不会出现在它的第一个 运行 上。因此,您将需要更多逻辑来搜索当前节点,然后在缺少时将其添加到列表中。
我在环境文件中定义了环境属性,用于覆盖节点中的默认设置。
在我的例子中,我想更新配方中的环境属性,所以当 运行ning chef-client
on b_node_name
时,环境属性将从这个改变:
default_attributes "hosts" => ["a_node_name"]
对此:
default_attributes "hosts" => ["a_node_name", "b_node_name"]
这样做我想将我 运行 chef-client
添加到数组中的新 b_node_name
这样所有节点都将获得新 chef-client
[=73 的更新列表=]s.
这可以吗?我是否应该使用数据包来让所有节点从那里读取和更新该信息?我正在寻找实现这个的最佳方法。 我真的很感激任何帮助。
更新: 我在我的食谱中添加了以下几行:
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"]
。
如果我通过 Chef Server UI 到达节点并检查 hosts
属性,我会看到主机设置为 ["a_hostname", "b_hostname"]
而不是 hosts=["a_hostname"]
为什么我在 chef-client
运行 期间得到 hosts=["a_hostname"]
?
更新 2:
使用 node.set
而不是 node.default
或 node.override
使值持续存在,但仅适用于我 运行 chef-client 所在的节点(不是所有节点),因此上述情况有效但不是以下一个:
c_hostname
中的第一个主厨客户 运行:
[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"]
我希望看到主机数组设置为 ["a_hostname","b_hostname"] 由 chef-client 运行 在 b_hostname
在配方中,执行此操作以动态更改属性值。
node.default['hosts'] = ['a_node_name', 'b_node_name']
Chef 每次 运行 都会重置属性,因此您看到的行为是有意的 - 检查 https://docs.chef.io/attributes.html
如果您想在 运行 之间保留节点属性更改,请使用 node.set - 在您的情况下
node.set['hosts'] = ['a_node_name', 'b_node_name']
在 Chef 客户端 运行s 期间更改节点属性时要小心 - Chef 客户端首先编译属性以预先确定节点属性值,然后 运行s 食谱,所以如果你想动态更改值在 运行 期间,您可能需要将 node.set 放入 ruby 区块
已更新以允许按添加时间排序。
您需要使用搜索。与其使用属性来确定列表,不如使用属性来指示给定节点属于列表。
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
。需要注意的是,它将仅包括已完成 运行 的节点。因此,如果您有并行构建的节点,它们将看不到彼此。此外,当前节点不会出现在它的第一个 运行 上。因此,您将需要更多逻辑来搜索当前节点,然后在缺少时将其添加到列表中。