Posts Tagged ‘ruby’

Icinga REST ruby gem

October 8, 2011

I’ve just published a gem to simplify access to the Icinga REST API.

The Icinga REST API can be use to allow nodes in a multi-server system to get information about the overall state of the system from the monitoring server, without requiring them to have detailed information about the other nodes in the system. This can be quite handy.

For example, let’s say one server in a multi-server system wants to take itself out of the active server pool to carry out some long-running, processor intensive task, and then put itself back into service once it has finished. This is fine, unless too many other, similar servers try to do the same thing at the same time. In that case, there might be too few active servers left to handle the realtime load on the system.

One option is for the server to say “I want to go out of service, but I’ll only do that if fewer than N of my siblings are currently out of service.” Assuming that our Icinga monitoring server knows about every node (which it should), then we could do something like this;

    #!/usr/bin/env ruby

    require 'rubygems'
    require 'icinga_rest'

    check = IcingaRest::ServiceCheck.new(
      :host    => 'my.icinga.host',
      :authkey => 'mysecretapikey',
      :filter  => [
        {:host_name    => 'web*'},
        {:service_name => 'In Service', :state => :critical}
      ]
    )

    puts check.count

Then, we can make a decision based on the value of check.count to see if this server is allowed to take a break.

That’s about all that the gem can be used for right now. I might extend it as I think of more ways to use the monitoring server to coordinate the activities of the various servers in a system.

Updated: The code is up on Github, here.

Updated: Thanks to a tip from Erik Eide, the gem no longer has to shell out to wget to call the Icinga REST API. The Addressable gem can handle the malformed URLs that the API requires.

Advertisements

Install ruby1.9.2 from source using Puppet

October 6, 2011

I usually use Ubuntu 10.04 as my server platform. Now that I’m switching to ruby 1.9.2 in production, the utter crapness of the built-in Ubuntu packages has become unsupportable (ruby 1.9.1 doesn’t work with Bundler, for example).

So, I wanted a way to install ruby 1.9.2 using Puppet. This is what I came up with. The files fit together like this;

In my site.pp file, I’ve got this;

import "ruby192"
include ruby

The init.pp file just contains this;

import "*"

The real fun is in the ruby.pp file;

class ruby {

  exec { "apt-update":
    command => "/usr/bin/apt-get update"
  }

  # pre-requisites
  package { [
      "gcc",
      "g++",
      "build-essential",
      "libssl-dev",
      "libreadline5-dev",
      "zlib1g-dev",
      "linux-headers-generic"
    ]:
    ensure => "installed",
    require => Exec["apt-update"]
  }

  # put the build script in /root
  file { "/root/build-ruby.sh":
    ensure => "present",
    source => "puppet:///modules/ruby192/build-ruby.sh",
    mode => 755
  }

  # run the build script
  exec { "build-ruby192":
    command => "/root/build-ruby.sh",
    cwd => "/root",
    timeout => 0,
    creates => "/usr/bin/ruby",
    require => File["/root/build-ruby.sh"]
  }

  # update rubygems
  exec { "update-rubygems":
    command => "/usr/bin/gem update --system",
    unless  => "/usr/bin/gem -v |/bin/grep ^1.8",
    require => Exec["build-ruby192"]
  }

}

As you can see, it updates the apt cache, installs some pre-requisites and then runs a script to build ruby 1.9.2 from source. The “timeout => 0” line is important. Without it, puppet will not allow long enough for the build script to run completely. Here’s the build script;

#!/bin/bash

RUBY_VERSION='ruby-1.9.2-p290'

wget "http://ftp.ruby-lang.org/pub/ruby/1.9/${RUBY_VERSION}.tar.gz"
tar xzf ${RUBY_VERSION}.tar.gz
cd ${RUBY_VERSION}
./configure --prefix=/usr && make && make install

That will install ruby 1.9.2 and rubygems, so all that remains for the ruby.pp module is to update rubygems to the latest version.

IP Ranges gem

September 10, 2011

I just published a gem to help manage ranges of IP numbers.

It allows you to take lots of arbitrary IP data like this;

  • 1.2.3.4
  • 1.2.1.254..1.3.4.4
  • 1.2.0.0/16

…and find out which ranges include or overlap with others. In this case, it provides output like this;

1.2.3.4 is contained by range 1.2.1.254..1.3.4.4
1.2.3.4 is contained by range 1.2.0.0/16
1.2.1.254..1.3.4.4 overlaps with 1.2.0.0/16

Here’s the source.