Installing RVM and multiple ruby versions with Puppet

rvm_logoWith the latest version of the Puppet RVM module it is even easier to install multiple versions of Ruby


# install rubies from binaries
Rvm_system_ruby {
  ensure     => present,
  build_opts => ['--binary'],
}

# ensure rvm doesn't timeout finding binary rubies
# the umask line is the default content when installing rvm if file does not exist
file { '/etc/rvmrc':
  content => 'umask u=rwx,g=rwx,o=rx
                     export rvm_max_time_flag=20',
  mode    => '0664',
  before  => Class['rvm'],
}

class { 'rvm': }
rvm::system_user { 'vagrant': }
rvm_system_ruby {
  'ruby-1.9.3':
    default_use => true;
  'ruby-2.0.0':;
  'jruby':;
}

Hiera can also be used to define what rubies to install, making the Puppet code even less verbose

...
class { 'rvm': }
# rvm::system_user no longer needed
# rvm_system_ruby no longer needed

The equivalent hiera yaml configuration to the previous example

rvm::system_rubies:
  '1.9':
    default_use: true
  '2.0': {}
  'jruby-1.7': {}

rvm::system_users:
  - vagrant

Continuum-ruby

continuum-ruby is a Ruby library to interact with Apache Continuum, using the XML-RPC interface and enabling access to the working copy directories. continuum-ruby is now available in the Continuum Sandbox.

More info on the Continuum XML-RPC interface:

Example

continuum = Continuum::Continuum.new("my.continuum.host", 8080, "admin", "password", "/continuum"

# xml-rpc interface
xml_rpc = Continuum::XmlRpc.new(continuum)
ok, result = xml_rpc.build_project(1)
error = Continuum.parse_error(result) if !ok

# getting working copy files
working_copy = Continuum::WorkingCopy.new(continuum)
test_results = working_copy.get(1, "target/surefire-reports", "emailable-report.html")
files = working_copy.dir(1, "target")
files.each do |file|
file_content = working_copy.get(1, "target", file)
end

Using Subversion Ruby bindings

I tried to do some subversion hacking from Ruby, very simple things like add/remove files,
commits and so, and realized that there’s no documentation at all out there, just blog posts
here and there.

I finally got something working, including user authentication (that is not as easy as you would
expect) and ignoring https certificates not signed by a trusted CA. Something like committing a file is not as simple as it would seem.

You have to make sure you have the latest version installed. In linux it means installing the subversion-ruby package. In OS X is more complicated, you need to remove the preinstalled subversion, install the newer one from Collabnet, and move some files around.

mv /Library/Ruby/Site/1.8/svn /Library/Ruby/Site/1.8/svn.bak
mv /Library/Ruby/Site/1.8/universal-darwin9.0/svn /Library/Ruby/Site/1.8/universal-darwin9.0/svn.bak
ln -s /opt/subversion/lib/svn-ruby/svn /Library/Ruby/Site/1.8/svn
ln -s /opt/subversion/lib/svn-ruby/universal-darwin/svn /Library/Ruby/Site/1.8/universal-darwin9.0/svn

Once you have it installed then you can call the svn libraries

  require "svn/core"
  require "svn/client"
  require "svn/wc"
  require "svn/repos"

  make_context("") do |ctx|
    # checkout
    ctx.checkout SVN_URL, "/tmp"
  end

  # Add a file and commit with a message
  make_context("Adding a file") do |ctx|
    ctx.add f
    ctx.commit f
  end

  # from http://svn.collab.net/repos/svn/trunk/subversion/bindings/swig/ruby/test/util.rb
  def make_context(log)
    ctx = Svn::Client::Context.new

    # Function for commit messages
    ctx.set_log_msg_func do |items|
      [true, log]
    end

    # don't fail on non CA signed ssl server
    ctx.add_ssl_server_trust_file_provider

    # username and password
    ctx.add_simple_prompt_provider(0) do |cred, realm, username, may_save|
      cred.username = "myusername"
      cred.password = "mypassword"
      cred.may_save = false
    end
    # setup_auth_baton(ctx.auth_baton)
    return ctx unless block_given?
    begin
      yield ctx
    ensure
      ctx.destroy
    end
  end

Playing with Ruby and Rails

I have been playing with Ruby and Rails for a good number of months already and fond it quite interesting.
It’s fairly easy to start new projects and get going, although it’s also very easy to make
mistakes if you don’t know what’s going on behind the scenes. For instance, it’s very easy
to have the N+1 SQL problem, or dependency mismatches between machines.

What I like:

  • Migrations
  • Different environments (dev, test, production), and predefined configurations for each, like log level
  • Real time development, change a file and see the changes immediately.
  • AJAX support, very easy to create partial updates and requests

What I don’t like:

  • Dependency management, if you don’t define versions it will take whatever is installed in the system
    (but probably I’m just spoiled by using Maven for so long)
  • Debugging, it ends being puts statements, although there’s probably something helpful out there
  • The plugin ecosystem, it’s a big mess with plugins and forks of plugins, and forks of forks,… It’s too easy to fork, which makes users less likely to contribute the changes and just work on their version.
  • Scripting, mistakes like typos are very easy to do, and refactoring becomes a big PITA