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


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

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

* We store our environment name in node['environment']['name'], it may be different for you.

Some would suggest that this recipe should catch NoMethodError and handle things (so that undefined attributes can be set) but I'd rather let it fail so the user knows he/she is setting an undefined attribute instead of overriding a defined one.

On Mon, Sep 22, 2014 at 7:06 PM, Matthew Moretti < " target="_blank"> > wrote:

This sort of error pops up when you try to set an attribute deeper than is currently defined. That is if node.run_state['some'] or node.run_state['some']['dynamic'] or node.run_state['some']['dynamic']['attribute'] doesn’t exist (is nil) then you can’t set it’s sub-values.

Since this is a temporary state value, is there any reason to burry it so deep? Probably this would be sufficient:

ruby_block "set_attr_#{attr}" do
  block do
    node.run_state['a_temporary_value_of_some_kind''] = val
  end
end

Hope that helps.

Matt Moretti


On Mon, Sep 22, 2014 at 9:51 PM, DV < " target="_blank"> > wrote:
Maybe you guys can help me out really quick. I was very happy to have found out about node.run_state because we just happened to need to set some runtime attributes set dynamically thru a recipe.

But, the following code works, and the one below it doesn't.

    ruby_block "set_attr_#{attr}" do
            block do
                    eval ( "node.normal['some']['dynamic']['attribute']['name'] = #{val}" )
            end
    end

(attribute gets stored in node object, do not want this permanence)

versus:

    ruby_block "set_attr_#{attr}" do
            block do
                    eval ( "node.run_state['some']['dynamic']['attribute']['name'] = #{val}" )
            end
    end

(doesn't work, but do want).

The error we get for the 2nd block:

NoMethodError: ruby_block[set_attr_zenoss.enabled] (custom-resource::env_attributes line 24) had an error: NoMethodError: undefined method `[]=' for nil:NilClass

The reason we're putting this into ruby block is because "['some']['dynamic']['attribute']['name']" part needs to be changeable thru attribute (in effect, setting node['something']['or']['other'] = some_value for the duration of chef-client run).

Is there anything we can do about this? Is there anything else close to node.run_state that we can use?

On Wed, Sep 10, 2014 at 2:53 PM, James Scott < " target="_blank"> > wrote:
OK, so the release notes/breaking changes topic is updated:


and there's an example of using node.run_state here:


james

On Wed, Sep 10, 2014 at 10:51 AM, Julian C. Dunn < " target="_blank"> > wrote:
Yes, we (ChefCo) should probably pull the materials from the
intermediate class curriculum to illustrate the use of node.run_state.

+ James

- Julian

On Wed, Sep 10, 2014 at 10:46 AM, John Warren < " target="_blank"> > wrote:
> Thanks for the reply.  The apparent lack of documentation of node.run_state
> is a bit troubling: the link below is the first Google hit when I search for
> "chef node run_state".  Is there any documentation that discusses
> node.run_state in depth, the way node attributes are discussed, for instance
> here: https://docs.getchef.com/chef_overview_attributes.html ?  You have me
> convinced that node.run_state is kosher, but the people who review my code
> and have already -1'd it (citing the reference below) may not be as easily
> swayed.  Having official documentation that refutes the erroneous heading in
> the referenced official release notes would be most helpful in making my
> case that my code (at least as far as the use of node.run_state goes) is up
> to spec.
>
> Thanks,
>
> John
>
> -----Original Message----- From: Julian C. Dunn
> Sent: Wednesday, September 10, 2014 9:54 AM
> To: " target="_blank">
> Subject: [chef] Re: node.run_state
>
> I think the heading is just wrong. node.run_state is still used (and
> we teach it in Chef Intermediate :-) )
>
> - Julian
>
> On Wed, Sep 10, 2014 at 9:41 AM, John Warren < " target="_blank"> > wrote:
>>
>> The following section in the documentation for Chef client 11 appears to
>> be
>> a source of some confusion:
>>
>> https://docs.getchef.com/breaking_changes_chef_11.html#node-run-state-replaced
>> The heading of the section would seem to indicate that node.run_state
>> should
>> not be used at all anymore, while the section text seems to reference only
>> node.run_state[:seen_recipes] as no longer being valid.  Can I get some
>> clarification on what the status of node.run_state is in terms of having
>> been “replaced” as a whole or in part?
>>
>> Thanks,
>>
>> John
>
>
>
>
> --
> [ Julian C. Dunn < " target="_blank"> >          * Sorry, I'm    ]
> [ WWW: http://www.aquezada.com/staff/julian    * only Web 1.0  ]
> [ gopher://sdf.org/1/users/keymaker/           * compliant!    ]
> [ PGP: 91B3 7A9D 683C 7C16 715F 442C 6065 D533 FDC2 05B9       ]



--
[ Julian C. Dunn < " target="_blank"> >          * Sorry, I'm    ]
[ WWW: http://www.aquezada.com/staff/julian    * only Web 1.0  ]
[ gopher://sdf.org/1/users/keymaker/           * compliant!    ]
[ PGP: 91B3 7A9D 683C 7C16 715F 442C 6065 D533 FDC2 05B9       ]




--
Best regards, Dmitriy V.




--
Best regards, Dmitriy V.




Archive powered by MHonArc 2.6.16.

§