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.