How to Access the Current Node from a Library in a Chef Cookbook

How can I access the current node from a library in a Chef cookbook?

What you can do is to include the module in your recipe. That way, your module functions get access to the methods of the recipe, including node.

I normally do this for my library modules:

# my_cookbook/libraries/helpers.rb
module MyCookbook
module Helpers
def foo
node["foo"]
end
end
end

Then, in the recipe, I include the module into the current instance of a recipe:

# my_cookbook/recipes/default.rb
extend MyCookbook::Helpers

That way, only the current recipe gets the module included, not all of them in the whole chef run (you thus avoid name clashes).

Alternatively, you could pass the current node as a parameter to the function. That way, you don't need to include the module (which has the upside of keeping the module namespaces) but has the downside of a more convoluted method call.

Access Node attributes in Chef Library

You don't have access to the node object in a library unless you pass it into the initializer:

class MyHelper
def self.get_inputs_for(node)
# Your code will work fine
end
end

Then you call it with:

inputs = MyHelper.get_inputs_for(node)

Alternative, you can to create a module and mix it into the Chef Recipe DSL:

module MyHelper
def get_inputs
# Same code, but you'll get "node" since this is a mixin
end
end

Chef::Recipe.send(:include, MyHelper)

Then you have access to the get_inputs method right in a recipe:

inputs = get_inputs

Notice this is an instance method versus a class method.

In short, libraries don't have access to the node object unless given as a parameter. Modules will, if they are mixed into the Recipe DSL. Additionally, the node object is actually an instance variable, so it's not available at the class level (i.e. self.).

Chef - access new_resource from library

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.

cookbook_version root_dir in library

Copying down from the comment:

That is not supported and will break in some releases. Use a cookbook_file resource first to copy it out to known location. This might mean your library helper code needs to be become a DSL extension or custom resource instead.

How to use Chef search method in library code (in module method)?

You want something like this.

Chef::Search::Query.new.search(:node, 'foo:bar') do |n|
# something with n
end

Determining the Operating System in a Chef Library

I changed approach slightly instead of trying to access the os object directly, I instead used the node object via a 'mixin'.

require 'win32/service'

module Project
module Helper
def serviceExists?(service_name)
if node['os'].include?('windows')
Win32::Service.exists?(service_name)
else
raise 'Checking for services under this platform is not implemented yet.'
end
end
end
end

Chef::Recipe.send(:include, Project::Helper)
Chef::Resource.send(:include, Project::Helper)

Chef, related path from cookbook to file storage

The structure you describe is not inside a cookbook so those files do not exist as far as Chef is concerned. Even inside a cookbook, you need to use a cookbook_file or remote_directory resource to write to a known place first.



Related Topics



Leave a reply



Submit