【问题标题】:Merging two chef attributes合并两个厨师属性
【发布时间】:2016-12-22 08:07:20
【问题描述】:

我们存储库中的两个不同文件包含以下行:

# library_cookbook_1/attributes/default.rb
default[:library_cookbook_1][:foo] = true
# library_cookbook_2/attributes/default.rb
default[:library_cookbook_2][:foo] = true

我想合并这两个属性。仅仅将一个设置为另一个是不够的,因为它们都可以互换使用。我最担心的是有人犯了这个错误:

"environment_json_attributes": {
    "library_cookbook_1": {
        "foo": false //Now it's false half of the time...
    }
}

忘记在我们的代码中设置两个变量的值在我们当前的结构下是一个致命的错误。我想以维护覆盖层次结构的方式合并属性,这样如果 library_cookbook_1 具有角色级别覆盖,但 library_cookbook_2 具有环境级别覆盖,则厨师将处理覆盖,就好像属性只是一个属性一样。

理想的合并代码如下所示:

> node.attributes.debug_value('library_cookbook_1', 'foo')
{'precedence1' => true, 'precendence3' => false}
> node.attributes.debug_value('library_cookbook_2', 'foo')
{'precedence1' => false, 'precendence2' => true}

> attr_merge(['library_cookbook_1', 'foo'], ['library_cookbook_2', 'foo'])
> node.attributes.debug_value('library_cookbook_1', 'foo')
{'precedence1' => true, 'precendence2' => true, 'precendence3' => false}
> node.attributes.debug_value('library_cookbook_2', 'foo')
{'precedence1' => true, 'precendence2' => true, 'precendence3' => false}

> node[:library_cookbook_1][:foo].precedence4 = true
> node.attributes.debug_value('library_cookbook_2', 'foo')
{'precedence1' => true, 'precendence2' => true, 'precendence3' => false, 'precedence4' => true}

理想情况下,我希望每个属性都是指向同一事物的指针,这样以后的调用和赋值都适用于两者。

现在,显而易见的答案是简单地重构掉其中一个属性。不幸的是,chef 使重构属性变得困难——我们有 10 个不同的环境、7 个不同的角色、每个环境 20 个节点等。如果我们尝试重构整个事物,我们肯定会犯一个以微妙方式出现的错误。

【问题讨论】:

  • 如果您尝试保留两个不同的属性,您肯定会遇到一些微妙的问题。做对了,否则你会付出很长时间的代价。

标签: chef-infra chef-attributes


【解决方案1】:

重构使用属性的说明书,改为使用单个属性。然后添加一些代码,如果任何一个原始 attrs 设置为 nil(或哨兵)以外的其他值,它将中止 Chef 运行。前一个小时左右可能会有点烦人,但您会很快找到旧值的设置位置。

如果做不到这一点,请制作一个采用单个属性并基于它设置两个旧值的 force_override 的食谱。这意味着如果发生冲突,新值总是会获胜。

【讨论】:

    【解决方案2】:

    如果我们尝试重构整个事情,我们肯定会犯一个微妙的错误。

    你需要先解决这个问题!您需要有足够的自动化测试才能对更改充满信心。如果您担心进行更改,那么您将陷入困境并且永远无法使用 Chef。

    使用ChefSpec 快速对您的食谱代码进行单元测试(无需应用任何更改)

    也许您需要类似 Vagrant 或带有 VM 的 chefdev 环境,以便在您的真实环境之前使用您的新说明书测试完全融合的节点。

    附带说明一下,在多环境设置中,您可能也想stay away from roles

    显而易见的答案是简单地重构掉其中一个属性

    无论您选择哪种方法,您都需要重构,因为 Chef 不支持您想要的开箱即用的功能。由于害怕改变事情而添加不明显的kludges只会在以后咬你。

    所以,你明显的答案将是我的答案....

    重构说明书以使用单个属性。单个属性已经很好地完成了precedence

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-08
      • 2015-11-20
      • 1970-01-01
      • 1970-01-01
      • 2013-02-22
      相关资源
      最近更新 更多