4

I am just trying to create a simple cookbook in chef. I am using libraries as a learning process.

module ABC
  class YumD
    def self.pack (*count)
      for i in 0...count.length
        yum_packag "#{count[i]}" do
          action :nothing
        end.run_action :install
      end
    end
  end
end

When I call this in the recipe I get a compile error which says

undefined method `yum_package' for ABC::YumD:Class
sethvargo
  • 26,739
  • 10
  • 86
  • 156
Sbal
  • 343
  • 7
  • 20

2 Answers2

5

You do not have access to the Chef Recipe DSL inside libraries. The DSL methods are actually just shortcuts to full-blown Ruby classes. For example:

template '/etc/foo.txt' do
  source 'foo.erb'
end

Actually "compiles" (read: "is interpreted") to:

template = Chef::Resource::Template.new('/etc/foo.txt')
template.source('foo.erb')
template.run_action(:create)

So, in your case, you want to use YumPackage:

module ABC
  class YumD
    def self.pack(*count)
      for i in 0...count.length
        package = Chef::Resource::YumPackage.new("#{count[i]}")
        package.run_action(:install)
      end
    end
  end
 end
sethvargo
  • 26,739
  • 10
  • 86
  • 156
  • Thanks got it. However I get error for `package.run_action(:install). The error that I get is 'undefined method `events' for nil:NilClass' .. package.action just works fine. But I need to install the packages at compile time cos I download a gem using chef_gem which depends on the package. – Sbal Feb 21 '14 at 07:37
  • Way late to the party, but I think the reason this doesn't work is that the constructor is missing `run_context`. But that doesn't seem to be available from the library. – Nathan Meyer Oct 06 '15 at 22:02
  • The answer I was looking for was how to use a class method in my recipe and the answer at http://stackoverflow.com/questions/20835697/how-to-require-my-library-in-chef-ruby-block helped me. You have to define the method with `def self.<>` and then you can reference it in your recipe with `AppHelper.<> – saranicole Jan 25 '16 at 16:25
2

To improve on sethvargo's answer, which should avoid the undefined method events for nil:NilClass error: try adding run_context to the constructor call:

module ABC
  class YumD
    def self.pack(*count)
      for i in 0...count.length
        package = Chef::Resource::YumPackage.new("#{count[i]}", run_context)
        package.run_action(:install)
      end
    end
  end
 end
Jos Backus
  • 21
  • 2
  • This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post - you can always comment on your own posts, and once you have sufficient [reputation](http://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](http://stackoverflow.com/help/privileges/comment). – jruizaranguren Sep 09 '15 at 06:03
  • SO would not let me comment on the original post by Sbal. Blame them, not me. And if I'm not answering the question, neither is sethvargo, yet I don't see you complain about his post. – Jos Backus Sep 11 '15 at 17:45
  • I think you're on to something but when I try it, `run_context` is undefined. – Nathan Meyer Oct 06 '15 at 22:03
  • Easy fix: create a new run_context, like this: `run_context = Chef::RunContext.new(Chef::Node.new, {}, Chef::EventDispatch::Dispatcher.new)` – Jos Backus Oct 19 '15 at 23:14
  • @JosBackus tried that. Fails with `ArgumentError: Cannot find a platform for node[]`. Any idea about how to pass the platform information to the Chef::Node object? – SaltwaterC Oct 20 '15 at 13:43
  • @JosBackus to answer my own question: `#!/opt/chef/embedded/bin/ruby require 'chef' require 'ohai' node = Chef::Node.new node.automatic = Ohai::System.new.all_plugins[0].data run_context = Chef::RunContext.new(node, {}, Chef::EventDispatch::Dispatcher.new) package = Chef::Resource::Package.new 'git', run_context package.run_action :install` LE: Please ignore the useless formatting for code in comments. – SaltwaterC Oct 20 '15 at 16:07
  • @SaltwaterC the Ohai call sets up the platform, which is why it now works and not before. Glad you got it to work. – Jos Backus Oct 22 '15 at 19:34