Attributes inheritance

Ohai Chefs !

Is there a way in an attribute file to reuse attributes from another file ?

Here is my use case :
I have an application split in two components, each requiring its
configuration.
Most of thetime the configuration of both will be identical but this may
not be always true.
For this reason I’d like to define ‘default’ attributes in the default
attribute file and then have one attribute file per part of my application.
Atribute would be organized this way :
default.rb
default[“myapp”][“conf”] = "XXX"
default[“myapp”][“truc”] = "YYY"
part1.rb
default[“myapp”][“part1”][“conf”] = “XXX1”
#default[“myapp”][“part1”][“truc”] = “YYY” < I want it to default to this
value when not explicitly set
part2.rb
default[“myapp”][“part2”][“conf”] = “XXX2”

Is there a way to achieve this ?
At the moment I am using global variable to pass information from one file
to the other but this seams ugly to me.


Dorian JAMINAIS
System Administrator
+33 6 95 10 95 37
http://perfect-memory.com

https://twitter.com/semanticbushttp://www.facebook.com/pages/Perfect-Memory/155555567821817

I’m not sure I understand your problem, but at first sight it seems like you could use node.set in the recipes:

attributes/default.rb
default[“myapp”][“conf”] = "XXX"
default[“myapp”][“truc”] = “YYY”

recipes/part1.rb
node.set[“myapp”][“conf”] = XXX1

recipes/part2.rb
node.set[“myapp”][“conf”] = XXX2


Cassiano Leal
http://cassianoleal.com
http://twitter.com/cassianoleal

On July 22, 2013 at 14:16:26, Dorian Jaminais (dorian.jaminais@perfect-memory.com) wrote:

Ohai Chefs !

Is there a way in an attribute file to reuse attributes from another file ?

Here is my use case :
I have an application split in two components, each requiring its configuration.
Most of thetime the configuration of both will be identical but this may not be always true.
For this reason I’d like to define ‘default’ attributes in the default attribute file and then have one attribute file per part of my application. Atribute would be organized this way :
default.rb
default[“myapp”][“conf”] = "XXX"
default[“myapp”][“truc”] = "YYY"
part1.rb
default[“myapp”][“part1”][“conf”] = “XXX1”
#default[“myapp”][“part1”][“truc”] = “YYY” < I want it to default to this value when not explicitly set
part2.rb
default[“myapp”][“part2”][“conf”] = “XXX2”

Is there a way to achieve this ?
At the moment I am using global variable to pass information from one file to the other but this seams ugly to me.


Dorian JAMINAIS
System Administrator
+33 6 95 10 95 37

On Monday, July 22, 2013 at 10:15 AM, Dorian Jaminais wrote:

Ohai Chefs !

Is there a way in an attribute file to reuse attributes from another file ?

Here is my use case :
I have an application split in two components, each requiring its configuration.
Most of thetime the configuration of both will be identical but this may not be always true.
For this reason I’d like to define ‘default’ attributes in the default attribute file and then have one attribute file per part of my application. Atribute would be organized this way :
default.rb
default[“myapp”][“conf”] = "XXX"
default[“myapp”][“truc”] = "YYY"
part1.rb
default[“myapp”][“part1”][“conf”] = “XXX1”
#default[“myapp”][“part1”][“truc”] = “YYY” < I want it to default to this value when not explicitly set
part2.rb
default[“myapp”][“part2”][“conf”] = “XXX2”

Is there a way to achieve this ?
At the moment I am using global variable to pass information from one file to the other but this seams ugly to me.
Split the shared part out into another cookbook?


Daniel DeLeo

I would set this in the component’s recipe:

node.normal[:myapp][:part1][:conf] ||= “XXX1”

||= will only set the attribute if the attribute has not yet been set.

On Mon, Jul 22, 2013 at 5:08 PM, Daniel DeLeo dan@kallistec.com wrote:

On Monday, July 22, 2013 at 10:15 AM, Dorian Jaminais wrote:

Ohai Chefs !

Is there a way in an attribute file to reuse attributes from another file ?

Here is my use case :
I have an application split in two components, each requiring its
configuration.
Most of thetime the configuration of both will be identical but this may
not be always true.
For this reason I’d like to define ‘default’ attributes in the default
attribute file and then have one attribute file per part of my application.
Atribute would be organized this way :
default.rb
default[“myapp”][“conf”] = "XXX"
default[“myapp”][“truc”] = "YYY"
part1.rb
default[“myapp”][“part1”][“conf”] = “XXX1”
#default[“myapp”][“part1”][“truc”] = “YYY” < I want it to default to
this value when not explicitly set
part2.rb
default[“myapp”][“part2”][“conf”] = “XXX2”

Is there a way to achieve this ?
At the moment I am using global variable to pass information from one file
to the other but this seams ugly to me.

Split the shared part out into another cookbook?


Daniel DeLeo

@Josiah : Thanks for the tip, I didn’t know about the ||= operator.

I was looking for a way to do that using the attribute files.
Based on your response, my new work around is to define the component’s
attributes in two different hashes and have them merge into the default one.

Thanks

2013/7/23 Josiah Kiehl bluepojo@gmail.com

I would set this in the component’s recipe:

node.normal[:myapp][:part1][:conf] ||= “XXX1”

||= will only set the attribute if the attribute has not yet been set.

On Mon, Jul 22, 2013 at 5:08 PM, Daniel DeLeo dan@kallistec.com wrote:

On Monday, July 22, 2013 at 10:15 AM, Dorian Jaminais wrote:

Ohai Chefs !

Is there a way in an attribute file to reuse attributes from another file
?

Here is my use case :
I have an application split in two components, each requiring its
configuration.
Most of thetime the configuration of both will be identical but this may
not be always true.
For this reason I’d like to define ‘default’ attributes in the default
attribute file and then have one attribute file per part of my application.
Atribute would be organized this way :
default.rb
default[“myapp”][“conf”] = "XXX"
default[“myapp”][“truc”] = "YYY"
part1.rb
default[“myapp”][“part1”][“conf”] = “XXX1”
#default[“myapp”][“part1”][“truc”] = “YYY” < I want it to default to
this value when not explicitly set
part2.rb
default[“myapp”][“part2”][“conf”] = “XXX2”

Is there a way to achieve this ?
At the moment I am using global variable to pass information from one
file to the other but this seams ugly to me.

Split the shared part out into another cookbook?


Daniel DeLeo


Dorian JAMINAIS
System Administrator
+33 6 95 10 95 37
http://perfect-memory.com

https://twitter.com/semanticbushttp://www.facebook.com/pages/Perfect-Memory/155555567821817

I don’t think that’ll work if the default has been set.

What I mean is, say you have:

node.default[:myapp][:part1][:conf] = ‘XXX’
node.set[:myapp][:part1][:conf] ||= ‘XXX1’

This will probably set node[:myapp][:part1][:conf] to ‘XXX1’, since node.set[:myapp][:part1][:conf] was nil when the ||= operator kicked in.

I might be wrong and Chef might be doing some sourcery behind the scenes, but taking only Ruby into account, it wouldn’t work.


Cassiano Leal
http://cassianoleal.com
http://twitter.com/cassianoleal

On July 23, 2013 at 05:21:59, Dorian Jaminais (dorian.jaminais@perfect-memory.com) wrote:

@Josiah : Thanks for the tip, I didn’t know about the ||= operator.

I was looking for a way to do that using the attribute files.
Based on your response, my new work around is to define the component’s attributes in two different hashes and have them merge into the default one.

Thanks

2013/7/23 Josiah Kiehl bluepojo@gmail.com
I would set this in the component’s recipe:

node.normal[:myapp][:part1][:conf] ||= “XXX1”

||= will only set the attribute if the attribute has not yet been set.

On Mon, Jul 22, 2013 at 5:08 PM, Daniel DeLeo dan@kallistec.com wrote:

On Monday, July 22, 2013 at 10:15 AM, Dorian Jaminais wrote:

Ohai Chefs !

Is there a way in an attribute file to reuse attributes from another file ?

Here is my use case :
I have an application split in two components, each requiring its configuration.
Most of thetime the configuration of both will be identical but this may not be always true.
For this reason I’d like to define ‘default’ attributes in the default attribute file and then have one attribute file per part of my application. Atribute would be organized this way :
default.rb
default[“myapp”][“conf”] = "XXX"
default[“myapp”][“truc”] = "YYY"
part1.rb
default[“myapp”][“part1”][“conf”] = “XXX1”
#default[“myapp”][“part1”][“truc”] = “YYY” < I want it to default to this value when not explicitly set
part2.rb
default[“myapp”][“part2”][“conf”] = “XXX2”

Is there a way to achieve this ?
At the moment I am using global variable to pass information from one file to the other but this seams ugly to me.
Split the shared part out into another cookbook?


Daniel DeLeo


Dorian JAMINAIS
System Administrator
+33 6 95 10 95 37

Actually it works but I put the ||= operator in the recipe file and it
works as expected

2013/7/23 Cassiano Leal cassianoleal@gmail.com

I don’t think that’ll work if the default has been set.

What I mean is, say you have:

node.default[:myapp][:part1][:conf] = ‘XXX’

node.set[:myapp][:part1][:conf] ||= ‘XXX1’

This will probably set node[:myapp][:part1][:conf] to ‘XXX1’, since
node.set[:myapp][:part1][:conf] was nil when the ||= operator kicked in.

I might be wrong and Chef might be doing some sourcery behind the scenes,
but taking only Ruby into account, it wouldn’t work.


Cassiano Leal
http://cassianoleal.com
http://twitter.com/cassianoleal

On July 23, 2013 at 05:21:59, Dorian Jaminais (
dorian.jaminais@perfect-memory.com) wrote:

@Josiah : Thanks for the tip, I didn’t know about the ||= operator.

I was looking for a way to do that using the attribute files.
Based on your response, my new work around is to define the component’s
attributes in two different hashes and have them merge into the default one.

Thanks

2013/7/23 Josiah Kiehl bluepojo@gmail.com

I would set this in the component’s recipe:

node.normal[:myapp][:part1][:conf] ||= “XXX1”

||= will only set the attribute if the attribute has not yet been set.

On Mon, Jul 22, 2013 at 5:08 PM, Daniel DeLeo dan@kallistec.com wrote:

On Monday, July 22, 2013 at 10:15 AM, Dorian Jaminais wrote:

Ohai Chefs !

Is there a way in an attribute file to reuse attributes from another
file ?

Here is my use case :
I have an application split in two components, each requiring its
configuration.
Most of thetime the configuration of both will be identical but this may
not be always true.
For this reason I’d like to define ‘default’ attributes in the default
attribute file and then have one attribute file per part of my application.
Atribute would be organized this way :
default.rb
default[“myapp”][“conf”] = "XXX"
default[“myapp”][“truc”] = "YYY"
part1.rb
default[“myapp”][“part1”][“conf”] = “XXX1”
#default[“myapp”][“part1”][“truc”] = “YYY” < I want it to default to
this value when not explicitly set
part2.rb
default[“myapp”][“part2”][“conf”] = “XXX2”

Is there a way to achieve this ?
At the moment I am using global variable to pass information from one
file to the other but this seams ugly to me.

Split the shared part out into another cookbook?


Daniel DeLeo


Dorian JAMINAIS
System Administrator
+33 6 95 10 95 37
http://perfect-memory.com

https://twitter.com/semanticbushttp://www.facebook.com/pages/Perfect-Memory/155555567821817


Dorian JAMINAIS
System Administrator
+33 6 95 10 95 37
http://perfect-memory.com

https://twitter.com/semanticbushttp://www.facebook.com/pages/Perfect-Memory/155555567821817

Nice, so Chef really is doing something behind the scenes. Good to know! :slight_smile:


Cassiano Leal
http://cassianoleal.com
http://twitter.com/cassianoleal

On July 23, 2013 at 09:38:26, Dorian Jaminais (dorian.jaminais@perfect-memory.com) wrote:

Actually it works but I put the ||= operator in the recipe file and it works as expected

2013/7/23 Cassiano Leal cassianoleal@gmail.com
I don’t think that’ll work if the default has been set.

What I mean is, say you have:

node.default[:myapp][:part1][:conf] = ‘XXX’
node.set[:myapp][:part1][:conf] ||= ‘XXX1’

This will probably set node[:myapp][:part1][:conf] to ‘XXX1’, since node.set[:myapp][:part1][:conf] was nil when the ||= operator kicked in.

I might be wrong and Chef might be doing some sourcery behind the scenes, but taking only Ruby into account, it wouldn’t work.


Cassiano Leal
http://cassianoleal.com
http://twitter.com/cassianoleal

On July 23, 2013 at 05:21:59, Dorian Jaminais (dorian.jaminais@perfect-memory.com) wrote:

@Josiah : Thanks for the tip, I didn’t know about the ||= operator.

I was looking for a way to do that using the attribute files.
Based on your response, my new work around is to define the component’s attributes in two different hashes and have them merge into the default one.

Thanks

2013/7/23 Josiah Kiehl bluepojo@gmail.com
I would set this in the component’s recipe:

node.normal[:myapp][:part1][:conf] ||= “XXX1”

||= will only set the attribute if the attribute has not yet been set.

On Mon, Jul 22, 2013 at 5:08 PM, Daniel DeLeo dan@kallistec.com wrote:

On Monday, July 22, 2013 at 10:15 AM, Dorian Jaminais wrote:

Ohai Chefs !

Is there a way in an attribute file to reuse attributes from another file ?

Here is my use case :
I have an application split in two components, each requiring its configuration.
Most of thetime the configuration of both will be identical but this may not be always true.
For this reason I’d like to define ‘default’ attributes in the default attribute file and then have one attribute file per part of my application. Atribute would be organized this way :
default.rb
default[“myapp”][“conf”] = "XXX"
default[“myapp”][“truc”] = "YYY"
part1.rb
default[“myapp”][“part1”][“conf”] = “XXX1”
#default[“myapp”][“part1”][“truc”] = “YYY” < I want it to default to this value when not explicitly set
part2.rb
default[“myapp”][“part2”][“conf”] = “XXX2”

Is there a way to achieve this ?
At the moment I am using global variable to pass information from one file to the other but this seams ugly to me.
Split the shared part out into another cookbook?


Daniel DeLeo


Dorian JAMINAIS
System Administrator
+33 6 95 10 95 37


Dorian JAMINAIS
System Administrator
+33 6 95 10 95 37

chef-shell will free your mind…

$ chef-shell -s

chef > recipe_mode
chef:recipe > node.default[‘noxexistent’].class
=> Chef::Node::VividMash

When you access an attribute that does not exist from a recipe, it returns
as an empty Chef::Node::VividMash object, not nil.
This is why your ‘or’ statement is failing =)

Some other trivia: ‘node.set’ is the same as ‘node.normal’.

chef:recipe > node.default[‘foo’] = “bar”
=> "bar"
chef:recipe > node[‘foo’]
=> "bar"
chef:recipe > node.normal[‘foo’] = “baz”
=> "baz"
chef:recipe > node[‘foo’]
=> "baz"
chef:recipe > node.override[‘foo’] = “biz”
=> "biz"
chef:recipe > node[‘foo’]
=> “biz”

Yet, all three are actually persisted on the node object

chef:recipe > node.default[‘foo’]
=> "bar"
chef:recipe > node.normal[‘foo’]
=> "baz"
chef:recipe > node.override[‘foo’]
=> “biz”

The chef-client only consumes the one with the highest precedence.

-s

On Tue, Jul 23, 2013 at 8:16 AM, Cassiano Leal cassianoleal@gmail.comwrote:

I don’t think that’ll work if the default has been set.

What I mean is, say you have:

node.default[:myapp][:part1][:conf] = ‘XXX’

node.set[:myapp][:part1][:conf] ||= ‘XXX1’

This will probably set node[:myapp][:part1][:conf] to ‘XXX1’, since
node.set[:myapp][:part1][:conf] was nil when the ||= operator kicked in.

I might be wrong and Chef might be doing some sourcery behind the scenes,
but taking only Ruby into account, it wouldn’t work.


Cassiano Leal
http://cassianoleal.com
http://twitter.com/cassianoleal

On July 23, 2013 at 05:21:59, Dorian Jaminais (
dorian.jaminais@perfect-memory.com) wrote:

@Josiah : Thanks for the tip, I didn’t know about the ||= operator.

I was looking for a way to do that using the attribute files.
Based on your response, my new work around is to define the component’s
attributes in two different hashes and have them merge into the default one.

Thanks

2013/7/23 Josiah Kiehl bluepojo@gmail.com

I would set this in the component’s recipe:

node.normal[:myapp][:part1][:conf] ||= “XXX1”

||= will only set the attribute if the attribute has not yet been set.

On Mon, Jul 22, 2013 at 5:08 PM, Daniel DeLeo dan@kallistec.com wrote:

On Monday, July 22, 2013 at 10:15 AM, Dorian Jaminais wrote:

Ohai Chefs !

Is there a way in an attribute file to reuse attributes from another
file ?

Here is my use case :
I have an application split in two components, each requiring its
configuration.
Most of thetime the configuration of both will be identical but this may
not be always true.
For this reason I’d like to define ‘default’ attributes in the default
attribute file and then have one attribute file per part of my application.
Atribute would be organized this way :
default.rb
default[“myapp”][“conf”] = "XXX"
default[“myapp”][“truc”] = "YYY"
part1.rb
default[“myapp”][“part1”][“conf”] = “XXX1”
#default[“myapp”][“part1”][“truc”] = “YYY” < I want it to default to
this value when not explicitly set
part2.rb
default[“myapp”][“part2”][“conf”] = “XXX2”

Is there a way to achieve this ?
At the moment I am using global variable to pass information from one
file to the other but this seams ugly to me.

Split the shared part out into another cookbook?


Daniel DeLeo


Dorian JAMINAIS
System Administrator
+33 6 95 10 95 37
http://perfect-memory.com

https://twitter.com/semanticbushttp://www.facebook.com/pages/Perfect-Memory/155555567821817

Also, here's a handy chart
http://docs.opscode.com/_images/overview_chef_attributes_table.png

On Tue, Jul 23, 2013 at 8:56 AM, Sean OMeara someara@gmail.com wrote:

chef-shell will free your mind...

$ chef-shell -s

chef > recipe_mode
chef:recipe > node.default['noxexistent'].class
=> Chef::Node::VividMash

When you access an attribute that does not exist from a recipe, it returns
as an empty Chef::Node::VividMash object, not nil.
This is why your 'or' statement is failing =)

Some other trivia: 'node.set' is the same as 'node.normal'.

chef:recipe > node.default['foo'] = "bar"
=> "bar"
chef:recipe > node['foo']
=> "bar"
chef:recipe > node.normal['foo'] = "baz"
=> "baz"
chef:recipe > node['foo']
=> "baz"
chef:recipe > node.override['foo'] = "biz"
=> "biz"
chef:recipe > node['foo']
=> "biz"

Yet, all three are actually persisted on the node object

chef:recipe > node.default['foo']
=> "bar"
chef:recipe > node.normal['foo']
=> "baz"
chef:recipe > node.override['foo']
=> "biz"

The chef-client only consumes the one with the highest precedence.

-s

On Tue, Jul 23, 2013 at 8:16 AM, Cassiano Leal cassianoleal@gmail.comwrote:

I don’t think that’ll work if the default has been set.

What I mean is, say you have:

node.default[:myapp][:part1][:conf] = ‘XXX’

node.set[:myapp][:part1][:conf] ||= ‘XXX1’

This will probably set node[:myapp][:part1][:conf] to ‘XXX1’, since
node.set[:myapp][:part1][:conf] was nil when the ||= operator kicked in.

I might be wrong and Chef might be doing some sourcery behind the scenes,
but taking only Ruby into account, it wouldn’t work.

--
Cassiano Leal
http://cassianoleal.com
http://twitter.com/cassianoleal

On July 23, 2013 at 05:21:59, Dorian Jaminais (
dorian.jaminais@perfect-memory.com) wrote:

@Josiah : Thanks for the tip, I didn't know about the ||= operator.

I was looking for a way to do that using the attribute files.
Based on your response, my new work around is to define the component's
attributes in two different hashes and have them merge into the default one.

Thanks

2013/7/23 Josiah Kiehl bluepojo@gmail.com

I would set this in the component's recipe:

node.normal[:myapp][:part1][:conf] ||= "XXX1"

||= will only set the attribute if the attribute has not yet been set.

On Mon, Jul 22, 2013 at 5:08 PM, Daniel DeLeo dan@kallistec.com wrote:

On Monday, July 22, 2013 at 10:15 AM, Dorian Jaminais wrote:

Ohai Chefs !

Is there a way in an attribute file to reuse attributes from another
file ?

Here is my use case :
I have an application split in two components, each requiring its
configuration.
Most of thetime the configuration of both will be identical but this
may not be always true.
For this reason I'd like to define 'default' attributes in the default
attribute file and then have one attribute file per part of my application.
Atribute would be organized this way :
default.rb
default["myapp"]["conf"] = "XXX"
default["myapp"]["truc"] = "YYY"
part1.rb
default["myapp"]["part1"]["conf"] = "XXX1"
#default["myapp"]["part1"]["truc"] = "YYY" < I want it to default to
this value when not explicitly set
part2.rb
default["myapp"]["part2"]["conf"] = "XXX2"

Is there a way to achieve this ?
At the moment I am using global variable to pass information from one
file to the other but this seams ugly to me.

Split the shared part out into another cookbook?

--
Daniel DeLeo

--
Dorian JAMINAIS
System Administrator
+33 6 95 10 95 37
http://perfect-memory.com

https://twitter.com/semanticbushttp://www.facebook.com/pages/Perfect-Memory/155555567821817

I see. So Dorian’s problem would probably be best solved by using

node.normal[:myapp][:part1][:conf] = “XXX1” unless node[:myapp][:part1][:conf]

Right?


Cassiano Leal
http://cassianoleal.com
http://twitter.com/cassianoleal

On July 23, 2013 at 09:56:38, Sean OMeara (someara@gmail.com) wrote:

chef-shell will free your mind…

$ chef-shell -s

chef > recipe_mode
chef:recipe > node.default[‘noxexistent’].class
=> Chef::Node::VividMash

When you access an attribute that does not exist from a recipe, it returns as an empty Chef::Node::VividMash object, not nil.
This is why your ‘or’ statement is failing =)

Some other trivia: ‘node.set’ is the same as ‘node.normal’.

chef:recipe > node.default[‘foo’] = “bar”
=> "bar"
chef:recipe > node[‘foo’]
=> "bar"
chef:recipe > node.normal[‘foo’] = “baz”
=> "baz"
chef:recipe > node[‘foo’]
=> "baz"
chef:recipe > node.override[‘foo’] = “biz”
=> "biz"
chef:recipe > node[‘foo’]
=> “biz”

Yet, all three are actually persisted on the node object

chef:recipe > node.default[‘foo’]
=> "bar"
chef:recipe > node.normal[‘foo’]
=> "baz"
chef:recipe > node.override[‘foo’]
=> “biz”

The chef-client only consumes the one with the highest precedence.

-s

On Tue, Jul 23, 2013 at 8:16 AM, Cassiano Leal cassianoleal@gmail.com wrote:
I don’t think that’ll work if the default has been set.

What I mean is, say you have:

node.default[:myapp][:part1][:conf] = ‘XXX’
node.set[:myapp][:part1][:conf] ||= ‘XXX1’

This will probably set node[:myapp][:part1][:conf] to ‘XXX1’, since node.set[:myapp][:part1][:conf] was nil when the ||= operator kicked in.

I might be wrong and Chef might be doing some sourcery behind the scenes, but taking only Ruby into account, it wouldn’t work.


Cassiano Leal
http://cassianoleal.com
http://twitter.com/cassianoleal

On July 23, 2013 at 05:21:59, Dorian Jaminais (dorian.jaminais@perfect-memory.com) wrote:

@Josiah : Thanks for the tip, I didn’t know about the ||= operator.

I was looking for a way to do that using the attribute files.
Based on your response, my new work around is to define the component’s attributes in two different hashes and have them merge into the default one.

Thanks

2013/7/23 Josiah Kiehl bluepojo@gmail.com
I would set this in the component’s recipe:

node.normal[:myapp][:part1][:conf] ||= “XXX1”

||= will only set the attribute if the attribute has not yet been set.

On Mon, Jul 22, 2013 at 5:08 PM, Daniel DeLeo dan@kallistec.com wrote:

On Monday, July 22, 2013 at 10:15 AM, Dorian Jaminais wrote:

Ohai Chefs !

Is there a way in an attribute file to reuse attributes from another file ?

Here is my use case :
I have an application split in two components, each requiring its configuration.
Most of thetime the configuration of both will be identical but this may not be always true.
For this reason I’d like to define ‘default’ attributes in the default attribute file and then have one attribute file per part of my application. Atribute would be organized this way :
default.rb
default[“myapp”][“conf”] = "XXX"
default[“myapp”][“truc”] = "YYY"
part1.rb
default[“myapp”][“part1”][“conf”] = “XXX1”
#default[“myapp”][“part1”][“truc”] = “YYY” < I want it to default to this value when not explicitly set
part2.rb
default[“myapp”][“part2”][“conf”] = “XXX2”

Is there a way to achieve this ?
At the moment I am using global variable to pass information from one file to the other but this seams ugly to me.
Split the shared part out into another cookbook?


Daniel DeLeo


Dorian JAMINAIS
System Administrator
+33 6 95 10 95 37

When I started seeing people using ||= (pipe-pipe-equals), I thought it was
the coolest thing since:

variable = logical statement ? a : b

But it would get funny sometimes and then I came across this article, which
totally melted my brain:

http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html

Since then, I have (grudgingly) developed a new appreciation for set_unless.

On Tue, Jul 23, 2013 at 12:31 PM, Cassiano Leal cassianoleal@gmail.comwrote:

I see. So Dorian’s problem would probably be best solved by using

node.normal[:myapp][:part1][:conf] = “XXX1” unless
node[:myapp][:part1][:conf]

Right?


Cassiano Leal
http://cassianoleal.com
http://twitter.com/cassianoleal

On July 23, 2013 at 09:56:38, Sean OMeara (someara@gmail.com) wrote:

chef-shell will free your mind…

$ chef-shell -s

chef > recipe_mode
chef:recipe > node.default[‘noxexistent’].class
=> Chef::Node::VividMash

When you access an attribute that does not exist from a recipe, it returns
as an empty Chef::Node::VividMash object, not nil.
This is why your ‘or’ statement is failing =)

Some other trivia: ‘node.set’ is the same as ‘node.normal’.

chef:recipe > node.default[‘foo’] = “bar”
=> "bar"
chef:recipe > node[‘foo’]
=> "bar"
chef:recipe > node.normal[‘foo’] = “baz”
=> "baz"
chef:recipe > node[‘foo’]
=> "baz"
chef:recipe > node.override[‘foo’] = “biz”
=> "biz"
chef:recipe > node[‘foo’]
=> “biz”

Yet, all three are actually persisted on the node object

chef:recipe > node.default[‘foo’]
=> "bar"
chef:recipe > node.normal[‘foo’]
=> "baz"
chef:recipe > node.override[‘foo’]
=> “biz”

The chef-client only consumes the one with the highest precedence.

-s

On Tue, Jul 23, 2013 at 8:16 AM, Cassiano Leal cassianoleal@gmail.comwrote:

I don’t think that’ll work if the default has been set.

What I mean is, say you have:

node.default[:myapp][:part1][:conf] = ‘XXX’

node.set[:myapp][:part1][:conf] ||= ‘XXX1’

This will probably set node[:myapp][:part1][:conf] to ‘XXX1’, since
node.set[:myapp][:part1][:conf] was nil when the ||= operator kicked in.

I might be wrong and Chef might be doing some sourcery behind the scenes,
but taking only Ruby into account, it wouldn’t work.


Cassiano Leal
http://cassianoleal.com
http://twitter.com/cassianoleal

On July 23, 2013 at 05:21:59, Dorian Jaminais (
dorian.jaminais@perfect-memory.com) wrote:

@Josiah : Thanks for the tip, I didn’t know about the ||= operator.

I was looking for a way to do that using the attribute files.
Based on your response, my new work around is to define the component’s
attributes in two different hashes and have them merge into the default one.

Thanks

2013/7/23 Josiah Kiehl bluepojo@gmail.com

I would set this in the component’s recipe:

node.normal[:myapp][:part1][:conf] ||= “XXX1”

||= will only set the attribute if the attribute has not yet been set.

On Mon, Jul 22, 2013 at 5:08 PM, Daniel DeLeo dan@kallistec.com wrote:

On Monday, July 22, 2013 at 10:15 AM, Dorian Jaminais wrote:

Ohai Chefs !

Is there a way in an attribute file to reuse attributes from another
file ?

Here is my use case :
I have an application split in two components, each requiring its
configuration.
Most of thetime the configuration of both will be identical but this
may not be always true.
For this reason I’d like to define ‘default’ attributes in the default
attribute file and then have one attribute file per part of my application.
Atribute would be organized this way :
default.rb
default[“myapp”][“conf”] = "XXX"
default[“myapp”][“truc”] = "YYY"
part1.rb
default[“myapp”][“part1”][“conf”] = “XXX1”
#default[“myapp”][“part1”][“truc”] = “YYY” < I want it to default to
this value when not explicitly set
part2.rb
default[“myapp”][“part2”][“conf”] = “XXX2”

Is there a way to achieve this ?
At the moment I am using global variable to pass information from one
file to the other but this seams ugly to me.

Split the shared part out into another cookbook?


Daniel DeLeo


Dorian JAMINAIS
System Administrator
+33 6 95 10 95 37
http://perfect-memory.com

https://twitter.com/semanticbushttp://www.facebook.com/pages/Perfect-Memory/155555567821817

Nice article. I’m a Ruby dev, so it didn’t really present me with anything new, but it’s got great information summarised in a nice way.

I use ||= all the time when programming in Ruby. It’s a great shortcut for memoisation and some logical operations.

The article is a great reminder that you need to understand how it works before using it everywhere, though. :slight_smile:


Cassiano Leal
http://cassianoleal.com
http://twitter.com/cassianoleal

On July 24, 2013 at 03:19:30, steve . (leftathome@gmail.com) wrote:

When I started seeing people using ||= (pipe-pipe-equals), I thought it was the coolest thing since:

variable = logical statement ? a : b

But it would get funny sometimes and then I came across this article, which totally melted my brain:

http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html

Since then, I have (grudgingly) developed a new appreciation for set_unless.

On Tue, Jul 23, 2013 at 12:31 PM, Cassiano Leal cassianoleal@gmail.com wrote:
I see. So Dorian’s problem would probably be best solved by using

node.normal[:myapp][:part1][:conf] = “XXX1” unless node[:myapp][:part1][:conf]

Right?


Cassiano Leal
http://cassianoleal.com
http://twitter.com/cassianoleal

On July 23, 2013 at 09:56:38, Sean OMeara (someara@gmail.com) wrote:

chef-shell will free your mind…

$ chef-shell -s

chef > recipe_mode
chef:recipe > node.default[‘noxexistent’].class
=> Chef::Node::VividMash

When you access an attribute that does not exist from a recipe, it returns as an empty Chef::Node::VividMash object, not nil.
This is why your ‘or’ statement is failing =)

Some other trivia: ‘node.set’ is the same as ‘node.normal’.

chef:recipe > node.default[‘foo’] = “bar”
=> "bar"
chef:recipe > node[‘foo’]
=> "bar"
chef:recipe > node.normal[‘foo’] = “baz”
=> "baz"
chef:recipe > node[‘foo’]
=> "baz"
chef:recipe > node.override[‘foo’] = “biz”
=> "biz"
chef:recipe > node[‘foo’]
=> “biz”

Yet, all three are actually persisted on the node object

chef:recipe > node.default[‘foo’]
=> "bar"
chef:recipe > node.normal[‘foo’]
=> "baz"
chef:recipe > node.override[‘foo’]
=> “biz”

The chef-client only consumes the one with the highest precedence.

-s

On Tue, Jul 23, 2013 at 8:16 AM, Cassiano Leal cassianoleal@gmail.com wrote:
I don’t think that’ll work if the default has been set.

What I mean is, say you have:

node.default[:myapp][:part1][:conf] = ‘XXX’
node.set[:myapp][:part1][:conf] ||= ‘XXX1’

This will probably set node[:myapp][:part1][:conf] to ‘XXX1’, since node.set[:myapp][:part1][:conf] was nil when the ||= operator kicked in.

I might be wrong and Chef might be doing some sourcery behind the scenes, but taking only Ruby into account, it wouldn’t work.


Cassiano Leal
http://cassianoleal.com
http://twitter.com/cassianoleal

On July 23, 2013 at 05:21:59, Dorian Jaminais (dorian.jaminais@perfect-memory.com) wrote:

@Josiah : Thanks for the tip, I didn’t know about the ||= operator.

I was looking for a way to do that using the attribute files.
Based on your response, my new work around is to define the component’s attributes in two different hashes and have them merge into the default one.

Thanks

2013/7/23 Josiah Kiehl bluepojo@gmail.com
I would set this in the component’s recipe:

node.normal[:myapp][:part1][:conf] ||= “XXX1”

||= will only set the attribute if the attribute has not yet been set.

On Mon, Jul 22, 2013 at 5:08 PM, Daniel DeLeo dan@kallistec.com wrote:

On Monday, July 22, 2013 at 10:15 AM, Dorian Jaminais wrote:

Ohai Chefs !

Is there a way in an attribute file to reuse attributes from another file ?

Here is my use case :
I have an application split in two components, each requiring its configuration.
Most of thetime the configuration of both will be identical but this may not be always true.
For this reason I’d like to define ‘default’ attributes in the default attribute file and then have one attribute file per part of my application. Atribute would be organized this way :
default.rb
default[“myapp”][“conf”] = "XXX"
default[“myapp”][“truc”] = "YYY"
part1.rb
default[“myapp”][“part1”][“conf”] = “XXX1”
#default[“myapp”][“part1”][“truc”] = “YYY” < I want it to default to this value when not explicitly set
part2.rb
default[“myapp”][“part2”][“conf”] = “XXX2”

Is there a way to achieve this ?
At the moment I am using global variable to pass information from one file to the other but this seams ugly to me.
Split the shared part out into another cookbook?


Daniel DeLeo


Dorian JAMINAIS
System Administrator
+33 6 95 10 95 37

On Wednesday, July 24, 2013 at 5:56 AM, Cassiano Leal wrote:

Nice article. I’m a Ruby dev, so it didn’t really present me with anything new, but it’s got great information summarised in a nice way.

I use ||= all the time when programming in Ruby. It’s a great shortcut for memoisation and some logical operations.

The article is a great reminder that you need to understand how it works before using it everywhere, though. :slight_smile:
Generally ||= is fine (though not thread safe, if you’re writing a threaded application–not a big deal for chef code though). The problem with using it with node attributes is that it’s incompatible with the “auto-vivify” feature. Auto-vivify is the thing that lets you write node.default[:foo][:bar][:baz] = “qux” when none of the intermediate hashes exist. Behind the scenes, chef is creating a new mash each time you access a key that does not exist. This is different from regular ruby code where the default behavior when accessing a key that doesn’t exist is to return nil[1] which is a “falsey” value. For this reason, default_unless and other _unless methods are provided to give you ||= type behavior.


Daniel DeLeo

  1. In regular ruby, you can change the default behavior of hashes when accessing missing keys by passing a block to Hash.new. For example, if you want to inflict code rage on someone, you could stick this in their code base:

chef > h = Hash.new {|h,k| true }
=> {}
chef > h[:foo]
=> true
chef > h[:foo] ||= “bar”
=> true
chef > h
=> {}