FilBot3
FilBot3

Reputation: 3718

Writing a Ruby class inside of a Chef Recipe

I am trying to "clean up" my Chef recipe to install Zabbix Agent, I know there are a million out there, but this is my test case for my understanding. I have my Chef instructions split up into a class, and separate methods for each step that would need to be completed. I put the class inside the recipe file. So, when I execute the recipe, linked here at GitHub, I receive this error:

NoMethodError
-------------
undefined method `execute' for #<Class:0x000000030e42c0>::Recipe_Zabbix_Agent_Unix

I'm by no means a Ruby guru, so I thought to myself, I bet this class is "separating" itself form the Chef inheritances, so I'll need to make the class inherit the Chef libraries by using the < thing. However, I still receive that error listed above. What am I missing, or not understanding when trying to do this? I've seen people write a library which is basically just a Ruby script, then the recipe includes the script and performs the functions in there, but I wanted to keep it contained in just the recipe for my simple understanding. Is that possible or is the only option I'm looking at doing the library route? I am running this on Chef 10.24 also.

Upvotes: 3

Views: 1891

Answers (2)

andrewdotn
andrewdotn

Reputation: 34873

You can create a class that takes the recipe as a parameter so that resource-definition methods are in scope.

In libraries/useful_thing.rb:

class UsefulThing
  def initialize(blah)
    @blah = blah
  end

  def apply(recipe)
    # Chef resources use instance_eval for blocks, which hides self
    outer_self = self
    recipe.directory "/foo/#{@blah}" do
        user ...
        group outer_self.latest_group
        ...
    end
    ...
  end

  ...
end

then in recipes/default.rb:

ut = UsefulThing.new(...)
ut.apply(self)

Upvotes: 1

coderanger
coderanger

Reputation: 54249

In general, class-based Resources go in a library file, not a recipe. See https://github.com/poise/berkshelf-api/blob/master/libraries/berkshelf_api.rb for an example of using Poise to get elements of the LWRP DSL in your class-based Resource.

Upvotes: 2

Related Questions