リポジトリ内の 2 つの異なるファイルには、次の行が含まれています。
# 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 に環境レベルのオーバーライドがある場合、属性が 1 つの属性であるかのようにシェフがオーバーライドを処理するようにします。
理想的なマージ コードは次のようになります。
> 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}
理想的には、各属性を同じものへのポインターにすることで、将来の呼び出しと割り当てが両方に適用されるようにします。
さて、明らかな答えは、単純に属性の 1 つをリファクタリングすることです。残念なことに、chef は属性のリファクタリングを困難にしています - 私たちは 10 の異なる環境、7 つの異なる役割、環境ごとに 20 のノードなどを持っています。