如果满足某些条件,我希望能够使用 include_recipe
和 only_if
。以下代码不会引发任何错误,但也不考虑 only_if
的条件,因此无论如何都会被执行:
include_recipe "cubrid" do
only_if "hostname | grep 'blahblahshouldnotmatch'"
end
是否可能仅在某些条件下使用include_recipe
?
如果满足某些条件,我希望能够使用 include_recipe
和 only_if
。以下代码不会引发任何错误,但也不考虑 only_if
的条件,因此无论如何都会被执行:
include_recipe "cubrid" do
only_if "hostname | grep 'blahblahshouldnotmatch'"
end
是否可能仅在某些条件下使用include_recipe
?
include_recipe
不是 Chef 中的普通资源,而是普通方法。因此,它会忽略传递的块,以及在那里指定的only_if
条件。
幸运的是,这个问题有一个解决方案。#chef freenode 频道的用户 flaccid 提出了以下完美运作的解决方案。
this_node_is_shard_broker = node["hostname"].include? "node2"
include_recipe "cubrid" if this_node_is_shard_broker
如果当前运行节点的主机名是 node2
,则上述内容将执行 include_recipe
,这正是我想要实现的。
这个很好用:
include_recipe "foo" if node['bar'] == 'baz'
if node["hostname"].include? "node2"
include_recipe "cubrid"
end
在所有建议中
,它们都涉及编程。include_recipe "foo" if node['bar'] == 'baz'
你忘记了一件非常重要的事情-这个if在编译阶段被评估,如果在执行过程中改变了node['bar'],那么这个if将会提供错误的结果,因为它将基于原始值而不是更改后的值。
有人会认为这是一种不好的实践,但在这之前请三思。只是举个例子:在chef-client运行中安装软件包是一种常见做法。之后重新加载ohai插件软件包可以看作是一个好的实践,但是代码会发生什么:
include_recipe "my_cookbook::install" unless node['packages'].key?('mypackage')
如果mypackage安装在同一客户端运行中较早执行的cookbook中,该怎么办?正确的答案是该recipe将被包含,尽管从代码中可以清楚地看出预期是不包含它。
不幸的是,我至少不知道如何解决这个问题,因为include_recipe和可能的条件都是编译阶段评估的。据我所知,没有办法根据其他cookbook在同一chef-client运行中采取的操作有条件地包含recipe。
only_if
,该字符串将由自定义解释器解释,现在必须手动调用该解释器并从其输出中提取布尔值。虽然不太方便,但通常是可以接受的。 - Zeust the Unoobianonly_if
关键字的话,那就太完美了。include_recipe cookbook::recipe if [condition]
似乎是静态的,如果条件在收敛过程中发生变化,就无法正常工作。resource_name :conditional_include
property :recipe, String, name_property: true
default_action :apply
action :apply do
include_recipe new_resource.recipe
end
conditional_include 'cookbook::recipe' do
only_if { [condition] }
end
only_if
是Chef提供的一种结构,您可以使用任何only_if
或not_if
结构来创建您的条件。
include_recipe
看起来只是一个普通的 Ruby 函数调用,因此您可以使用简单的 Ruby 语法if <条件> <代码> end
。 - cmur2