Details
-
Type:
Bug
-
Status:
Closed
-
Priority:
Major
-
Resolution: Won't Fix
-
Affects Version/s: 0.10.6
-
Fix Version/s: None
-
Component/s: None
-
Labels:None
Description
As pointed out by llaurent in https://gist.github.com/1376294 the deep merging of arrays between cookbook and role defaults is broken.
cookbook attributes:
default["test"] = {
:t1 => [ "un", "deux", "trois" ],
:t2 => [ "un", "deux", "trois" ],
:t3 => [ "un", "deux", "trois" ],
:t4 => [ "un", "deux", "trois" ],
:t5 => [ "un", "deux", "trois" ],
:t6 => [ "un", "deux", "trois" ]
}
+
role attributes:
default_attributes "test" => {
:t1 => [ "!merge:deux" ],
:t2 => [ "!merge:" ],
:t3 => [ "!merge:", "deux", "trois" ],
:t4 => [ "!merge:", "quatre", "cinq", "six" ],
:t5 => [ "quatre", "cinq", "six" ]
}
produce
[Fri, 18 Nov 2011 13:37:10 -0800] INFO: BLA1: ["un", "deux", "trois"] [Fri, 18 Nov 2011 13:37:10 -0800] INFO: BLA2: ["un", "deux", "trois"] [Fri, 18 Nov 2011 13:37:10 -0800] INFO: BLA3: ["un", "deux", "trois"] [Fri, 18 Nov 2011 13:37:10 -0800] INFO: BLA4: ["un", "deux", "trois"] [Fri, 18 Nov 2011 13:37:10 -0800] INFO: BLA5: ["un", "deux", "trois", "quatre", "cinq", "six"]
Although I don't use it myself this is expected to work from the documentation @ http://wiki.opscode.com/display/chef/Attributes#Attributes-SettingAttributesattheSamePrecedenceLevel wherein: "A common use case is to set default attributes in a cookbook's attribute files, and also set the same default attributes, but with different values, using a role. In this scenario, the attributes set in the role will be deep merged on top of the attributes from the attributes file. The attributes set by the role will win if there is a conflict."
Issue appears to be in chef/lib/chef/run_list/run_list_expansion.rb in the apply_role_attributes method, the role.default_attributes are always merged with an empty hash in @default_attrs at least once, this eats the !merge exclusion which needs to be preserved for the later deep merge with cookbook defaults.
eg:
@default_attrs: {} role.default_attributes: {"test1"=>{"t1"=>["!merge:deux"], "t2"=>["!merge:"], "t3"=>["!merge:", "deux", "trois"], "t4"=>["!merge:", "quatre", "cinq", "six"], "t5"=>["quatre", "cinq", "six"]}} deep_merge result: {"test1"=>{"t1"=>[], "t2"=>[], "t3"=>[], "t4"=>[], "t5"=>["quatre", "cinq", "six"]}}