Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a chruby_gem LWRP #5

Open
Atalanta opened this issue Jun 1, 2013 · 21 comments
Open

Add a chruby_gem LWRP #5

Atalanta opened this issue Jun 1, 2013 · 21 comments
Assignees

Comments

@Atalanta
Copy link
Owner

Atalanta commented Jun 1, 2013

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

@Atalanta
Copy link
Owner Author

Atalanta commented Jun 2, 2013

Ignore above comment. That should be for issue #4

Re: LWRP: Postmodern suggests using chruby-exec.

Investigating.

@postmodern
Copy link

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

@atalanta-cookbooks
Copy link

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?

@postmodern
Copy link

I don't know how LWRPs work, but I would favour the least repetitious / "blocky" syntax.

@atalanta-cookbooks
Copy link

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?

@postmodern
Copy link

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.

@atalanta-cookbooks
Copy link

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.

@postmodern
Copy link

Correct. GEM_HOME is defined as $HOME/.gem/$RUBY_ENGINE/$RUBY_VERSION.

@Atalanta
Copy link
Owner Author

Atalanta commented Jun 2, 2013

Tested with 2.0.0-p195 - behaves as expected.

Next question is how to call chruby-exec from Chef. Two obvious options:

  • bash resource
  • execute resource

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

@Atalanta
Copy link
Owner Author

Atalanta commented Jun 2, 2013

$ 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)

@Atalanta
Copy link
Owner Author

Atalanta commented Jun 2, 2013

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?

@ghost ghost assigned Atalanta Jun 2, 2013
@postmodern
Copy link

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.

@Atalanta
Copy link
Owner Author

Atalanta commented Jun 2, 2013

Aha okay, so I guess I don't need to source chruby in that case. Any thoughts on idempotence?

@postmodern
Copy link

Just installing the gems should be idempotent?

@Atalanta
Copy link
Owner Author

Atalanta commented Jun 3, 2013

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.

@postmodern
Copy link

It will just install the latest version, even if that version is already installed.

@Atalanta
Copy link
Owner Author

Atalanta commented Jun 3, 2013

Right - that's what I thought. Ideally a provider knows if action is needed, to save node convergence time.

@mdub
Copy link

mdub commented Jun 20, 2013

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".

@databus23
Copy link

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

@timfjord
Copy link

timfjord commented Jul 6, 2013

@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

@jeroenj
Copy link

jeroenj commented Aug 23, 2013

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants