能否在Chef的`include_recipe`中指定`only_if`/`not_if`条件?

14

如果满足某些条件,我希望能够使用 include_recipeonly_if。以下代码不会引发任何错误,但也不考虑 only_if 的条件,因此无论如何都会被执行:

include_recipe "cubrid" do
    only_if "hostname | grep 'blahblahshouldnotmatch'"
end

是否可能仅在某些条件下使用include_recipe

5个回答

24

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,这正是我想要实现的。


8
include_recipe 看起来只是一个普通的 Ruby 函数调用,因此您可以使用简单的 Ruby 语法 if <条件> <代码> end - cmur2

9

这个很好用:

include_recipe "foo" if node['bar'] == 'baz'

4
上述方法对我无效,但以下方法有效:
if node["hostname"].include? "node2"
  include_recipe "cubrid"
end

1

在所有建议中

,它们都涉及编程。
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。


我认为,如果您真的想让一个配方取决于在Chef运行期间可能会更改的属性,您唯一的选择是使配方中的每个资源都有条件。但这是一个相当罕见的用例。更常见的情况是希望将字符串传递给only_if,该字符串将由自定义解释器解释,现在必须手动调用该解释器并从其输出中提取布尔值。虽然不太方便,但通常是可以接受的。 - Zeust the Unoobian

0
我一直在寻找一种动态的方法来根据条件包含一个食谱。如果Chef本身有only_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_ifnot_if结构来创建您的条件。
注意:在提出这种方法之后,我发现其他无关的帖子也包括使用动态配方名称的资源的配方。因此,这种方法已经存在一段时间了,只是不一定是为了这个特定的目的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接