【问题标题】:Cookbook dependencies based on chef version基于 Chef 版本的 Cookbook 依赖项
【发布时间】:2022-03-04 11:51:21
【问题描述】:

我有一个包装食谱,它使用来自其他食谱的资源,但它们有不同的限制。我尝试将 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 等),但都没有奏效。有人有解决此问题的想法吗?

【问题讨论】:

  • 将逻辑移到配方中怎么样?

标签: ruby chef-infra metadata chef-recipe


【解决方案1】:

TL;DR

您正在使用来自 Chef DSL 的约束,但它并不打算使用。您需要基于布尔表达式而不是元数据约束进行分支。我以String#to_f 为例提供了几种方法(如果您关心语义版本控制中的补丁级别,则不推荐),以及更准确但经常被忽视的Gem::Version

不要对分支使用约束

if chef_version '&lt;= 12'

您正在尝试使用来自 DSL 的约束。此约束has a specific purpose:声明食谱支持的厨师客户端版本,不提供逻辑分支。如果不查看 DSL 的底层 Chef 代码,我会说表达式不太可能以您期望的方式提供 if-then 表达式。暂时不管这是否是正确的模式,您可以尝试通过几种不同的方式获取当前版本的 Chef 工具:

  1. 在主厨客户端版本上进行分支,可能转换为浮点数(通常是字符串)。例如:

    if Chef::VERSION.to_f <= 12
    
  2. 从 ohai 获取节点值,例如:

    if node['chef_packages']['chef']['version'].to_f <= 12
    
  3. 直接从客户端解析值,例如:

    depends %x(chef-client --version).split[1].to_f <= 12 ? 'ypg_tomcat' : 'yp_tomcat'
    

但是,在所有情况下,您都必须处理这样一个事实,即传递给您的是一个包含语义版本控制的字符串,而不是浮点数或整数。因此,您必须弄清楚您真正想要如何解析信息,这可能容易出错(不过,请参阅下面的使用 Gem::Version 的技巧)。无论如何,一旦你按照你想要的方式解析它,你就可以使用比较运算符来匹配它以获得你想要的分支行为。

更好的选择

与其试图让元数据约束保持业务逻辑,不如将数据移出到属性中。考虑一个属性,例如node['yp_linko']['tomcat_cookbook'],您可以根据除语义版本控制之外的一些其他可检测节点值来设置它。

另一种方法是声明两个食谱为依赖项,然后声明 include 您想要在 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 解决方案。您似乎有其他具有类似问题的食谱,因此至少值得考虑让所有客户使用相同版本而不是在食谱级别解决问题是否更有意义。

【讨论】:

  • 感谢您真正有见地的回答。我们正在将环境中的所有节点升级到最新的 chef 版本以规避这个问题。我目前是该项目的负责人,但这是一项漫长的努力,因为我们有 1000 多个节点。同时,您的第一个解决方案(使用动态属性)似乎是最好的选择,因为在元数据中具有依赖会使菜谱在收敛期间初始化,这使得收敛在编译阶段失败,因为旧版本中使用了一些方法根本不与厨师 > 13 一起工作。再次感谢!
猜你喜欢
  • 1970-01-01
  • 2014-01-22
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 2014-07-07
  • 2019-12-25
  • 2020-07-24
  • 2020-02-14
相关资源
最近更新 更多