Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I set up a dependency to a Ruby library which doesn't exist at the time Chef loads recipes?

Scenario:

  • Recipe1: downloads archives, extracts them. Makes available a CLI which also defines a Ruby library.
  • Recipe2: leverages Ruby API from the aforementioned library.

In recipe1/recipes/default.rb:

.. do work
node[:recipe1][:filePath] = ".." #path to file

In recipe2/recipes/default.rb:

require node[:recipe1][:filePath]/lib/Library
.. do work

However, when loading the recipes, Chef announces:

[Wed, 17 Aug 2011 19:32:23 +0800] DEBUG: Loading cookbook apache2's definitions from /var/chef/cookbooks/apache2/definitions/web_app.rb
[Wed, 17 Aug 2011 19:32:23 +0800] DEBUG: Loading cookbook apache2's definitions from /var/chef/cookbooks/apache2/definitions/apache_module.rb
[Wed, 17 Aug 2011 19:32:23 +0800] DEBUG: Loading Recipe Recipe1 via include_recipe
[Wed, 17 Aug 2011 19:32:23 +0800] DEBUG: Found recipe default in cookbook Recipe1
[Wed, 17 Aug 2011 19:32:23 +0800] ERROR: Running exception handlers
[Wed, 17 Aug 2011 19:32:23 +0800] ERROR: Exception handlers complete
[Wed, 17 Aug 2011 19:32:23 +0800] DEBUG: Re-raising exception: LoadError - no such file to load -- /path/to/library/Library
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in `gem_original_require'
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in `require'
/var/chef/cookbooks/hsltcli/recipes/default.rb:63:in `from_file'
/usr/lib64/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/cookbook_version.rb:578:in `load_recipe'
/usr/lib64/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/mixin/language_include_recipe.rb:40:in `include_recipe'
/usr/lib64/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/mixin/language_include_recipe.rb:27:in `each'
/usr/lib64/ruby/gems/1.8/gems/chef-0.10.4/bin/../lib/chef/mixin/language_include_recipe.rb:27:in `include_recipe'

How can I declare/enable a Ruby library after all recipes are in the process of running?

like image 502
elred Avatar asked Oct 10 '22 05:10

elred


1 Answers

Using a Gem package, you call the run_action() method on the resource so it happens during compile time, and make sure that the Gem paths are cleared. For example:

r = gem_package "dynect_rest" do
  action :nothing
end
r.run_action(:install)
require 'rubygems'
Gem.clear_paths

Or, slightly more compact:

gem_package "dynect_rest" do
  action :nothing
end.run_action(:install)
require 'rubygems'
Gem.clear_paths

(the require 'rubygems' is probably not strictly necessary, as it should already be loaded by Chef, but we want to be sure)

like image 160
jtimberman Avatar answered Oct 14 '22 05:10

jtimberman