Matthew,
Thanks! After thinking about it and re-reading docs I think your
suggestion got me to realize why I can't just set /node.run_state/ the
way I can set /node.normal/:
/>run_state is an empty Hash that is always discarded at the end of
the chef-client run./
So I have to treat it as empty hash instead of as node's attributes
hash, and also, it can't be used to modify cookbook behavior (because
/node.run_state/ doesn't get merged with /node.normal/ attributes).
So, for my recipe to override attributes at recipe level, I have to
use /node.override['something'] = value/. That way I get to override
the value, yet the override doesn't get saved to node object like it
would with /node.normal['something'] = value/.
/P.S./ The use case for this recipe is to let users override any
cookbook attributes on per-environment, per-role basis. For example -
enabling Tomcat debugging on particular set of webapps in particular
environment. Normally this would require doing "knife node edit" or
creating a special recipe to set attributes.
Here's working code snippets:
*Goal:* set /node['tomcat']['debug']['enabled]=true/ and
/node['tomcat']['blah']['blah']='whatever' /on /my-webapp-1/ hosts in
/qa-1/ environment.
*/my-webapp-1.rb:/*
name "my-webapp-1"
description "Role for my webapp 1"
default_attributes(
'custom-resource' => {
'env_attributes' => {
'qa-1' => {
* 'tomcat.debug.enabled' => true,*
* 'tomcat.blah.blah' => 'whatever'*
}
}
}
)
run_list(...,"recipe[custom-resource]","recipe[tomcat]",...)
Then the Ruby block overrides Tomcat cookbook's attributes at run time:
*/cookbooks/custom-resource/attributes/default.rb/*
default["custom-resource"]["env_attributes"] = Hash.new
*/cookbooks/custom-resource/default.rb/*
node["custom-resource"]["env_attributes"].each do |env, attrs|
if env == *node[:environment][:name]*
Chef::Log.info("Setting env_attributes for #{env}...")
attrs.each do |attr,val|
Chef::Log.info("Setting attribute #{attr} to #{val}")
if val.instance_of? String
ruby_block "set_attr_#{attr}" do
block do
* eval ( "node.override['" + attr.split(".").join("']['") +
"'] = #{val}" )*
end
end
else
ruby_block "set_attr_#{attr}" do
block do
* eval ( "node.override['" + attr.split(".").join("']['") +
"'] = #{val}" )*
end
end
end
end
end
end
Archive powered by MHonArc 2.6.16.