Cascade update dependent attributes


#1

Hi,

Is any body faced with such problem?

cookbook1 attributes

default[:a] = 1
default[:b] = “use-#{ node.a }”

cookbook2 attributes

override[:a] = 2

I found that in the cassandra cookbook.
The problem is if I want to change one attribute in the wrapper cookbook I
have to change both attributes.
Otherwise error happens because ruby make substitution before cookbook2 is
loaded.

Does Chef has any standard method to cope with it?

I see a simple solution:

class DynamicAttribute
def initialize(&block)
@block = block
end
def to_s
@block.call
end
end

Usage:
default[:a] = DynamicAttribute.new do “use-#{ node.a }” end

It’s unwieldy a little.
Is any ideas how to humanize it?


Daneel S. Yaitskov


#2

Use roles.

You can move the computed attributes in cookbook1 into a recipe which
will be parsed after all of the attributes are parsed, but as you
construct role/wrapper cookbook heirarchies, you wind up facing the fact
that include_attribute and include_recipe don’t parse in the correct
order (dependent stuff is parsed first, then the stuff in the cookbook
is parsed). You’ll wind up in an arms race trying to push your computed
attributes later and later, and there’s no way out of it. Eventually
you wind up with compile/converge phase issues and start using lazy
attributes. Roles have the correct property that the attributes in the
role are parsed first, then any dependent sub-roles are slurped in and
their attributes are applied. And all that is compiled together before
you every hit the first attribute file so there’s no parse-order
problems. Again, attributes and recipes have their parse order wrong,
roles do not.

On 11/30/13 1:04 PM, Daneel Yaitskov wrote:

Hi,

Is any body faced with such problem?

cookbook1 attributes

default[:a] = 1
default[:b] = “use-#{ node.a }”

cookbook2 attributes

override[:a] = 2

I found that in the cassandra cookbook.
The problem is if I want to change one attribute in the wrapper
cookbook I have to change both attributes.
Otherwise error happens because ruby make substitution before
cookbook2 is loaded.

Does Chef has any standard method to cope with it?

I see a simple solution:

class DynamicAttribute
def initialize(&block)
@block = block
end
def to_s
@block.call
end
end

Usage:
default[:a] = DynamicAttribute.new do “use-#{ node.a }” end

It’s unwieldy a little.
Is any ideas how to humanize it?


Daneel S. Yaitskov