[chef] Re: Re: Re: Re: Re: Re: Re: node.run_state


Chronological Thread 
  • From: Lamont Granquist < >
  • To:
  • Cc: DV < >
  • Subject: [chef] Re: Re: Re: Re: Re: Re: Re: node.run_state
  • Date: Mon, 22 Sep 2014 22:43:51 -0700


You should avoid setting attributes at converge-time using ruby_block unless you absolutely have to. You are eventually going to have a bad time in later recipes when you try to use those attributes at compile time and they don't work the way you think they will. You'll have to use lazy attributes everywhere and
that is code smell that you need to drop those ruby_blocks and move whatever input prep you need to do before this to compile time.

On Mon Sep 22 22:19:43 2014, DV wrote:
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.

§