我有一个使用其他烹饪书中的资源的包装食谱,但它们有不同的约束。我尝试定义我的metadata.rb如下:
名字’yp_linko’维护者’作者’…
您正在使用Chef DSL中的约束,其方式是不打算使用它。您需要基于布尔表达式而不是元数据约束进行分支。我提供了几种使用方法 串#to_f 作为示例(如果您关心语义版本中的补丁级别,则不推荐),以及更准确但经常被忽略的 宝石::版本 。
if chef_version '<= 12'
您正在尝试使用DSL中的约束。这个约束 有特定的目的 :声明cookbook支持的chef-client版本,而不是提供逻辑分支。如果没有查看DSL的底层Chef代码,我会说这个表达式不太可能像你期望的那样为你的if-then表达式提供信息。暂时搁置这是否是正确的模式,您可以尝试以几种不同的方式获取当前版本的Chef工具:
在chef-client版本上分支,可能被转换为Float(通常是String)。例如:
if Chef::VERSION.to_f <= 12
从ohai获取节点值,例如:
if node['chef_packages']['chef']['version'].to_f <= 12
直接从客户端解析值,例如:
depends %x(chef-client --version).split[1].to_f <= 12 ? 'ypg_tomcat' : 'yp_tomcat'
但是,在所有情况下,您将不得不处理这样一个事实:您正在传递包含语义版本控制的String,而不是Float或Integer。因此,您必须弄清楚您是如何真正想要解析信息的,这可能容易出错(尽管如此,请参阅下面的使用Gem :: Version的技巧)。无论如何,一旦你按照你想要的方式解析它,你可以使用比较运算符来匹配它,以获得你想要的分支行为。
您可能应该将数据移出到属性,而不是尝试使元数据约束保持业务逻辑。考虑一个属性,如 node['yp_linko']['tomcat_cookbook'] ,您可以根据语义版本控制之外的其他一些可检测节点值进行设置。
node['yp_linko']['tomcat_cookbook']
另一种方法是将两个烹饪书声明为依赖,然后 包括 你想要的食谱 yp_linko 菜谱。例如,假设您尚未在Tomcat cookbook中声明不兼容的chef-client版本:
# metadata.rb depends 'yp_tomcat' depends 'ypg_tomcat' # default.rb if Chef::VERSION <= Gem::Version.new(12) include ypg_tomcat::default else include yp_tomcat::default end
最后,您应该考虑首先在基础架构中运行不同版本的Chef客户端是否真的有意义。可能有业务需要这样做,但这是你真正想要解决的真正问题。在您的食谱中分支是基础设施问题的X / Y解决方案。您可能还有其他类似问题的烹饪书,因此至少值得考虑让所有客户使用相同版本而不是在菜谱级解决问题更有意义。