Attributes not getting set from wrapper cookbook


#1

Ohai! Chefs!

Having issues with the attribute while developing wrapper cookbook to
deploy the app cookbook.
Following are the 2 cookbooks to explain the problem.

=================================
app-cookbook

  • attributes
    default[‘asm’][‘user’] = “vagrant”

  • recipes

    • default.rb

    user node[‘asm’][‘user’] do
    password node[‘asm’][‘password’]
    home "/home/#{node[‘asm’][‘user’]}"
    end


app-wrapper-cookbook

  • recipes

    • default.rb

    include_recipe "app-cookbook::default"
    node.set[‘asm’][‘user’] = ‘otheruser’
    =================================

When I run the app-wrapper-cookbook, the attribute set in wrapper
cookbook node.set['asm']['user'] = 'otheruser' doesn’t take effect.
Instead it reads the value vagrant.
It should have been otheruser ?

How to solve this attribute precedence while building the wrapper cookbook ?

@millisami
~Sachin Sagar Rai
Ruby on Rails Developer
http://tfm.com.np
http://nepalonrails.com


#2

Where possible you should try to set the attributes in your wrapper
cookbook’s attributes file, not the recipe itself. It is safe (and
recommended) to do so if you only have app-wrapper-cookbook in your
run list and depend on app-cookbook in metadata; app-cookbook’s
attributes will get loaded first and then overridden by the wrapper.

In the wrapper’s attributes file you need only do

default[‘asm’][‘user’] = ‘otheruser’

There is no need to use “set” priority. “default” will do fine, given
merge order.

Even if you want to change the attribute in recipe context, you are
modifying the attribute in the wrong order. You need to do this before
include_recipe. That’s because include_recipe will compile and add the
user to the resource collection before you’ve had a chance to change
the attribute.

You can read http://www.getchef.com/blog/2013/12/03/doing-wrapper-cookbooks-right/
for more background & guidance on wrapper cookbooks.

regards,
Julian

On Tue, Dec 10, 2013 at 11:37 PM, millisami r millisami@gmail.com wrote:

Ohai! Chefs!

Having issues with the attribute while developing wrapper cookbook to deploy
the app cookbook.
Following are the 2 cookbooks to explain the problem.

=================================
app-cookbook

  • attributes
    default[‘asm’][‘user’] = “vagrant”

  • recipes

    • default.rb

    user node[‘asm’][‘user’] do
    password node[‘asm’][‘password’]
    home "/home/#{node[‘asm’][‘user’]}"
    end


app-wrapper-cookbook

  • recipes

    • default.rb

    include_recipe "app-cookbook::default"
    node.set[‘asm’][‘user’] = ‘otheruser’
    =================================

When I run the app-wrapper-cookbook, the attribute set in wrapper cookbook
node.set['asm']['user'] = 'otheruser' doesn’t take effect.
Instead it reads the value vagrant.
It should have been otheruser ?

How to solve this attribute precedence while building the wrapper cookbook ?

@millisami
~Sachin Sagar Rai
Ruby on Rails Developer
http://tfm.com.np
http://nepalonrails.com


[ Julian C. Dunn jdunn@aquezada.com * 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 ]


#3

Thanks for the reply.
I’ve modified the case below.

=================================
app-cookbook

  • attributes
    default[‘asm’][‘user’] = "vagrant"
    default[‘asm’][‘deploy_to’] = “/home/#{node[‘asm’][‘user’]}/myapp”

  • recipes

    • default.rb

    user node[‘asm’][‘user’] do
    password node[‘asm’][‘password’]
    home "/home/#{node[‘asm’][‘user’]}"
    end


app-wrapper-cookbook

  • recipes
    • default.rb
      node.set[‘asm’][‘user’] = 'otheruser’
      include_recipe “app-cookbook::default”
      =================================

In app-cookbook, I’ve another attribute ['asm']['deploy_to'] which uses
the ['asm']['user'] to interpolate
the value to ['asm']['deploy_to'].

Now running the app-wrapper-cookbook, the value for ['asm']['user'] is
overriden with the value otheruser,
but the value of ['asm']['deploy_to'] still has the vagrant in path.
i.e. It generates /home/vagrant/myapp which should also have been
overridden by /home/otheruser/myapp

Is this the way that computed attributes works?
How chef will resolve such issue?

@millisami
~Sachin Sagar Rai
Ruby on Rails Developer
http://tfm.com.np
http://nepalonrails.com

On Wed, Dec 11, 2013 at 10:44 AM, Julian C. Dunn jdunn@aquezada.com wrote:

Where possible you should try to set the attributes in your wrapper
cookbook’s attributes file, not the recipe itself. It is safe (and
recommended) to do so if you only have app-wrapper-cookbook in your
run list and depend on app-cookbook in metadata; app-cookbook’s
attributes will get loaded first and then overridden by the wrapper.

In the wrapper’s attributes file you need only do

default[‘asm’][‘user’] = ‘otheruser’

There is no need to use “set” priority. “default” will do fine, given
merge order.

Even if you want to change the attribute in recipe context, you are
modifying the attribute in the wrong order. You need to do this before
include_recipe. That’s because include_recipe will compile and add the
user to the resource collection before you’ve had a chance to change
the attribute.

You can read
http://www.getchef.com/blog/2013/12/03/doing-wrapper-cookbooks-right/
for more background & guidance on wrapper cookbooks.

regards,
Julian

On Tue, Dec 10, 2013 at 11:37 PM, millisami r millisami@gmail.com wrote:

Ohai! Chefs!

Having issues with the attribute while developing wrapper cookbook to
deploy
the app cookbook.
Following are the 2 cookbooks to explain the problem.

=================================
app-cookbook

  • attributes
    default[‘asm’][‘user’] = “vagrant”

  • recipes

    • default.rb

    user node[‘asm’][‘user’] do
    password node[‘asm’][‘password’]
    home "/home/#{node[‘asm’][‘user’]}"
    end


app-wrapper-cookbook

  • recipes

    • default.rb

    include_recipe "app-cookbook::default"
    node.set[‘asm’][‘user’] = ‘otheruser’
    =================================

When I run the app-wrapper-cookbook, the attribute set in wrapper
cookbook
node.set['asm']['user'] = 'otheruser' doesn’t take effect.
Instead it reads the value vagrant.
It should have been otheruser ?

How to solve this attribute precedence while building the wrapper
cookbook ?

@millisami
~Sachin Sagar Rai
Ruby on Rails Developer
http://tfm.com.np
http://nepalonrails.com


[ Julian C. Dunn jdunn@aquezada.com * 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 ]


#4

On Wed, Dec 11, 2013 at 3:03 AM, millisami r millisami@gmail.com wrote:

Thanks for the reply.
I’ve modified the case below.

=================================
app-cookbook

  • attributes
    default[‘asm’][‘user’] = "vagrant"
    default[‘asm’][‘deploy_to’] = “/home/#{node[‘asm’][‘user’]}/myapp”

  • recipes

    • default.rb

    user node[‘asm’][‘user’] do
    password node[‘asm’][‘password’]
    home "/home/#{node[‘asm’][‘user’]}"
    end


app-wrapper-cookbook

  • recipes
    • default.rb
      node.set[‘asm’][‘user’] = 'otheruser’
      include_recipe “app-cookbook::default”
      =================================

In app-cookbook, I’ve another attribute ['asm']['deploy_to'] which uses
the ['asm']['user'] to interpolate
the value to ['asm']['deploy_to'].

Now running the app-wrapper-cookbook, the value for ['asm']['user'] is
overriden with the value otheruser,
but the value of ['asm']['deploy_to'] still has the vagrant in path.
i.e. It generates /home/vagrant/myapp which should also have been
overridden by /home/otheruser/myapp

Is this the way that computed attributes works?
How chef will resolve such issue?

Because default[‘asm’][‘deploy_to’] was computed at attribute load
time, you also need to redefine that in your wrapper. I addressed that
in my blog post as well. :slight_smile:

  • Julian


[ Julian C. Dunn jdunn@aquezada.com * 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 ]


#5

I’ve already gone through your blog post as well.

Looks like everyone should define their attributes in a single level.
But what for the cases like below where redefining the attributes that take
multilevel hash.

default['rvm']['user_installs'] = [
  { 'user'          => node['asm']['user'],
    'rubies'        => [node["asm"]["rvm"]["ruby"]],
    'default_ruby'    => node["asm"]["rvm"]["ruby"],
    'global_gems' => [
        { 'name'    => 'bundler' },
        { 'name'    => 'rake',
          'version' => '10.1.0'
        },
        {
          'name' => 'unicorn'
        }
    ]
  }
]

Do I’ve to redefine the whole attributes for
default['rvm']['user_installs'] just to override the
node['asm']['user'] in the wrapper cookbook.

Or is the idea of nesting attributes is wrong?

@millisami
~Sachin Sagar Rai
Ruby on Rails Developer
http://tfm.com.np
http://nepalonrails.com

On Wed, Dec 11, 2013 at 11:00 PM, Julian C. Dunn jdunn@aquezada.com wrote:

On Wed, Dec 11, 2013 at 3:03 AM, millisami r millisami@gmail.com wrote:

Thanks for the reply.
I’ve modified the case below.

=================================
app-cookbook

  • attributes
    default[‘asm’][‘user’] = "vagrant"
    default[‘asm’][‘deploy_to’] = “/home/#{node[‘asm’][‘user’]}/myapp”

  • recipes

    • default.rb

    user node[‘asm’][‘user’] do
    password node[‘asm’][‘password’]
    home "/home/#{node[‘asm’][‘user’]}"
    end


app-wrapper-cookbook

  • recipes
    • default.rb
      node.set[‘asm’][‘user’] = 'otheruser’
      include_recipe “app-cookbook::default”
      =================================

In app-cookbook, I’ve another attribute ['asm']['deploy_to'] which uses
the ['asm']['user'] to interpolate
the value to ['asm']['deploy_to'].

Now running the app-wrapper-cookbook, the value for ['asm']['user']
is
overriden with the value otheruser,
but the value of ['asm']['deploy_to'] still has the vagrant in path.
i.e. It generates /home/vagrant/myapp which should also have been
overridden by /home/otheruser/myapp

Is this the way that computed attributes works?
How chef will resolve such issue?

Because default[‘asm’][‘deploy_to’] was computed at attribute load
time, you also need to redefine that in your wrapper. I addressed that
in my blog post as well. :slight_smile:

  • Julian


[ Julian C. Dunn jdunn@aquezada.com * 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 ]


#6

On Wed, Dec 11, 2013 at 10:05 PM, millisami r millisami@gmail.com wrote:

I’ve already gone through your blog post as well.

Looks like everyone should define their attributes in a single level.
But what for the cases like below where redefining the attributes that take
multilevel hash.

default['rvm']['user_installs'] = [
  { 'user'          => node['asm']['user'],
    'rubies'        => [node["asm"]["rvm"]["ruby"]],
    'default_ruby'    => node["asm"]["rvm"]["ruby"],
    'global_gems' => [
        { 'name'    => 'bundler' },
        { 'name'    => 'rake',
          'version' => '10.1.0'
        },
        {
          'name' => 'unicorn'
        }
    ]
  }
]

Do I’ve to redefine the whole attributes for
default['rvm']['user_installs'] just to override the
node['asm']['user'] in the wrapper cookbook.

Or is the idea of nesting attributes is wrong?

It’s more that things get difficult when you start mixing and matching
types for your attributes. Many people choose to structure their
attributes as hashes only for a number of reasons, merge order and
overriding being one of them.

Another good reason which has nothing to do with Chef is just ease of
reference. For example, how do you easily refer to or find the RVM
user_install for the ASM user above? You’d be forced to grab the
entire array and poke through it.

  • Julian


[ Julian C. Dunn jdunn@aquezada.com * 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 ]


#7

Alright, so the take-away from here is that lets not have the nested
computed attributes.
Just go along plain and simple attributes.
Thnaks

@millisami
~Sachin Sagar Rai
Ruby on Rails Developer
http://tfm.com.np
http://nepalonrails.com

On Thu, Dec 12, 2013 at 9:56 PM, Julian C. Dunn jdunn@aquezada.com wrote:

On Wed, Dec 11, 2013 at 10:05 PM, millisami r millisami@gmail.com wrote:

I’ve already gone through your blog post as well.

Looks like everyone should define their attributes in a single level.
But what for the cases like below where redefining the attributes that
take
multilevel hash.

default['rvm']['user_installs'] = [
  { 'user'          => node['asm']['user'],
    'rubies'        => [node["asm"]["rvm"]["ruby"]],
    'default_ruby'    => node["asm"]["rvm"]["ruby"],
    'global_gems' => [
        { 'name'    => 'bundler' },
        { 'name'    => 'rake',
          'version' => '10.1.0'
        },
        {
          'name' => 'unicorn'
        }
    ]
  }
]

Do I’ve to redefine the whole attributes for
default['rvm']['user_installs'] just to override the
node['asm']['user'] in the wrapper cookbook.

Or is the idea of nesting attributes is wrong?

It’s more that things get difficult when you start mixing and matching
types for your attributes. Many people choose to structure their
attributes as hashes only for a number of reasons, merge order and
overriding being one of them.

Another good reason which has nothing to do with Chef is just ease of
reference. For example, how do you easily refer to or find the RVM
user_install for the ASM user above? You’d be forced to grab the
entire array and poke through it.

  • Julian


[ Julian C. Dunn jdunn@aquezada.com * 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 ]