Node attributes used different in chef-client 13?


#1

Hello guys,

Some time ago i’ve created a recipe that had something like this:

  masters.each do |nodeobj|
    Chef::Log.warn("nodeobj: #{nodeobj}")
    master_ip << nodeobj.node.ipaddress
    master_hostname << nodeobj.node.name
  end

It was working properly on any chef-client up to version 13

On chef-client 13, I got this error:

NoMethodError
-------------
undefined method `ipaddress' for #<Chef::Node::Attribute:0x0000000004e28700>

Cookbook Trace:
---------------
  /var/chef/cache/cookbooks/cookbook_new/recipes/default.rb:21:in `block in from_file'
  /var/chef/cache/cookbooks/cookbook_new/recipes/default.rb:19:in `each'
  /var/chef/cache/cookbooks/cookbook_new/recipes/default.rb:19:in `from_file'

Relevant File Content:
----------------------
/var/chef/cache/cookbook_new/recipes/default.rb:

 14:  if masters.empty? || !masters.any?
 15:    Chef::Log.warn("Cannot find any master!")
 16:    # master_ip << node['ipaddress']
 17:    # master_hostname << node['name']
 18:  else
 19:    masters.each do |nodeobj|
 20:      Chef::Log.warn("nodeobj: #{nodeobj}")
 21>>     master_ip << nodeobj.node.ipaddress
 22:      master_hostname << nodeobj.node.name
 23:    end
 24:  end

If I change the client back to version 12.15.19, everything works.

Please help me understand how to modify my recipe to work both in v12 and v13.

Thank you!
Gabi


#2

https://docs.chef.io/deprecations_attributes.html

The deprecation warnings at the end of the Chef run in Chef 12 should also give you pointers on how to address.


#3

thank you.


#4

Now I get

NoMethodError
-------------
undefined method `[]' for nil:NilClass

Cookbook Trace:
---------------
  /var/chef/cache/cookbooks/cookbook_new/recipes/default.rb:21:in `block in from_file'
  /var/chef/cache/cookbooks/cookbook_new/recipes/default.rb:19:in `each'
  /var/chef/cache/cookbooks/cookbook_new/recipes/default.rb:19:in `from_file'

Relevant File Content:
----------------------
/var/chef/cache/cookbook_new/recipes/default.rb:

 14:  if masters.empty? || !masters.any?
 15:    Chef::Log.warn("Cannot find any master!")
 16:    # master_ip << node['ipaddress']
 17:    # master_hostname << node['name']
 18:  else
 19:    masters.each do |nodeobj|
 20:      Chef::Log.warn("nodeobj: #{nodeobj}")
 21>>     master_ip << nodeobj['node']['ipaddress']
 22:      master_hostname << nodeobj['node']['name']
 23:    end
 24:  end
 25:  Chef::Log.warn("master ip: #{master_ip}")
 26:  Chef::Log.warn("master hostname: #{master_hostname}")

Anything else I should change?
Thank you again.
Gabi


#5

In your original code, you had this:

The call to the #node method wasn’t needed in the first place (it’s there to make attributes files accept recipe-style attribute usage).

So in your new version:

Just remove the ['node'] part.


#6

Thank you, again kallistec.

I had another problem with the 2nd line master_hostname << nodeobj['node']['name'] which i had to change it to master_hostname << nodeobj.name and in the end, it works.

Best regards,
Gabi


#7

node.name and node.chef_environment are actually not standard attributes like node['ipaddress'] and really are methods on the node object.

we should probably fix that one way or the other at some point – to make it at least appear to be consistent for users – but it hasn’t bubbled up as the most important thing to fix about node objects yet.