Blender-Serf

Provides Serf based host discovery and job dispatch mechanism for Blender

Installation

  gem install blender-serf

Usage

Config

Blender-serf uses Serf's RPC interface for communication between serf and ruby. Following serf RPC connection specific configuration options are allowed

  • host (defaults to localhost)
  • port (defaults to 7373)
  • authkey (rpc authenticatioin key, default is nil)

Example

config(:serf, host: '127.0.0.1', port: 7373, authkey: 'foobar')

Using serf for host discovery

Serf provides cluster membership list via members and members_filtered RPC calls, among them Blender-Serf uses members_filtered RPC command for host discovery. Following is an example of obtaining all live members of a cluster

  require 'blender/serf'
  members(search(:serf, status: 'alive'))
  ruby_task 'test' do
    execute do |host|
      Blender::Log.info(host)
    end
  end

Member list can be obtained based on serf tags or name.

Filter by tag expect tags to be supplied as hash (key value pair), which allows grouping hosts by multiple tags

  members(search(:serf, tags: {'role'=>'db'}))
  ruby_task 'test' do
    execute do |host|
      Blender::Log.info(host)
    end
  end

Filter by name, the specification string can be a pattern as well

  members(search(:serf, name: 'foo-baar-*'))
  ruby_task 'test' do
    execute do |host|
      Blender::Log.info(host)
    end
  end

Combinations of all three filtering mechanism is valid as well

  members(search(:serf, name: 'foo-baar-*', status: 'alive', tags:{'datacenter' => 'eu-east-2a'}))
  ruby_task 'test'
    execute do |host|
      Blender::Log.info(host)
    end
  end

Using serf for job dispatch

Serf agents allow job execution via event handlers, where the execution details is captured by the handler, while trigger mechanism is controlled by serf event. Blender-Serf uses serf query event type to dispatch event and check for successfull response. The handler itself, and associated serf' configyration needs to be setup externally (bake it in your image, or use a configuration managemenet system like chef, puppet, ansible or salt for this).

Following example will trigger serf query event test against 3 nodes, one by one

  extend Blender::SerfDSL
  members(['node_1', 'node_2', 'node_3'])
  serf_task 'test'

A more elaborate example

  extend Blender::SerfDSL
  members(['node_1', 'node_2', 'node_3'])
  serf_task 'start_nginx' do
    query 'nginx'
    payload 'start'
    timeout 3
  end

Which might be accmoplished by the following handler script (needs to be present aprior)

require 'serfx/utils/handler'

include Serfx::Utils::Handler


on :query, 'nginx' do |event|
  case event.payload
  when 'start'
    %x{/etc/init.d/nginx start}
  when 'stop'
  # ...
  when 'check'
  # ...
  end
end

run

Supported ruby versions

Blender-serf currently support the following MRI versions:

  • Ruby 1.9.3
  • Ruby 2.1

License

Apache 2

Contributing

  1. Fork it ( https://github.com/PagerDuty/blender-serf/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request