georgthebub
georgthebub

Reputation: 407

Chef pass LWRP resource attribute to helper library

I'm writing a library cookbook that contains an LWRP which is supposed to install a tarball and run it as a daemon (the teamcity agent software). As part of this cookbook I want to write a helper method that checks if the software is installed. So I have a helper library with this structure:

    module TeamCity
     module Agent_helper
       def tc_agent_installed?(install_path, archive, version)
         return false unless File.symlink?(install_path)
         return false unless File.basename(File.readlink(install_path)) == "#{archive.match(/^[^\.]*/).to_s}-#{version}"
         return false unless ::File.exist?(::File.join(install_path,'lib','agent.jar'))
         true
       end
     end
    end

My resource looks like this:

    actions :install, :configure
    default_action :install

    attribute :install_path, :kind_of => String, default: '/opt/tcbuild'
...
...
    attribute :version, :kind_of => String, default: '8.1.4'

Here's an example on how my helper method is being called from within the provider

    link target do
      to source
      owner new_resource.user
      group new_resource.group
      not_if { tc_agent_installed?(new_resource.install_path, new_resource.install_archive, new_resource.version) }
    end

Ideally that method should not be getting input parameters but instead be able to pull the attributes from the resource, since the method only serves one purpose. On the above link resource, I want to be able to write a library that can load the current resource's attributes (e.g new_resource.version in the above example). That way I can simply write the guard like this:

not_if { tc_agent_installed? }

I've tried multiple ways of passing the 'version' attribute to that module but haven't gotten it to work.

Passing a node attribute to a helper library is easily achieved, but it's not something that I want to do, since some resource attributes are using default values and aren't getting overriden by a node attribute.

Any ideas? What's the optimal way of passing resource attributes (not node attributes) to a library?

Upvotes: 0

Views: 579

Answers (2)

Tejay Cardon
Tejay Cardon

Reputation: 4223

Just pass the resource object

module TeamCity
  module Agent_helper
    def tc_agent_installed?(resource)
      return false unless File.symlink?(resource.install_path)
      return false unless File.basename(File.readlink(resource.install_path)) == "#{resource.archive.match(/^[^\.]*/).to_s}-#{resource.version}"
      return false unless ::File.exist?(::File.join(resource.install_path,'lib','agent.jar'))
      true
    end
  end
end

link target do
  to source
  owner new_resource.user
  group new_resource.group
  not_if { tc_agent_installed?(new_resource) }
end

Upvotes: 0

Oleksandr Slynko
Oleksandr Slynko

Reputation: 787

I would put this method in resource itself as a private method. If you don't want to pass attributes inside that method, then it has to know private variables inside resource, so it has to be inside that resource.

Upvotes: 1

Related Questions