ruby - 基于 Chef 版本的 Cookbook 依赖项
问题描述
我有一个包装食谱,它使用来自其他食谱的资源,但它们有不同的限制。我尝试定义我的 metadata.rb 如下:
name 'yp_linko'
maintainer 'The Authors'
maintainer_email 'devops@yp.ca'
license 'all_rights'
description 'Installs/Configures yp_linko'
long_description 'Installs/Configures yp_linko'
version '1.3.4'
depends 'apt'
if chef_version '<= 12' then
depends 'ypg_tomcat'
else
depends 'yp_tomcat'
end
这不起作用,因为厨师在收敛期间抓住了两本食谱。我尝试了几种不同的语法(only_if、unless 等),但都没有奏效。任何人都有解决这个问题的想法?
解决方案
TL;博士
您正在使用 Chef DSL 中的约束,但它并不打算使用。您需要基于布尔表达式而不是元数据约束进行分支。我提供了几种使用String#to_f作为示例的方法(如果您关心语义版本控制中的补丁级别,则不推荐),以及更准确但经常被忽视的Gem::Version。
不要使用约束进行分支
if chef_version '<= 12'
您正在尝试使用来自 DSL 的约束。这个约束有一个特定的目的:声明食谱支持的 chef-client 版本,而不是提供逻辑分支。如果不查看 DSL 的底层 Chef 代码,我会说表达式不太可能以您期望的方式提供 if-then 表达式。暂时不管这是否是正确的模式,您可以尝试以几种不同的方式获取当前版本的 Chef 工具:
在厨师客户端版本上分支,可能转换为浮点数(通常是字符串)。例如:
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'
但是,在所有情况下,您都必须处理这样一个事实,即传递给您的是一个包含语义版本控制的字符串,而不是浮点数或整数。因此,您必须弄清楚您真正想要如何解析信息,这可能容易出错(不过,请参阅下面的使用 Gem::Version 的技巧)。在任何情况下,一旦你按照你想要的方式解析它,你就可以使用比较运算符来匹配它以获得你想要的分支行为。
更好的选择
与其试图让元数据约束保持业务逻辑,不如将数据移出到属性中。考虑一个属性,例如node['yp_linko']['tomcat_cookbook']
,您可以根据除语义版本控制之外的一些其他可检测节点值来设置该属性。
另一种方法是声明两本食谱为依赖项,然后在yp_linko食谱中包含您想要的食谱。例如,假设您没有在 Tomcat 食谱中声明不兼容的 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 解决方案。您似乎可能还有其他具有类似问题的食谱,因此至少值得考虑让所有客户使用相同版本而不是在食谱级别解决问题是否更有意义。
推荐阅读
- ssl - Google Cloud Platform 上的 SSL 证书
- java - 如何在Spring中从@Autowired List<>的每个bean中获取@Qualifier
- mysql - 使用外键删除 MySQL 多表
- php - 使用 getlog() 执行的最后一个查询不会显示在 cake2php 中
- html - NodeJS 未检测或删除抓取的 HTML 中的问号 (?)
- azure-databricks - 将 Databricks 数据帧写入 BLOB 存储
- mysql - 如何在 mysql 的表中获取每个日期的唯一 SKU 计数(自学问题)
- java - Maven包含依赖删除一个
- javascript - 将对象数组附加到 HTML 文件中
- java - List all subpackages of a package (when their classes are loaded dynamically)