0

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

# 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 个节点等。如果我们尝试重构整个事物,我们肯定会犯一个以微妙方式出现的错误。

4

2 回答 2

1

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

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

于 2015-01-21T19:27:14.947 回答
0

如果我们试图重构整个事情,我们肯定会犯一个会以微妙的方式出现的错误。

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

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

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

附带说明一下,在多环境设置中,您可能也希望远离角色。

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

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

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

重构说明书以使用单个属性。单个属性已经很好地优先了。

于 2015-01-21T23:07:57.397 回答