Defining attributes for cookbook in recipe has different behavior than attributes from roles

Hello

  1. I’m using the opscode chef-client cookbook, and I am trying to define
    attributes for the cookbook from a wrapper recipe, however they don’t seem
    to be honored. When I define them in a role the node is in, it works
    however (working meaning chef_client operates on the attributes). What is
    different about the two?

Here is my attributes file:

exception_mail_template = “/opt/chef/mail_hanlder_template.erb”

default[‘chef-client’][‘config’][‘exception_handlers’] = [
{“class” => “MailHandler”, “arguments” => [{:template_path =>
"#{exception_mail_template}"}]
}]
default[‘chef-client’][‘load_gems’] = [
{“chef-handler-mail” => {“require_name” => “chef/handler/mail”}
}]

and portion of my recipe where I call chef_client

Exception handling for chef client runs

chef_gem “chef-handler-mail” do
action :install
end

Install exception handler email template

exception_mail_template = “/opt/chef/mail_hanlder_template.erb”

cookbook_file “#{exception_mail_template}” do
source "mail_handler.erb"
end

include_recipe “chef-client::config”

Thanks

On Wed, Dec 3, 2014 at 11:37 PM, William Jimenez <
william.jimenez@itsoninc.com> wrote:

Hello

  1. I'm using the opscode chef-client cookbook, and I am trying to
    define attributes for the cookbook from a wrapper recipe, however they
    don't seem to be honored. When I define them in a role the node is in, it
    works however (working meaning chef_client operates on the attributes).
    What is different about the two?

Here is my attributes file:

exception_mail_template = "/opt/chef/mail_hanlder_template.erb"

default['chef-client']['config']['exception_handlers'] = [
{"class" => "MailHandler", "arguments" => [{:template_path =>
"#{exception_mail_template}"}]
}]
default['chef-client']['load_gems'] = [
{"chef-handler-mail" => {"require_name" => "chef/handler/mail"}
}]

and portion of my recipe where I call chef_client

Exception handling for chef client runs

chef_gem "chef-handler-mail" do
action :install
end

Install exception handler email template

exception_mail_template = "/opt/chef/mail_hanlder_template.erb"

cookbook_file "#{exception_mail_template}" do
source "mail_handler.erb"
end

include_recipe "chef-client::config"

Thanks

Attribute Precedence is probably what's screwing you up:

Your default attribute in your attributes file would have the same
precedence as the cookbook. So order wins. A role will win though.

Thanks Galen, I just tried changing the attributes file to

force_override['chef-client']['config']['exception_handlers'] = [
{"class" => "MailHandler", "arguments" => [{:template_path =>
"#{exception_mail_template}"}]
}]
force_override['chef-client']['load_gems'] = [
{"chef-handler-mail" => {"require_name" => "chef/handler/mail"}
}]

No difference. What else could it be?

On Thu, Dec 4, 2014 at 11:54 AM, Galen Emery galen@getchef.com wrote:

On Wed, Dec 3, 2014 at 11:37 PM, William Jimenez <
william.jimenez@itsoninc.com> wrote:

Hello

  1. I'm using the opscode chef-client cookbook, and I am trying to
    define attributes for the cookbook from a wrapper recipe, however they
    don't seem to be honored. When I define them in a role the node is in, it
    works however (working meaning chef_client operates on the attributes).
    What is different about the two?

Here is my attributes file:

exception_mail_template = "/opt/chef/mail_hanlder_template.erb"

default['chef-client']['config']['exception_handlers'] = [
{"class" => "MailHandler", "arguments" => [{:template_path =>
"#{exception_mail_template}"}]
}]
default['chef-client']['load_gems'] = [
{"chef-handler-mail" => {"require_name" => "chef/handler/mail"}
}]

and portion of my recipe where I call chef_client

Exception handling for chef client runs

chef_gem "chef-handler-mail" do
action :install
end

Install exception handler email template

exception_mail_template = "/opt/chef/mail_hanlder_template.erb"

cookbook_file "#{exception_mail_template}" do
source "mail_handler.erb"
end

include_recipe "chef-client::config"

Thanks

Attribute Precedence is probably what's screwing you up:
About Attributes

Your default attribute in your attributes file would have the same
precedence as the cookbook. So order wins. A role will win though.

William,

You'll need to provide more detail about what's in your role, what you
expect to see happen, what actually happens. Debug output would be good too
(a Gist would be fine). Use markup in the Gist so we can see what's what
more easily in the role, etc.

Note, you misspell mail_handler as 'mail_hanlder', which may be a
confounding factor.

Avoid using attribute arrays: Arrays and Chef Attributes – Noah Kantrowitz

The force_override shouldn't be needed since the wrapper cookbook
attributes/default.rb will load after the chef-client/attributes/default.rb
file

Cheers,

Peter

On Wed, Dec 3, 2014 at 11:37 PM, William Jimenez <
william.jimenez@itsoninc.com> wrote:

Hello

  1. I'm using the opscode chef-client cookbook, and I am trying to
    define attributes for the cookbook from a wrapper recipe, however they
    don't seem to be honored. When I define them in a role the node is in, it
    works however (working meaning chef_client operates on the attributes).
    What is different about the two?

Here is my attributes file:

exception_mail_template = "/opt/chef/mail_hanlder_template.erb"

default['chef-client']['config']['exception_handlers'] = [
{"class" => "MailHandler", "arguments" => [{:template_path =>
"#{exception_mail_template}"}]
}]
default['chef-client']['load_gems'] = [
{"chef-handler-mail" => {"require_name" => "chef/handler/mail"}
}]

and portion of my recipe where I call chef_client

Exception handling for chef client runs

chef_gem "chef-handler-mail" do
action :install
end

Install exception handler email template

exception_mail_template = "/opt/chef/mail_hanlder_template.erb"

cookbook_file "#{exception_mail_template}" do
source "mail_handler.erb"
end

include_recipe "chef-client::config"

Thanks

Attribute Precedence is probably what's screwing you up:
About Attributes

Your default attribute in your attributes file would have the same
precedence as the cookbook. So order wins. A role will win though.

I'm trying to configure an exception handler to receive notification when a
chef run fails. I'm using the opscode cookbook chef-client to define this
exception handler in the client.rb file of each chef node.

I expect when I call chef-client::config it to modify the client.rb to
contain the following:

["chef/handler/mail"].each do |lib|

begin
require lib
rescue LoadError
Chef::Log.warn "Failed to load #{lib}. This should be resolved after a
chef run."
end
end

exception_handlers << MailHandler.new()

and it does this just fine when I define the attributes in the role of a
given node. But when I try to define the attributes in the recipe instead,
it doesn't add the above changes to client.rb, only builds the file with
the default settings.

The role has this defined in it (under the default attributes):

"chef_client": {
  "config": {
    "exception_handlers": [
      {
        "class": "MailHandler",
        "arguments": [
        ]
      }
    ]
  },
  "load_gems": {
    "chef-handler-mail": {
      "require_name": "chef/handler/mail"
    }
  }
}

Thanks for your help with this,

William

On Thu, Dec 4, 2014 at 12:25 PM, Peter Burkholder pburkholder@getchef.com
wrote:

William,

You'll need to provide more detail about what's in your role, what you
expect to see happen, what actually happens. Debug output would be good too
(a Gist would be fine). Use markup in the Gist so we can see what's what
more easily in the role, etc.

Note, you misspell mail_handler as 'mail_hanlder', which may be a
confounding factor.

Avoid using attribute arrays: Arrays and Chef Attributes – Noah Kantrowitz

The force_override shouldn't be needed since the wrapper cookbook
attributes/default.rb will load after the chef-client/attributes/default.rb
file

Cheers,

Peter

On Wed, Dec 3, 2014 at 11:37 PM, William Jimenez <
william.jimenez@itsoninc.com> wrote:

Hello

  1. I'm using the opscode chef-client cookbook, and I am trying to
    define attributes for the cookbook from a wrapper recipe, however they
    don't seem to be honored. When I define them in a role the node is in, it
    works however (working meaning chef_client operates on the attributes).
    What is different about the two?

Here is my attributes file:

exception_mail_template = "/opt/chef/mail_hanlder_template.erb"

default['chef-client']['config']['exception_handlers'] = [
{"class" => "MailHandler", "arguments" => [{:template_path =>
"#{exception_mail_template}"}]
}]
default['chef-client']['load_gems'] = [
{"chef-handler-mail" => {"require_name" => "chef/handler/mail"}
}]

and portion of my recipe where I call chef_client

Exception handling for chef client runs

chef_gem "chef-handler-mail" do
action :install
end

Install exception handler email template

exception_mail_template = "/opt/chef/mail_hanlder_template.erb"

cookbook_file "#{exception_mail_template}" do
source "mail_handler.erb"
end

include_recipe "chef-client::config"

Thanks

Attribute Precedence is probably what's screwing you up:
About Attributes

Your default attribute in your attributes file would have the same
precedence as the cookbook. So order wins. A role will win though.

--
William Jimenez
Systems Engineer, Operations
ItsOn, Inc.
650-241-8470 {us/pacific}

Hello all,
I may have discovered the culprit, I discovered there is something for
chef-client in the override attribute section of our roles, but it wasn't
for the chef-client recipe (which is why I didn't expect it), but for the
bootstrapper. It is probably wiping out my attempt to set the attributes in
the recipe.

Thanks,
William

On Thu, Dec 4, 2014 at 7:14 PM, William Jimenez <
william.jimenez@itsoninc.com> wrote:

I'm trying to configure an exception handler to receive notification when
a chef run fails. I'm using the opscode cookbook chef-client to define this
exception handler in the client.rb file of each chef node.

I expect when I call chef-client::config it to modify the client.rb to
contain the following:

["chef/handler/mail"].each do |lib|

begin
require lib
rescue LoadError
Chef::Log.warn "Failed to load #{lib}. This should be resolved after
a chef run."
end
end

exception_handlers << MailHandler.new()

and it does this just fine when I define the attributes in the role of a
given node. But when I try to define the attributes in the recipe instead,
it doesn't add the above changes to client.rb, only builds the file with
the default settings.

The role has this defined in it (under the default attributes):

"chef_client": {
  "config": {
    "exception_handlers": [
      {
        "class": "MailHandler",
        "arguments": [
        ]
      }
    ]
  },
  "load_gems": {
    "chef-handler-mail": {
      "require_name": "chef/handler/mail"
    }
  }
}

Thanks for your help with this,

William

On Thu, Dec 4, 2014 at 12:25 PM, Peter Burkholder <pburkholder@getchef.com

wrote:

William,

You'll need to provide more detail about what's in your role, what you
expect to see happen, what actually happens. Debug output would be good too
(a Gist would be fine). Use markup in the Gist so we can see what's what
more easily in the role, etc.

Note, you misspell mail_handler as 'mail_hanlder', which may be a
confounding factor.

Avoid using attribute arrays: Arrays and Chef Attributes – Noah Kantrowitz

The force_override shouldn't be needed since the wrapper cookbook
attributes/default.rb will load after the chef-client/attributes/default.rb
file

Cheers,

Peter

On Wed, Dec 3, 2014 at 11:37 PM, William Jimenez <
william.jimenez@itsoninc.com> wrote:

Hello

  1. I'm using the opscode chef-client cookbook, and I am trying to
    define attributes for the cookbook from a wrapper recipe, however they
    don't seem to be honored. When I define them in a role the node is in, it
    works however (working meaning chef_client operates on the attributes).
    What is different about the two?

Here is my attributes file:

exception_mail_template = "/opt/chef/mail_hanlder_template.erb"

default['chef-client']['config']['exception_handlers'] = [
{"class" => "MailHandler", "arguments" => [{:template_path =>
"#{exception_mail_template}"}]
}]
default['chef-client']['load_gems'] = [
{"chef-handler-mail" => {"require_name" => "chef/handler/mail"}
}]

and portion of my recipe where I call chef_client

Exception handling for chef client runs

chef_gem "chef-handler-mail" do
action :install
end

Install exception handler email template

exception_mail_template = "/opt/chef/mail_hanlder_template.erb"

cookbook_file "#{exception_mail_template}" do
source "mail_handler.erb"
end

include_recipe "chef-client::config"

Thanks

Attribute Precedence is probably what's screwing you up:
About Attributes

Your default attribute in your attributes file would have the same
precedence as the cookbook. So order wins. A role will win though.

--
William Jimenez
Systems Engineer, Operations
ItsOn, Inc.
650-241-8470 {us/pacific}

--
William Jimenez
Systems Engineer, Operations
ItsOn, Inc.
650-241-8470 {us/pacific}