Calling Notify from Within a Provider

Hi Chef Experts,

I’m working on a lightweight provider that should restart an external
service. However for some reason I’m finding it impossible to notify the
service from within the provider. One of the community modules -
supervisord - displays the issue but I’ve boiled it down to a simple
example for discussion here.

Let’s say we have a cookbook called provider_resource_test.

We have a default recipe:

Cookbook Name:: provider_resource_test

Recipe:: default

Copyright 2014, Picsolve Ltd.

All rights reserved - Do Not Redistribute

service "my-service-name”

…and a resource

actions :create, :delete

attribute :name, :kind_of => String, :name_attribute => true

def initialize(*args)
super
@action = :create
end

…and a lightweight provider:

use_inline_resources

action :create do
directory “/tmp/dir_#{new_resource.name}” do
notifies :reload, "service[my-service-name]"
end
end

action :delete do

nothing required

end

Finally I define a simple recipe that will use the resource:

Cookbook Name:: provider_resource_test

Recipe:: use_it

Copyright 2014, Picsolve Ltd.

All rights reserved - Do Not Redistribute

provider_resource_test_thing “an_instance_of_thing"

I try to instantiate this on a node by setting the following json
attributes:

root@resourcetest:~# cat /etc/chef/attribs.json
{
“run_list”: [“recipe[provider_resource_test]”,
“recipe[provider_resource_test::use_it]”]
}

I do a chef-client run and it invariably bails out with the following error:

[2014-03-19T16:41:28+00:00] ERROR:
provider_resource_test_thing[an_instance_of_thing]
(provider_resource_test::use_it line 11) had an error:
Chef::Exceptions::ResourceNotFound: resource
directory[/tmp/dir_an_instance_of_thing] is configured to notify
resource service[my-service-name] with action reload, but
service[my-service-name] cannot be found in the resource collection.
directory[/tmp/dir_an_instance_of_thing] is defined in
/var/chef/cache/cookbooks/provider_resource_test/providers/thing.rb:4:in
`block in class_from_file’

I have tried specifying the service directly with:

notifies :reload, “service[my-service-name]”

…and also by trying to resolve it with a resource() call.

Needless to say use_inline_resources is present at the top of the
provider file though I’ve tried without it as well.

I’m running chef-client 11.10.4 and a similarly recent Chef server. I
can post debug output from the chef-client run if it’s wanted, just
don’t want to spam the list on my first post.

I’ve been stumped with this for days so I’d very much appreciate some
advice: why can’t I notify a service from within a provider?


Alex Hewson

There is a technical reason that I'm sure others could probably explain
more clearly than I could, but the "simple" answer is that when you use
use_inline_resources you create a separate run_context containing only the
resources from within the provider. The resources within the provider are
not aware of the existence of the service resource. The solution is to have
your custom resource notify the service to restart in your recipe:

provider_resource_test_thing “an_instance_of_thing" do
notifies :restart, "service[your_service]"
end

Tom Duffield — Automation Consulting Engineer

651.769.7497 – tom@getchef.com – *my:
*Linkedinhttp://www.linkedin.com/in/thomasduffield
Twitter http://www.twitter.com/tomduffield
CHEF

GETCHEF.COM http://www.getchef.com/

TM

getchef.com http://www.getchef.com/ Bloghttp://www.opscode.com/blog/
Facebook https://www.facebook.com/getchefdotcom
Twitterhttps://twitter.com/chef
Youtube https://www.youtube.com/getchef

Meet me at #ChefConf 2014 http://chefconf.com/

On Thu, Mar 20, 2014 at 6:12 AM, Alex Hewson mock@mock.so wrote:

Hi Chef Experts,

I'm working on a lightweight provider that should restart an external
service. However for some reason I’m finding it impossible to notify the
service from within the provider. One of the community modules -
supervisord - displays the issue but I’ve boiled it down to a simple
example for discussion here.

Let’s say we have a cookbook called provider_resource_test.

We have a default recipe:

Cookbook Name:: provider_resource_test

Recipe:: default

Copyright 2014, Picsolve Ltd.

All rights reserved - Do Not Redistribute

service "my-service-name”

…and a resource

actions :create, :delete

attribute :name, :kind_of => String, :name_attribute => true

def initialize(*args)
super
@action = :create
end

…and a lightweight provider:

use_inline_resources

action :create do
directory "/tmp/dir_#{new_resource.name}" do
notifies :reload, "service[my-service-name]"
end
end

action :delete do

nothing required

end

Finally I define a simple recipe that will use the resource:

Cookbook Name:: provider_resource_test

Recipe:: use_it

Copyright 2014, Picsolve Ltd.

All rights reserved - Do Not Redistribute

provider_resource_test_thing “an_instance_of_thing"

I try to instantiate this on a node by setting the following json
attributes:

root@resourcetest:~# cat /etc/chef/attribs.json
{
"run_list": ["recipe[provider_resource_test]",
"recipe[provider_resource_test::use_it]"]
}

I do a chef-client run and it invariably bails out with the following
error:

[2014-03-19T16:41:28+00:00] ERROR:
provider_resource_test_thing[an_instance_of_thing]
(provider_resource_test::use_it line 11) had an error:
Chef::Exceptions::ResourceNotFound: resource
directory[/tmp/dir_an_instance_of_thing] is configured to notify
resource service[my-service-name] with action reload, but
service[my-service-name] cannot be found in the resource collection.
directory[/tmp/dir_an_instance_of_thing] is defined in
/var/chef/cache/cookbooks/provider_resource_test/providers/thing.rb:4:in
`block in class_from_file'

I have tried specifying the service directly with:

notifies :reload, "service[my-service-name]"

...and also by trying to resolve it with a resource() call.

Needless to say use_inline_resources is present at the top of the
provider file though I've tried without it as well.

I'm running chef-client 11.10.4 and a similarly recent Chef server. I
can post debug output from the chef-client run if it's wanted, just
don't want to spam the list on my first post.

I've been stumped with this for days so I'd very much appreciate some
advice: why can’t I notify a service from within a provider?

--
Alex Hewson

Hi Tom,

Many thanks for this - it cleared up the problem immediately.

Cheers,
Alex.

On 20/03/2014 11:54, Tom Duffield wrote:

There is a technical reason that I'm sure others could probably
explain more clearly than I could, but the "simple" answer is that
when you use use_inline_resources you create a separate run_context
containing only the resources from within the provider. The resources
within the provider are not aware of the existence of the service
resource. The solution is to have your custom resource notify the
service to restart in your recipe:

provider_resource_test_thing “an_instance_of_thing" do
notifies :restart, "service[your_service]"
end

Tom Duffield — Automation Consulting Engineer

651.769.7497 – tom@getchef.com
mailto:tom@getchef.com – *my: *Linkedin
http://www.linkedin.com/in/thomasduffield Twitter
http://www.twitter.com/tomduffield

CHEF

GETCHEF.COM http://www.getchef.com/

TM

getchef.com http://www.getchef.com/ Blog
http://www.opscode.com/blog/ Facebook
https://www.facebook.com/getchefdotcom Twitter
https://twitter.com/chef Youtube https://www.youtube.com/getchef

Meet me at #ChefConf 2014 http://chefconf.com/

On Thu, Mar 20, 2014 at 6:12 AM, Alex Hewson <mock@mock.so
mailto:mock@mock.so> wrote:

Hi Chef Experts,

I'm working on a lightweight provider that should restart an external
service. However for some reason I’m finding it impossible to
notify the
service from within the provider. One of the community modules -
supervisord - displays the issue but I’ve boiled it down to a simple
example for discussion here.

Let’s say we have a cookbook called provider_resource_test.

We have a default recipe:

#
# Cookbook Name:: provider_resource_test
# Recipe:: default
#
# Copyright 2014, Picsolve Ltd.
#
# All rights reserved - Do Not Redistribute
#

service "my-service-name”


…and a resource

actions :create, :delete

attribute :name, :kind_of => String, :name_attribute => true

def initialize(*args)
super
@action = :create
end


…and a lightweight provider:

use_inline_resources

action :create do
directory "/tmp/dir_#{new_resource.name
<http://new_resource.name>}" do
notifies :reload, "service[my-service-name]"
end
end

action :delete do
# nothing required
end



Finally I define a simple recipe that will use the resource:

#
# Cookbook Name:: provider_resource_test
# Recipe:: use_it
#
# Copyright 2014, Picsolve Ltd.
#
# All rights reserved - Do Not Redistribute
#


provider_resource_test_thing “an_instance_of_thing"



I try to instantiate this on a node by setting the following json
attributes:


root@resourcetest:~# cat /etc/chef/attribs.json
{
"run_list": ["recipe[provider_resource_test]",
"recipe[provider_resource_test::use_it]"]
}


I do a chef-client run and it invariably bails out with the
following error:

[2014-03-19T16:41:28+00:00] ERROR:
provider_resource_test_thing[an_instance_of_thing]
(provider_resource_test::use_it line 11) had an error:
Chef::Exceptions::ResourceNotFound: resource
directory[/tmp/dir_an_instance_of_thing] is configured to notify
resource service[my-service-name] with action reload, but
service[my-service-name] cannot be found in the resource collection.
directory[/tmp/dir_an_instance_of_thing] is defined in
/var/chef/cache/cookbooks/provider_resource_test/providers/thing.rb:4:in
`block in class_from_file'

I have tried specifying the service directly with:

notifies :reload, "service[my-service-name]"

...and also by trying to resolve it with a resource() call.

Needless to say use_inline_resources is present at the top of the
provider file though I've tried without it as well.

I'm running chef-client 11.10.4 and a similarly recent Chef server. I
can post debug output from the chef-client run if it's wanted, just
don't want to spam the list on my first post.

I've been stumped with this for days so I'd very much appreciate some
advice: why can’t I notify a service from within a provider?


--
Alex Hewson

--
Alex Hewson
phone: +44 7895 265219 email: mock@mock.so skype: alex.hewson