Kartik
Kartik

Reputation: 39

How to use Library Methods from another cookbook in chef?

I have a case where I have to use a library function from another cookbook, but I am always getting had an error: NoMethodError: undefined method 'func'.

What did I try:

cookbook_1/libraries/lib1.rb:

module namespace_1
  module namespace_2
    def func(var)
       something
    end
  end
end


Chef::Recipe.include(namespace_1::namespace_2)

cookbook_2/metadata.rb:

.
.
depends 'cookbook_1'

cookbook_2/resource/some_resource.rb:

# Try 1
action :setup do
  a = func('abc')
end

#Try 2
extend namespace_1::namespace_2
action :setup do
  a = func('abc')
end


#Try 3
::Chef::Recipe.send(:include, namespace_1::namespace_2)
action :setup do
  a = func('abc')
end


#Try 4
action :setup do
  a = namespace_1::namespace_2::func('abc')
end


#Try 5
Chef::Recipe.include(namespace_1::namespace_2)
action :setup do
  a = namespace_1::namespace_2::func('abc')
end

I am getting the same error, i.e. NoMethodError: undefined method 'func' How do I solve this?

Upvotes: 1

Views: 1047

Answers (1)

seshadri_c
seshadri_c

Reputation: 7340

For Ruby methods written in libraries or custom resources to be available in custom resource actions, we should use action_class block.

Quoting from documentation:

Use the action_class block to make methods available to the actions in the custom resource.

So in your cookbook1, apart from having the library, you should have a custom resource with action_class. I am giving my own example based on yours.

cookbook1: libraries/lib1.rb:

# a custom function to just return the received argument 

module Namespace1
  module Namespace2  
    def custom_func(arg1)
      arg1
    end
  end
end

cookbook1: resources/some_resource.rb:

property :msg, String, name_property: true

# this is required to make sure functions are available to custom actions
action_class do
  include Namespace1::Namespace2
end

action :setup do
  a = custom_func(new_resource.msg)
  
  log a do
    level :info
  end
end

Note that I created the custom resource in the same cookbook as the library. Now this custom resource can be used in cookbook2:

cookbook2: metadata.rb

depends 'cookbook1'

cookbook2: recipes/default.rb:

cookbook1_some_resource 'Test custom function'

Upvotes: 1

Related Questions