Icinga REST ruby gem

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.

, , , ,

Leave a Comment

Install ruby1.9.2 from source using Puppet

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.

, , ,

Leave a Comment

3D-printed vertebrae!

WARNING: This post contains very intimate images of parts of my anatomy ;)

I was unlucky enough to have an accident in a circus class in June, and fractured my spine. There followed a dull 3 months wearing a spine brace, but fortunately there doesn’t seem to be any long-term damage.

Being a geek, I asked the hospital for a digital copy of my CT scans, which they gave me on a DVD. The DVD comes with a basic HTML front-end to view the pictures, like this.

That’s not very informative, without several years of medical training, and there was a whole bunch of other stuff on the disk which, I assumed, were the original source files from the CT scanner. So, I had a look for an open source viewer for that data.

I found OsiriX which is a truly amazing program. After a few minutes of fiddling, I was playing with a 3D representation of my spine, rotating it, zooming in and out.

(You can see the damage to the lower of the 2 vertebrae shown – it should be the same size and shape as the one above)

So, that was fun. But then I decided to geek it up a level and see if I could get a 3D print.

You can export from OsiriX in a number of standard 3D formats. By exporting a .obj file, I could pull that into Meshlab, another great open source program, and clean up the 3D model a bit – deleting some “floating” parts and closing a couple of holes. I’m by no means a 3D modelling expert, and it shows, but I managed to tidy things up a little bit. You’ll need a fairly powerful machine – the vertex map of my scan had nearly 600,000 vertices, which takes quite a bit of memory and CPU to manipulate.

Finally, I had a clean enough .obj file to send off to be printed.

I chose i.materialise Their “3D Print Lab” has a really nice interface and lets you change scale and choose from several printing materials, allowing you to see the costs and properties of each. I chose to print my model at 50% scale in polyamide, which came in at around €35.

After submitting the job, Dmitriy at i.materialise was really helpful, further cleaning up the model before sending it to print (it turns out my ribs would have fallen off – who knew?)

So, here’s the finished product.

It’s of no practical use whatsoever, but it was a fun bit of geeking about.

PS: Don’t ever fracture your spine – it’s a really bad idea.

Leave a Comment

IP Ranges gem

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.

Leave a Comment

Follow

Get every new post delivered to your Inbox.