Edit: Bug in rubygems 2.4.4. (fixed in 2.4.5)
I'm having trouble installing gems with the embedded ruby that comes with Chef Client v12.2.1, using the chef_gem resource:
Mixlib::ShellOut::ShellCommandFailed
------------------------------------
chef_gem[zabbixapi] (generic_server_win::libzabbix-deps line 6) had an error: Mixlib::ShellOut::ShellCommand Failed: Expected process to exit with [0], but received '1'
---- Begin output of C:/opscode/chef/embedded/bin/gem install c:/chef/cache/zabbixapi-2.2.2.gem -q --no-rdoc --no-ri -v "2.2.2" ----
STDOUT:
STDERR: ERROR: While executing gem ... (Errno::EADDRNOTAVAIL)
The requested address is not valid in its context. - connect(2)
---- End output of C:/opscode/chef/embedded/bin/gem install c:/chef/cache/zabbixapi-2.2.2.gem -q --no-rdoc --no-ri -v "2.2.2" ----
Ran C:/opscode/chef/embedded/bin/gem install c:/chef/cache/zabbixapi-2.2.2.gem -q --no-rdoc --no-ri -v "2.2.2" returned 1
Also:
Same result when running the command manually on the command-line as an Administrator with the --local option
Same error occurs for other gems.
The servers that I'm trying to run this on have no internet access
I'm unable to reproduce the problem on a newly installed test machine (with internet access)
The version of ruby used is 2.0.0: ruby 2.0.0p451 (2014-02-24) [i386-mingw32]
Here is my Chef recipe:
cookbook_file "#{Chef::Config[:file_cache_path]}/zabbixapi-2.2.2.gem" do
source 'zabbixapi-2.2.2.gem'
end
chef_gem "zabbixapi" do
source "#{Chef::Config[:file_cache_path]}/zabbixapi-2.2.2.gem"
end
You're problem is that the chef_gem resource is special in the way it enforce the use of the embedded ruby in chef installation and that it is run before convergence to allow the gem to be required in recipes. documentation about it here
To use a local source deployed with chef you have to ensure the file is present before, if not the gem command will try to download it (and fail with no internet access).
To ensure your local file is present before the chef_gem call you have to ensure the cookbook_file resource is called at compile time with this trick
in your specific case this should do:
cookbook_file "#{Chef::Config[:file_cache_path]}/zabbixapi-2.2.2.gem" do
action :nothing
source 'zabbixapi-2.2.2.gem'
end.run_action(:create)
chef_gem "zabbixapi" do
source "#{Chef::Config[:file_cache_path]}/zabbixapi-2.2.2.gem"
end
The action nothing in the resource is to avoid having it called twice (once in compile phase and once in converge phase, even if the later won't have any impact, it's better to save time no evaluating it twice) then calling the action :create at end of the definition will trigger the action in the compile phase and the file will be present for the chef_gem call later.
Related
I have an error sometimes when running bundle install
Bundler::GemspecError: Could not read gem at /path/to/cache/gem It may be corrupted
I have a web URL filter that seems to block the initial attempt at downloading the gem (if I delete the cache file in question and run again, it works). Furthermore, the contents of the cache file is the html from the web URL filter page.
I would like to not have to delete the cache file and re-run, I would like to have bundler automatically rerun if this scenario happens.
I have thought about running bundle from a Ruby script, but I cannot seem to capture the error.
I need to automate the build of my project in Docker.
begin
puts "Starting bundle install"
system %w[bundle install]
rescue Bundler::GemspecError => e
puts e
end
However, I cannot seem to rescue the exception; the error thrown is:
Bundler::GemspecError: Could not read gem at /Users/lewis/.rvm/gems/ruby-2.3.3#hendricks-offline/cache/rack-2.0.3.gem. It may be corrupted.
An error occurred while installing rack (2.0.3), and Bundler cannot continue.
Make sure that `gem install rack -v '2.0.3'` succeeds before bundling.
The exception is not captured, as I get no output. I have been advised that this is because i am running bundle now outside of Ruby world, so to speak.
How would I go about this?
You can't rescue from system commands as it's not something fatal for ruby should the command fail, instead you have to check if the system command succeeded or failed using an if condition.
It would be more like:
puts "Starting bundle install"
if system('bundle install')
puts 'bundle successful'
else
puts 'bundle failed, deleting cache file and retrying'
system('command to delete cache file goes here')
system('bundle install')
end
I am install vagrant-librarian-chef in window 7, but it appear this error:
Installing the 'vagrant-librarian-chef' plugin. This can take a few minutes...
Bundler, the underlying system Vagrant uses to install plugins,
reported an error. The error is shown below. These errors are usually
caused by misconfigured plugin installations or transient network
issues. The error from Bundler is:
An error occurred while installing chef (12.8.1), and Bundler cannot continue.
Make sure that gem install chef -v '12.8.1' succeeds before bundling.
Warning: this Gemfile contains multiple primary sources. Using source more than once without a block is a security risk, and may result in installing unexpected gems. To resolve this warning, use a block to indicate which gems should come from the secondary source. To upgrade this warning to an error, run bundle config disable_multisource true.Errno::ENOENT: No such file or directory # dir_s_mkdir - C:/Users/tuan/.vagrant.d/gems/gems/chef-12.8.1-universal-mingw32/acceptance/top-cookbooks/test_run/learn-the-basics-ubuntu/cookbooks/learn-the-basics-ubuntu/.kitchen/kitchen-vagrant/kitchen-learn-the-basics-ubuntu-learn-the-basics-ubuntu-default-ubuntu-1404
Pls help me fix that.
Thanks all!
I was having a similar issue when using the 'ohai' ruby gem. I tried running gem install chef -v '12.8.1' but received an error. I fixed my problem by adding
gem 'chef-config', '~>12.7.2'
to my gemfile.
I looked at my gem dependency tree (gem dependency) and noticed the 'ohai' gem was trying to use chef-config 12.8, so I pinned it to an earlier version.
Could someone please help with a question regarding use of a 3rd party gem with an omnibus installation running Chef recipes?
I would like to use a 'p4ruby' gem that has been packaged up with omnibus and should be available for use in a recipe using
require 'P4'
I get the error
cannot load such file -- P4
In the installation directory I can see
./embedded/service/gem/ruby/2.1.0/gems/p4ruby-2015.1.0/ext/P4/p4rubyconf.h
./embedded/service/gem/ruby/2.1.0/gems/p4ruby-2015.1.0/ext/P4/p4rubydebug.h
./embedded/service/gem/ruby/2.1.0/cache/p4ruby-2015.1.0.gem
./embedded/service/gem/ruby/2.1.0/specifications/p4ruby-2015.1.0.gemspec
./embedded/service/gem/ruby/2.1.0/build_info/p4ruby-2015.1.0.info
./embedded/lib/ruby/gems/2.1.0/gems/p4ruby-2015.1.0/ext/P4/p4rubyconf.h
./embedded/lib/ruby/gems/2.1.0/gems/p4ruby-2015.1.0/ext/P4/p4rubydebug.h
./embedded/lib/ruby/gems/2.1.0/cache/p4ruby-2015.1.0.gem
I have read through the Chef docs and see that I could use chef_gem or gem_package for example
gem_package 'p4ruby' do
end
However this always tries to compile the gem and this leads to errors in our target installation environment as we cannot expect dev tools such as make and g++ to be available and we do not want to force installation of them.
How can I get Chef to 'see' this gem or to specifiy a 3rd party gem without compilation running? Is this possible?
For further info if I do use gem_package on a machine that does have make and g++ I end up with the following in the install directory (which looks slightly different than before). Is this a path issue?? I've searched all over but cannot find a solution
./embedded/service/gem/ruby/2.1.0/gems/p4ruby-2015.1.0/ext/P4/p4rubyconf.h
./embedded/service/gem/ruby/2.1.0/gems/p4ruby-2015.1.0/ext/P4/p4rubydebug.h
./embedded/service/gem/ruby/2.1.0/cache/p4ruby-2015.1.0.gem
./embedded/service/gem/ruby/2.1.0/specifications/p4ruby-2015.1.0.gemspec
./embedded/service/gem/ruby/2.1.0/build_info/p4ruby-2015.1.0.info
./embedded/lib/ruby/gems/2.1.0/gems/p4ruby-2015.1.0/ext/P4/p4rubyconf.h
./embedded/lib/ruby/gems/2.1.0/gems/p4ruby-2015.1.0/ext/P4/p4rubydebug.h
./embedded/lib/ruby/gems/2.1.0/cache/p4ruby-2015.1.0.gem
./embedded/lib/ruby/gems/2.1.0/specifications/p4ruby-2015.1.0.gemspec
Many thanks for any help
How can I get Chef to 'see' this gem or to specifiy a 3rd party gem
without compilation running? Is this possible?
No, if a gem has some C extension, it must be compiled and will need build tools, that's why there's the build-essential cookbook.
The differences between chef_gem and gem_package are this:
gem_package will install to system ruby (or default to chef embedded ruby is none present) where chef_gem will always install in chef embedded ruby.
gem_package run in converge phase where chef_gem run at compile time
The main reason is that chef_gem is aimed at installing gem to be used in recipes where gem_package is aimed at managing system gems for use out of chef.
Think I found a way of doing this...
$:.unshift *Dir[File.path('<my_path_to_gems>/**/lib')]
I can then
require 'P4'
in my recipes
I'm trying to install the gems "sensu_plugin" and "mixlib-shellout", on a windows server 2008r2, from a recipe. In this last one, I have the following code :
%w{ sensu-plugin mixlib-shellout }.each do |gem_plugin|
gem_package gem_plugin do
gem_binary("C:/opt/sensu/embedded/bin/gem")
options("--no-rdoc --no-ri")
action :install
end
end
Yet, when running the recipe on my machine, I receive the error "ERROR: While executing gem ... (Errno::ENOENT) No such file or directory - U:/". What I found out is that whenever I try installing a gem package using the gem binary located in the chef-client directory (C:\opscode\chef\embedded\bin\gem), it raised this last error.
The thing is that the gem I wish to use to installed the gem packages is actually located in C:/opt/sensu/embedded/bin/gem, which I have declared in the gem_binary option.
In the end it looks like chef is ignoring the gem_binary option and trying to install it from its own gem binary.
I can't see what's wrong with this config. Is the gem_binary really indicating what binary to use?
I am trying to install a chef handler via the chef_handler lwrp. This handler (chef-handler-email) comes bundled in a gem. I am trying to install the gem then turn on the handler from within a single recipe that looks like:
chef_gem "chef-handler-mail"
chef_handler "MailHandler" do
source 'chef/handler/mail'
arguments :to_address => "root"
action :nothing
supports :exception => true, :report => false
end.run_action(:enable)
This works fine if the gem is already installed. However, if the Gem is not already installed I receive this error:
[2012-12-09T20:47:56-05:00] FATAL: LoadError: chef_handler[MailHandler] (chef_handler::email line 13) had an error: LoadError: no such file to load -- chef/handler/mail.rb
It appears as though the chef_handler resource is trying to load the handler before chef_gem has executed and installed the gem for the handler. I can obviously do this in a two step manual process where I have a separate recipe for installing the gem, then flip over to another recipe that configures the handler, but I'm hoping to avoid multi-step manual processes. Can it be done via single recipe?
I have a similar recipe for chef minitest-chef-handler:
chef_gem 'minitest'
chef_gem 'minitest-chef-handler'
require 'rubygems'
require 'minitest-chef-handler'
[... some unrelated code ...]
chef_handler "MiniTest::Chef::Handler" do
source "minitest-chef-handler"
arguments :verbose => true
action :nothing
end.run_action( :enable )
Try requiring your gem before creating chef_handler resource, or may be source should be different...
The #run_action call causes the chef_handler resource to be run immediately at "compile" phase while the chef_gem resource is run during the "execute" phase as normally.
So also the gem needs to be installed at compile phase. And it seems that a require statement is also needed (as suggested in another answer) for Chef to load the gem.
chef_gem 'chef-handler-mail' do
action :nothing
end.run_action(:install)
require 'chef/handler/mail'
chef_handler 'MailHandler' do
source 'chef/handler/mail'
# ... other attributes
action :nothing
end.run_action(:enable)