Search code examples
rubychef-infracookbook

Chef - access new_resource from library


Is there a way I can access new_resource attributes from inside a Chef library (in libraries/default.rb) ?

My current solution is:

In libraries/default.rb

module Libraries
    def init(resource)
       @@server_name = resource.server_name
       @@server_type = resource.server_type
       @@script      = get_script_path
       ...
    end
    def get_script_path
       if @@server_type == 'admin'
          script = 'admin_cntl.sh'
          path   = '/admin_server/bin'
       elsif @@server_type == 'managed'
          script = 'managed_cntl.sh'
          path   = '/managed_server/bin'
       end
       ::File.join(path, script)
    end
end

In providers/default.rb

include Libraries

action :start do 
   init(new_resource)
   execute 'my_script' do 
      command "./#{@@script} start"
   end
end

action :remove do 
   init(new_resource)
   execute 'my_script' do 
      command "./#{@@script} stop"
   end
end

I think this is unnecessary overhead but I couldn't come up with a better solution.

Is there a better way ?


Solution

  • Use a normal mixin:

    # libraries/default.rb
    module MyLibrary
      def script_path
        case new_resource.server_type
        when 'admin'
          '/admin_server/bin/admin_cntl.sh'
        when 'managed'
          '/managed_server/bin/managed_cntl.sh'
        end
      end
    end
    
    # providers/default.rb
    include MyLibrary
    
    action :start do 
       execute 'my_script' do 
          command "./#{script_path} start"
       end
    end
    
    action :remove do 
       execute 'my_script' do 
          command "./#{script_path} stop"
       end
    end
    

    Also remember you can define methods directly in the provider if they are only useful for that one provider.