class Rye::Set

Rye::Set

Attributes

boxes[R]
name[R]
opts[R]
parallel[RW]

Run commands in parallel? A Boolean value. Default: false.

Public Class Methods

new(name='default', opts={}) click to toggle source
  • name The name of the set of machines

  • opts a hash of optional arguments

The opts hash is used as defaults for all for all Rye::Box objects. All args supported by Rye::Box are available here with the addition of:

  • :parallel => run the commands in parallel? true or false (default).

# File lib/rye/set.rb, line 25
def initialize(name='default', opts={})
  @name = name
  @boxes = []

  # These opts are use by Rye::Box and also passed to Net::SSH
  @opts = {
    :parallel => false,
    :user => Rye.sysinfo.user,
    :safe => true,
    :port => 22,
    :keys => [],
    :password => nil,
    :proxy => nil,
    :debug => nil,
    :error => STDERR,
  }.merge(opts)

  @parallel = @opts.delete(:parallel) # Rye::Box doesn't have :parallel

  @safe = @opts[:safe]
  @debug = @opts[:debug]
  @error = @opts[:error]

  @opts[:keys] = [@opts[:keys]].flatten.compact

  add_keys(@opts[:keys])
end

Public Instance Methods

[](key=nil) click to toggle source

See Rye::Box#[]

# File lib/rye/set.rb, line 120
def [](key=nil)
  run_command(:cd, key)
  self
end
add_box(*boxes) click to toggle source
  • boxes one or more boxes. Rye::Box objects will be added directly

to the set. Hostnames will be used to create new instances of Rye::Box and those will be added to the list.

# File lib/rye/set.rb, line 60
def add_box(*boxes)
  boxes = boxes.flatten.compact
  @boxes += boxes.collect do |box|
    box = Rye::Box.new(box, @opts) if box.is_a?(String)
    box.add_keys(@keys)
    box
  end
  self
end
Also aliased as: add_boxes
add_boxes(*boxes)
Alias for: add_box
add_key(*additional_keys)
Alias for: add_keys
add_keys(*additional_keys) click to toggle source

Add one or more private keys to each box. Also stores key paths in the set so when new boxes are added they will get the same keys,

  • additional_keys is a list of file paths to private keys

Returns the instance of Rye::Set

# File lib/rye/set.rb, line 75
def add_keys(*additional_keys)
  additional_keys = additional_keys.flatten.compact
  @opts[:keys] ||= []
  @opts[:keys] += additional_keys
  @opts[:keys].uniq!
  @boxes.each do |box|
    box.add_keys *additional_keys
  end
  self
end
Also aliased as: add_key
cd(key=nil) click to toggle source

alias :cd :'[]' # fix for jruby

# File lib/rye/set.rb, line 125
def cd(key=nil)
  run_command(:cd, key)
  self
end
empty?() click to toggle source

Are there any boxes in this set?

# File lib/rye/set.rb, line 131
def empty?
  @boxes.nil? || @boxes.empty?
end
inspect() click to toggle source
# File lib/rye/set.rb, line 114
def inspect
  a = [self.class.to_s, @name, @parallel, @opts.inspect, @boxes.inspect]
  %q{#<%s:%s parallel=%s opts=%s boxes=%s>} % a
end
keys() click to toggle source

See Rye#keys

# File lib/rye/set.rb, line 106
def keys
  Rye.keys
end
method_missing(meth, *args, &block) click to toggle source

Catches calls to Rye::Box commands. If meth is the name of an instance method defined in Rye::Cmd then we call it against all the boxes in +@boxes+. Otherwise this method raises a Rye::CommandNotFound exception. It will also raise a Rye::NoBoxes exception if this set has no boxes defined.

Returns a Rye::Rap object containing the responses from each Rye::Box.

# File lib/rye/set.rb, line 142
def method_missing(meth, *args, &block)
  # Ruby 1.8 populates Module.instance_methods with Strings. 1.9 uses Symbols.
  meth = (Rye.sysinfo.ruby[1] == 8) ? meth.to_s : meth.to_sym
  raise Rye::NoBoxes if @boxes.empty?
  if @safe
    raise Rye::CommandNotFound, meth.to_s unless Rye::Box.instance_methods.member?(meth)
  end
  run_command(meth, *args, &block)
end
remove_key(*keys)
Alias for: remove_keys
remove_keys(*keys) click to toggle source
# File lib/rye/set.rb, line 87
def remove_keys(*keys)
  @opts[:keys] ||= []
  @opts[:keys] -= keys.flatten.compact
  @boxes.each do |box|
    box.remove_keys keys.flatten.compact
  end
  self
end
Also aliased as: remove_key
root?() click to toggle source
# File lib/rye/set.rb, line 55
def root?; user.to_s == "root" end
run(cmd) click to toggle source
# File lib/rye/dsl.rb, line 5
def run cmd
  instance_eval &@@command[cmd]
end
setenv(n, v) click to toggle source

Add an environment variable. n and v are the name and value. Returns the instance of Rye::Set

# File lib/rye/set.rb, line 99
def setenv(n, v)
  run_command(:setenv, n, v)
  self
end
Also aliased as: setenvironment_variable
setenvironment_variable(n, v)
Alias for: setenv
to_s() click to toggle source
# File lib/rye/set.rb, line 110
def to_s
  "%s:%s" % [self.class.to_s, @name]
end
user() click to toggle source
# File lib/rye/set.rb, line 54
def user; (@opts || {})[:user]; end

Private Instance Methods

debug(msg) click to toggle source
# File lib/rye/set.rb, line 201
def debug(msg); @debug.puts msg if @debug; end
error(msg) click to toggle source
# File lib/rye/set.rb, line 202
def error(msg); @error.puts msg if @error; end
run_command(meth, *args, &block) click to toggle source

Determines whether to call the serial or parallel method, then calls it.

# File lib/rye/set.rb, line 155
def run_command(meth, *args, &block)
  runner = @parallel ? :run_command_parallel : :run_command_serial
  self.send(runner, meth, *args, &block)
end
run_command_parallel(meth, *args, &block) click to toggle source

Run the command on all boxes in parallel

# File lib/rye/set.rb, line 162
def run_command_parallel(meth, *args, &block)
  debug "P: #{meth} on #{@boxes.size} boxes (#{@boxes.collect {|b| b.host }.join(', ')})"
  threads = []

  raps = Rye::Rap.new(self)
  (@boxes || []).each do |box|
    threads << Thread.new do
      Thread.current[:rap] = box.send(meth, *args, &block) # Store the result in the thread
    end
  end

  threads.each do |t|
    Kernel.sleep 0.03 # Give the thread some breathing room

    begin
      t.join # Wait for the thread to finish
    rescue Exception => ex
      # Store the exception in the result
      raps << Rap.new(self, [ex])
      next
    end

    raps << t[:rap] # Grab the result
  end

  raps
end
run_command_serial(meth, *args, &block) click to toggle source

Run the command on all boxes in serial

# File lib/rye/set.rb, line 192
def run_command_serial(meth, *args, &block)
  debug "S: #{meth} on #{@boxes.size} boxes (#{@boxes.collect {|b| b.host }.join(', ')})"
  raps = Rye::Rap.new(self)
  (@boxes || []).each do |box|
    raps << box.send(meth, *args, &block)
  end
  raps
end