The opscode chef bootstrap installs Matz Ruby on the node automatically. There are cookbooks for installing ruby enterprise edition on a node, but they create a separate Ruby “universe” on your box: You will have to be very careful how you install gems to make sure they are used by either the default Ruby or by REE. As this really bothered me, I created a little cookbook which installs Ruby Enterprise Edition as the default Ruby using Ruby Version Manager (RVM) and Chef. This gives me the best of both worlds: REEs stability and speed as well as a sane way of managing gems.
Bootstrap Your Chef Node
First, you need to bootstrap your node using
$ knife bootstrap www.example.com
This will install Ruby on your node and register the node at the chef server. Now you’re ready to run cookbooks on that node.
The rvm_ree_default cookbook
My cookbook consists of a default recipe and one file to be uploaded to your node. Here is the
# # Cookbook Name:: rvm_ree_default # Recipe:: default # # Copyright 2010, Matthias Marschall # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # see: http://li109-47.members.linode.com/blog/ package "curl" package "git-core" include_recipe "build-essential" %w(libreadline5-dev zlib1g-dev libssl-dev libxml2-dev libxslt1-dev).each do |pkg| package pkg end bash "install RVM" do user "root" code "bash < <( curl -L http://bit.ly/rvm-install-system-wide )" not_if "rvm --version" end cookbook_file "/etc/profile.d/rvm.sh" bash "install REE in RVM" do user "root" code "rvm install ree" not_if "rvm list | grep ree" end bash "make REE the default ruby" do user "root" code "rvm --default ree" end gem_package "chef" # re-install the chef gem into REE to enable subsequent chef-client runs
It installs the prerequisite packages and uses the
rvm-install-system-wide script to get RVM installed. To enable RVM in all shells, it puts the
rvm.sh into the
/etc/profile.d. Then, it uses RVM to install REE and make it the default Ruby on the box. As a last step, it installs the chef gem again as the brand new REE doesn’t yet have it. Now, REE is your default Ruby and all commands like
gem, etc. work as expected using REE.
Here is the
[[ -s "/usr/local/lib/rvm" ]] && . "/usr/local/lib/rvm" # This loads RVM into a shell session.
Don’t forget to
$ knife cookbook upload rvm_ree_default before trying to use it!
Install RVM at Bootstrap Time
The above way helps if you already have chef nodes up and running and want to switch them to REE. If you install a brand new node, you can use a bootstrap template to install REE with RVM as default. Here you go:
bash -c ' if [ ! -f /usr/local/bin/chef-client ]; then apt-get update apt-get install -y git-core curl apt-get install -y build-essential binutils-doc gcc autoconf flex bison apt-get install -y libreadline5-dev zlib1g-dev libssl-dev libxml2-dev libxslt1-dev bash < <( curl -L http://bit.ly/rvm-install-system-wide ) ( cat < /etc/profile.d/rvm.sh source /etc/profile rvm install ree rvm --default ree gem install ohai chef --no-rdoc --no-ri --verbose ln -nfs $(which chef-client) /usr/bin/chef-client fi mkdir -p /etc/chef ( cat <<'EOP' EOP ) > /tmp/validation.pem awk NF /tmp/validation.pem > /etc/chef/validation.pem rm /tmp/validation.pem ( cat <<'EOP' log_level :info log_location STDOUT chef_server_url "" validation_client_name "" # Using default node name" node_name "" EOP ) > /etc/chef/client.rb ( cat <<'EOP' @run_list }.to_json %> EOP ) > /etc/chef/first-boot.json chef-client -j /etc/chef/first-boot.json'
The upper part of the script is the interesting one here: First, it installs the required packages, then RVM and then it uses RVM to install Ruby Enterprise Edition and makes it the default ruby.
The symlink to
chef-client is only necessary if you want to use sudo (without -i option) to call
chef-client (sudo without -i won’t load the enviroment so RVM will not be available for your sudo commands).
To bootstrap your node using the above script, save it in your chef repo under
bootstrap/ubuntu10.04-rvm-ree.erb and run
$ knife bootstrap www.example.com -t bootstrap/ubuntu10.04-rvm-ree.erb
No matter whether you want to switch an existing node to Ruby Enterprise Edition or bootstrap your node using it, the Ruby Version Manager helps you keep a clean system. And, it offers you the possibility to smoothly upgrade to another ruby version later or even use separate gem sets for different applications. Does it work for you? Please leave a comment or tweet this post.
15 thoughts on “Chef: RVM + Ruby Enterprise Edition as Default Ruby”
I’m having some trouble with your test:
not_if “rvm –version”
I get error output like this:
ERROR: bash[Install RVM] (/srv/chef/cache/cookbooks/modcloth/recipes/default.rb:38:in `from_file’) had an error:
No such file or directory – rvm –version
You’re using some kind of thing that makes it annoying to copy code. This makes it really annoying to copy code.
@M yes, we’re using tynt.com to track user interaction with our blog. I’m sorry that it is annoying when copying code but there is no way to avoid that for special parts of the site. We would have to disable it completely, which is not an option right now.
Thanks! This is very good and very helpful!
You should contribute all of this back to the core Chef projects!
Yes, it’s already on my todo list. I already talked to @jtimberman about it. Great that you find it helpful.
ok, contributed the knife bootstrap scripts to install Ruby Enterprise Edition (REE) from dpkg as well as with Ruby Version Manager (RVM) and the rvm_ree_default cookbook.
I created an rvm recipe based on the scripts found here:
Cleaned up and tested on ubuntu. Individual recipes for installing rvm, installing ree and jruby via rvm, and setting the default ruby via rvm.
@Dennis Great job! The separation of the cookbooks is really nice.
git-coredependencies, it would not install on a minimal ubuntu install as it can be found on quite a few rented servers.
And for me it was necessary to install the
chefgem into the new default ruby.
When I bootstrap RVM+ree using either knife ec2 server create…, or knife bootstrap… methods, and on chef-client runs where RVM+ree are installed, the process always causes either knife or chef-client to not return:
node.amazonws.com ree-1.8.7-2010.02 – #installing
I never get past that successfully. Any hints? Can I be the only one seeing this behavior?
How long are you waiting? It may take a while for rvm to download and compile ruby.
Thank you so much!!
This is now out of date as of 3/24/2011.
The system-wide install has been removed from RVM
A similar result is supposed to be possible simply by installing as root.