chef gem_package not using the right binary - ruby

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?

Related

Ruby Gem conflicts between local gem and system installed gem

I have a Gemfile that looks something like this:
source 'http://rubygems.org'
gemspec
gem "parent_gem", "0.1.3", :path => "#{File.expand_path(__FILE__)}/../vendor/gems/parent_gem-0.1.3"
parent_gem depends on child_gem-1.4.1, which we have packaged in the /vender/gems folder in the package. If a user installs child_gem-1.6.0 on their host on Ubuntu, they will get a Gem::ConflictError because it will try to use 1.6 and log child_gem-1.6.0 conflicts with child_gem (~> 1.4.1). However, if a user runs it on Amazon Linux, it works fine and uses the packaged child gem.
If I run gem list child_gem, I get the following output on both systems:
*** LOCAL GEMS ***
child_gem (1.6.1)
gem list parent_gem returns nothing because it's not installed separated and only exists in the package's vendor directory.
In the files that initiates the script, there is this line:
Gem.use_paths(nil, Gem.path << "/opt/my-app/vendor")
And the /opt/my-app/vendor directory includes child_gem-1.4.1.
Ultimately, I know that setting up the package properly with Bundler should resolve the issue, but I'm trying to understand why this is an issue.
How does Ruby decide where to look for a gem on a system? And where do I look to understand why it works on Amazon Linux but not Ubuntu?

Chef with omnibus using 3rd party gems

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

Local ruby gems fail to install on Windows 2008R2: Errno::EADDRNOTAVAIL

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.

How to install gems with system wide rbenv by using chef

I installed rbenv system wide (in /usr/local/rbenv) in my VPS.
And I want to install gems by using chef.
I tried like this, but the gem is installed in system default ruby.
gem_package "daemons" do
action :install
end
How can I install gems in system wide rbenv?
By following coderanger's advice, I installed rbenv cookbook by Berkshelf.
After that I edited recipe file like this:
include_recipe "rbenv::default"
include_recipe "rbenv::ruby_build"
rbenv_ruby "2.0.0-p451"
rbenv_gem "daemons" do
ruby_version "2.0.0-p451"
end
Then I got a error ERROR: No resource, method, or local variable named `rbenv_root_path' for `Chef::Recipe "default"'. How can I solve this problem?
You need to use the rbenv_gem resource.

Error installing gems that use native extensions on Ubuntu, Ruby 1.9.2 via RVM

I get an error while trying to install the ffi gem:
~ - 16:54>gem i ffi
Building native extensions. This could take a while...
ERROR: Error installing ffi:
ERROR: Failed to build gem native extension.
rake RUBYARCHDIR=/home/mdemare/.rvm/gems/ruby-1.9.2-p136/gems/ffi-1.0.6/lib RUBYLIBDIR=/home/mdemare/.rvm/gems/ruby-1.9.2-p136/gems/ffi-1.0.6/lib
/home/mdemare/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/site_ruby/1.9.1/rubygems.rb:370:in `bin_path': can't find gem rake ([">= 0"]) with executable rake (Gem::GemNotFoundException)
from /home/mdemare/.rvm/gems/ruby-1.9.2-p136/bin/rake:19:in `<main>'
Gem files will remain installed in /home/mdemare/.rvm/gems/ruby-1.9.2-p136/gems/ffi-1.0.6 for inspection.
Results logged to /home/mdemare/.rvm/gems/ruby-1.9.2-p136/gems/ffi-1.0.6/gen/gem_make.out
I'm getting frequent errors of all kinds while installing gems with native extensions, so I assume that there's something broken with my Ubuntu installation, but I've no idea what. I'll post any information you need to diagnose the problem.
EDIT: When I cd to the ffi gem (mentioned in the second but last line), and run the rake line in line 6, I get "Could not find RubyGem rake-compiler".
After gem i rake-compiler, and run rake again, I get this:
configure: error: source directory already configured; run "make distclean" there first
make: *** [/home/mdemare/.rvm/gems/ruby-1.9.2-p136/gems/ffi-1.0.6/build/x86_64-linux/ffi_c/1.9.2/libffi/.libs/libffi_convenience.a] Error 1
rake aborted!
Command failed with status (2): [make...]
Update:
These are my rake gemspecs:
~ - 10:59>find ~/.rvm/ -name 'rake-0.8.7.gemspec'
~/.rvm/gems/ruby-1.9.2-p136/specifications/rake-0.8.7.gemspec
~/.rvm/gems/ruby-1.9.2-p136#global/specifications/rake-0.8.7.gemspec
~/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/gems/1.9.1/specifications/rake-0.8.7.gemspec
The last one is where gem looks, but that gemspec is different from the first one, and doesn't include the executable. Copying the long one doesn't quite solve the problem though - I get a file not found for the rake executable.
This caused me a ton of aggravation at the Boston Hack Day when trying to install Vagrant (for which FFI is a dependency). I ended up wasting so much time that I switched machines to work around the problem.
After the fact, I found a hack that works (although I'm sure there's a better solution). The file that the error message is complaining about
~/.rvm/gems/ruby-1.9.2-p180/bin/rake
differs from other similar copies in that it's missing path setup stuff at the head, so I copied these lines from one of the files that had them:
[genericized per #danv's answer below. Thanks for the improvement!]
ENV['GEM_HOME']=ENV['GEM_HOME'] || '~/.rvm/gems/ruby-1.9.2-p180'
ENV['GEM_PATH']=ENV['GEM_PATH'] || '~/.rvm/gems/ruby-1.9.2-p180:~/.rvm/gems/ruby-1.9.2-p180#global'
ENV['PATH']='~/.rvm/gems/ruby-1.9.2-p180/bin:~/.rvm/gems/ruby-1.9.2-p180#global/bin:~/.rvm/rubies/ruby-1.9.2-p180/bin:' + ENV['PATH']
That fixed it for me. This was a new Ubuntu 10.10 install with no default Ruby installation (which could be part of the problem) and Ruby 1.9.2 installed using RVM. Lots of other gems installed fine, including those requiring native compilation, so the problem is something specific to FFI.
I had a similar problem, and a workaround at http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=529663 helped me.
In short, try to install the gem with:
$ rake=/usr/bin/rake gem install ffi
#Tom Morris - Tried your method and it worked fine.
I inserted your path specs (modified - see below) into ~/.rvm/gems/ruby-1.9.2-p180/bin/rake after line 12.
I modified the path specs so they are generic using ~ for the user home:
ENV['GEM_HOME']=ENV['GEM_HOME'] || "~/.rvm/gems/ruby-1.9.2-p180"
ENV['GEM_PATH']=ENV['GEM_PATH'] || "~/.rvm/gems/ruby-1.9.2-p180:~/.rvm/gems/ruby-1.9.2-p180#global"
ENV['PATH']="~/.rvm/gems/ruby-1.9.2-p180/bin:~/.rvm/gems/ruby-1.9.2-p180#global/bin:~/.rvm/rubies/ruby-1.9.2-p180/bin:"+ ENV['PATH']
Thanks for finding this fix!
Thanks #Tim Morris and #danv, your answers / comments helped. I adjusted for my setup, which is based more towards a superuser environment. Now this is what /usr/local/rvm/gems/ruby-1.9.2-p180/bin/rake looks like on my server:
require 'rubygems'
version = ">= 0"
ENV['GEM_HOME']=ENV['GEM_HOME'] || "/usr/local/rvm/gems/ruby-1.9.2-p180"
ENV['GEM_PATH']=ENV['GEM_PATH'] || "/usr/local/rvm/gems/ruby-1.9.2-p180:/usr/local/rvm/gems/ruby-1.9.2-p180#global"
if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
version = $1
ARGV.shift
end
gem 'rake', version
load Gem.bin_path('rake', 'rake', version)
The installer attempts to run rake but fails when it isn't found:
can't find gem rake ([">= 0"]) with executable rake (Gem::GemNotFoundException)
You need to install the rake gem: gem install rake.

Resources