Recipe attributes: when and how the hell?

Hi guys, about attribute precedence everythin is said but, when the hell
attributes defined on the recipes like the one below are loaded? And how?

node.default[‘autofs’][‘map’][’/mnt/shared’] = ‘shared.map’

On the docs [1], at the “Reset attributes” step (before convergence) it
says: All attributes in the rebuilt node object are reset. All attributes
from recipes, roles, environments, Ohai and attribute files are loaded. All
attributes in the rebuilt node object are updated with the attribute data
according to attribute precedence. When all of the attributes are updated,
the rebuilt node object is complete.

So the interesting part is: “All attributes from RECIPES, roles … are
loaded” so if all attributes are loaded before convergence, why if i set an
attribute on a recipe later in the runlist i cant get that information?

So attributes on recipes are loaded exactly when that piece of the recipe
are executed, on the convergence phase?

Im so confusing about that. I know that lazy works, but if you want to loop
over a list attribute that you are building from other cookbooks i.e.:

  • autofs maps
  • firewall rules
  • snmp mibs
  • selinux policies
  • allowed ssh groups or users
  • … etc…you are stuck!
    Because you need a way to let other cookbooks add rules, maps, mibs, groups
    or whatever, knowing that when shorewal template will be rendered, it will
    be filled with all rules, an so with snmp, sudoers, groups, autofs maps …
    you know whatever !

An explanantion of when and how attributes on recipes are loaded and
merged, will be appreciated. As far as i know, what is written on the docs
are false.

Attributes on recipes doesnt seems to be being loaded before
convergence…but surprise! If you use node.override[‘rules’] << [new
rule]

It seems to works… like on this cookbook [2]

Thanks in advance guys!

[1] - http://docs.opscode.com/essentials_nodes_chef_run.html
[2] - http://community.opscode.com/cookbooks/shorewall

Si necesitas una máquina para hacer algo y no la compras al final te darás
cuenta de que has pagado lo mismo y no tienes la máquina.–Henry Ford

Alberto

Setting attributes in recipe code is subject to typical
compile/converge parsing. Its just ruby code, so if you let an
attribute later in a run in recipe code then there is no way to get it
earlier in the run. There's no magical way to get at attributes that
will be set in recipe code without parsing and executing the ruby code.

Because of compile/converge issues, it is advised to not set attributes
in recipe code. Generally you want to be setting attributes in roles
and attributes files. Setting node attributes in recipes is "code
smell".

The kind of scatter/gather use case that you're trying to do where you
have one resource and you want to build up its arguments across
information gathered from multiple different recipes is actually best
done via a definition that re-opens the resource and not via a node
attribute + LWRP. An example is here:

http://docs.opscode.com/essentials_cookbook_definitions.html

See the "Many Recipes, One Definition" example.

That is a compile-time macro which incrementally builds the argument to
the single template resource in compile mode. The end result is a
single resource placed in the resource collection as early as the first
time you use the definition in your recipes (the template that you
configure will be setup early in the run, rather than where you wind
up going down the LWRP route which is usually to a delayed notification
that edits the file at the end of the run, or that has to use
Chef::Util::FileEdit incrementally throughout the run, which is super
gross).

That'll do what you want, but it requires using a definition which some
people find offensive and unclean, but trying to make LWRPs and node
attributes work is ultimately going to make you sadder.

On Thu Apr 10 10:45:39 2014, aL. wrote:

Hi guys, about attribute precedence everythin is said but, when the
hell attributes defined on the recipes like the one below are loaded?
And how?

node.default['autofs']['map']['/mnt/shared'] = 'shared.map'

On the docs [1], at the "Reset attributes" step (before convergence)
it says: All attributes in the rebuilt node object are reset. All
attributes from recipes, roles, environments, Ohai and attribute files
are loaded. All attributes in the rebuilt node object are updated with
the attribute data according to attribute precedence. When all of the
attributes are updated, the rebuilt node object is complete.

So the interesting part is: "All attributes from RECIPES, roles ......
are loaded" so if all attributes are loaded before convergence, why if
i set an attribute on a recipe later in the runlist i cant get that
information?

So attributes on recipes are loaded exactly when that piece of the
recipe are executed, on the convergence phase?

Im so confusing about that. I know that lazy works, but if you want to
loop over a list attribute that you are building from other cookbooks
i.e.:

  • autofs maps
  • firewall rules
  • snmp mibs
  • selinux policies
  • allowed ssh groups or users
  • .... etc...you are stuck!
    Because you need a way to let other cookbooks add rules, maps, mibs,
    groups or whatever, knowing that when shorewal template will be
    rendered, it will be filled with all rules, an so with snmp, sudoers,
    groups, autofs maps ... you know whatever !

An explanantion of when and how attributes on recipes are loaded and
merged, will be appreciated. As far as i know, what is written on the
docs are false.

Attributes on recipes doesnt seems to be being loaded before
convergence...but surprise! If you use node.override['rules'] << [new
rule]

It seems to works.. like on this cookbook [2]

Thanks in advance guys!

[1] - Chef Infra Client Overview
[2] - http://community.opscode.com/cookbooks/shorewall

Si necesitas una máquina para hacer algo y no la compras al final te
darás cuenta de que has pagado lo mismo y no tienes la máquina.--Henry
Ford

Alberto