Open Atalanta opened 11 years ago
Ignore above comment. That should be for issue #4
Re: LWRP: Postmodern suggests using chruby-exec.
Investigating.
I would lean towards a bundler style syntax:
chruby '1.9.3' do
gem 'foo'
end
chruby '1.9.3', 'jruby' do
gem 'foo'
end
There's some restriction around the way LWRPs work - the DSL keyword needs to be chruby_something
How about:
chruby_gem '1.9.3' do
gem 'foo'
end
chruby_gem ['1.9.3', 'ree'] do
gem 'bar'
end
Easiest to implement would be:
chruby_gem 'rspec' do
version ['1.9.3', 'jruby']
end
I think this is how the rbenv_gem
works.
What do you think?
I don't know how LWRPs work, but I would favour the least repetitious / "blocky" syntax.
chruby-exec
doesn't quite behave as I expected:
$ chruby
1.9.3-p392
* 1.9.3-p429
embedded
$ chruby-exec 392 -- gem install chess
Fetching: chess-0.0.3.gem (100%)
Building native extensions. This could take a while...
Successfully installed chess-0.0.3
1 gem installed
Installing ri documentation for chess-0.0.3...
Installing RDoc documentation for chess-0.0.3...
$ gem list
*** LOCAL GEMS ***
bigdecimal (1.1.0)
chess (0.0.3)
io-console (0.3)
json (1.5.5)
minitest (2.5.1)
rake (0.9.2.2)
rdoc (3.9.5)
ubuntu@ip-10-240-109-90:~$ ruby --versio
ruby: invalid option --versio (-h will show valid options) (RuntimeError)
ubuntu@ip-10-240-109-90:~$ ruby --version
ruby 1.9.3p429 (2013-05-15 revision 40747) [x86_64-linux]
$ chruby embedded
ubuntu@ip-10-240-109-90:~$ gem list
*** LOCAL GEMS ***
bigdecimal (1.1.0)
bundler (1.1.5)
chef (11.4.4)
chess (0.0.3)
erubis (2.7.0)
highline (1.6.18)
io-console (0.3)
ipaddress (0.8.0)
json (1.5.4)
mime-types (1.23)
minitest (2.5.1)
mixlib-authentication (1.3.0)
mixlib-cli (1.3.0)
mixlib-config (1.1.2)
mixlib-log (1.6.0)
mixlib-shellout (1.1.0)
net-ssh (2.6.7)
net-ssh-gateway (1.2.0)
net-ssh-multi (1.2.0, 1.1)
ohai (6.16.0)
rake (0.9.2.2)
rdoc (3.9.4)
rest-client (1.6.7)
ruby-shadow (2.2.0)
systemu (2.5.2)
yajl-ruby (1.1.0)
I would expect chruby-exec 392 to only install the Gem for that Ruby. But it seems that Gem is available to all Rubies? Is this what you would expect? Or have I missed something?
Actually this is an artifact of how chruby sets GEM_HOME
. chruby doesn't take into account RUBY_PATCHLEVEL
, in order to allow re-using gems between patch-level upgrades.
Aha; So embedded Ruby is also 1.9.3; so if I asked ruby_build to install something other than 1.9.3, and then ran chruby_exec somthingelse -- gem install, we'd get the behaviour I expected.
Correct. GEM_HOME
is defined as $HOME/.gem/$RUBY_ENGINE/$RUBY_VERSION
.
Tested with 2.0.0-p195 - behaves as expected.
Next question is how to call chruby-exec from Chef. Two obvious options:
chruby-exec is actually a Bash function, I guess, so I'll need to source chruby first. Something like:
bash "Install rspec" do
user "ubuntu"
code <<-EOH
source /etc/profile.d/chruby
chruby-exec 2.0 -- gem install rspec --no-ri --no-rdoc
EOH
end
$ sudo chef-apply chruby_gem.rb
Recipe: (chef-apply cookbook)::(chef-apply recipe)
* bash[Install rspec] action run
- execute "bash" "/tmp/chef-script20130602-28477-anwnhq"
ubuntu@ip-10-240-109-90:/tmp$ ruby --version
ruby 2.0.0p195 (2013-05-14 revision 40734) [x86_64-linux]
ubuntu@ip-10-240-109-90:/tmp$ gem list rspec
*** LOCAL GEMS ***
rspec (2.13.0)
rspec-core (2.13.1)
rspec-expectations (2.13.0)
rspec-mocks (2.13.1)
Wonder what the best way to guarantee idempotence is. Best would be to look at the file or directory it creates, which could be calculated.
Alternative would be to run gem list and look for the thing we're trying to install.
Thoughts?
Current chruby-exec
is a shell script that invokes $SHELL -l -i -c
. I have plans to rewrite it as a shell function, that way someone doesn't try to run chruby-exec
from dash.
Aha okay, so I guess I don't need to source chruby in that case. Any thoughts on idempotence?
Just installing the gems should be idempotent?
Do you mean that Rubygems itself is idempotent? is if bundler is installed, when I try to install bundler, no action will be taken?
I guess I should just look at the core Chef provider and see what that does.
It will just install the latest version, even if that version is already installed.
Right - that's what I thought. Ideally a provider knows if action is needed, to save node convergence time.
Bump! I'm also looking for a reliable way to install gems (like bundler) - ideally at the system level - using the chruby cookbook.
FWIW, my "gem_require" gem (https://github.com/mdub/gem_require) provides an idempotent version of "gem install".
A simple solution that works for me is the following definition
define :chruby_gem, :action => :install do
gem_package "chruby #{params[:ruby]}: #{params[:name]}" do
package_name params[:name]
gem_binary "/opt/rubies/#{params[:ruby]}/bin/gem"
version params[:version] if params[:version]
action params[:action]
end
end
The gem_packe resource also handles the idempotency for us:
chruby_gem 'bundler' do
ruby '1.9.3-p448'
end
Gives me on a second run:
INFO: Processing gem_package[chruby 1.9.3-p448: passenger] action install (vhost::passenger line 2)
DEBUG: gem_package[chruby 1.9.3-p448: passenger] using gem '/opt/rubies/1.9.3-p448/bin/gem'
DEBUG: gem_package[chruby 1.9.3-p448: passenger] found installed gem passenger version 4.0.5 matching passenger (= 4.0.5)
DEBUG: gem_package[chruby 1.9.3-p448: passenger] is already installed - nothing to do
DEBUG: gem_package[chruby 1.9.3-p448: passenger] resetting gem environment to default
@databus23's solution works great. But i think we can use it without proxy-definition
gem_package 'bundler' do
gem_binary "/opt/rubies/#{node[:chruby][:default]}/bin/gem"
end
This indeed works great, but if you're running chef-client withing a chruby ruby then it is using the correct gem command, but it's used withing the ruby environment you're running.
For now the only workaround is to run chef in a ruby not managed by chruby. In my case on OSX I would need to use the system ruby.
It would be great to be able to specify gems to install per Ruby:
For example:
chruby_gem "bundler" do ruby "1.9.3-p429" end