Class: Cute::TakTuk::TakTuk

Inherits:
Object
  • Object
show all
Defined in:
lib/cute/taktuk.rb

Overview

This class wraps the command TakTuk and generates automatically the long CLI options for taktuk command.

Constant Summary collapse

VALID_STREAMS =
[:output, :error, :status, :connector, :state, :info, :message, :taktuk ]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hostlist, options = {:connector => 'ssh'}) ⇒ TakTuk

Returns a new instance of TakTuk.

Raises:

  • (ArgumentError)


390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
# File 'lib/cute/taktuk.rb', line 390

def initialize(hostlist,options = {:connector => 'ssh'})
  raise ArgumentError.new("options parameter has to be a hash") unless options.is_a?(Hash)

  @binary = 'taktuk'
  @options = Options[options.merge({ :streams => [:output, :error, :status ]})] if options[:streams].nil?
  @options.merge!({:connector => 'ssh'}) if options[:connector].nil?
  @streams = Stream.new(@options[:streams])
  # @streams = Stream.new([:output,:error,:status, :state])

  @hostlist = Hostlist.new(hostlist)
  @commands = Commands.new

  @args = nil
  @stdout = nil
  @stderr = nil
  @status = nil

  @exec_cmd = nil
  @curthread = nil
  @connector = @options[:connector]
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args) ⇒ Object



576
577
578
579
580
581
582
# File 'lib/cute/taktuk.rb', line 576

def method_missing(meth,*args)
  @commands << (meth.to_s.gsub(/_/,' ').strip.downcase)
  args.each do |arg|
    @commands.push(arg.strip.downcase)
  end
  self
end

Instance Attribute Details

#argsObject (readonly)

Returns the value of attribute args.



386
387
388
# File 'lib/cute/taktuk.rb', line 386

def args
  @args
end

#binaryObject

Returns the value of attribute binary.



385
386
387
# File 'lib/cute/taktuk.rb', line 385

def binary
  @binary
end

#commandsObject (readonly)

Returns the value of attribute commands.



386
387
388
# File 'lib/cute/taktuk.rb', line 386

def commands
  @commands
end

#exec_cmdObject (readonly)

Returns the value of attribute exec_cmd.



386
387
388
# File 'lib/cute/taktuk.rb', line 386

def exec_cmd
  @exec_cmd
end

#statusObject (readonly)

Returns the value of attribute status.



386
387
388
# File 'lib/cute/taktuk.rb', line 386

def status
  @status
end

#stderrObject (readonly)

Returns the value of attribute stderr.



386
387
388
# File 'lib/cute/taktuk.rb', line 386

def stderr
  @stderr
end

#stdoutObject (readonly)

Returns the value of attribute stdout.



386
387
388
# File 'lib/cute/taktuk.rb', line 386

def stdout
  @stdout
end

#streamsObject

Returns the value of attribute streams.



385
386
387
# File 'lib/cute/taktuk.rb', line 385

def streams
  @streams
end

Instance Method Details

#[](command, prefix = '[', suffix = ']') ⇒ Object



571
572
573
574
# File 'lib/cute/taktuk.rb', line 571

def [](command,prefix='[',suffix=']')
  @commands << "#{prefix} #{command} #{suffix}"
  self
end

#exec(cmd) ⇒ Object

It executes a command on multiple hosts. All output is printed via stdout and stderr. Note that this method returns immediately, and requires a call to the loop method in order for the command to actually execute. The execution is done by TakTuk using broadcast exec.

Example

tak.exec("hostname")
tak.exec("mkdir ~/test")
tak.loop() # to trigger the execution of commands

Parameters:

  • cmd (String)

    Command to execute.



509
510
511
512
513
514
# File 'lib/cute/taktuk.rb', line 509

def exec(cmd)
  mode = "broadcast"
  @commands << "#{mode} exec"
  @commands << "[ #{cmd} ]"
  @commands << ';' # TakTuk command separator
end

#exec!(cmd) ⇒ Hash

It executes a command on multiple hosts capturing the output, and other information related with the execution. It blocks until the command finishes.

Example

tak.exec!("uname -r") #=> {"node2"=>{:output=>"3.2.0-4-amd64", :status=>0}, "node3"=>{:output=>"3.2.0-4-amd64", :status=>0}, ...}

Parameters:

  • cmd (String)

    Command to be executed

Returns:

  • (Hash)

    Result data structure



543
544
545
546
547
548
549
# File 'lib/cute/taktuk.rb', line 543

def exec!(cmd)
  loop() unless @commands.empty?
  exec(cmd)
  results = run!()
  @commands = Commands.new
  return results
end

#free!Object Also known as: close



471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
# File 'lib/cute/taktuk.rb', line 471

def free!()
  @binary = nil
  @options = nil
  # if @streams
  #   @streams.each_value do |stream|
  #     stream.free if stream
  #     stream = nil
  #   end
  # end
  @hostlist.free if @hostlist
  @hostlist = nil
  @commands = nil
  @args = nil
  @stdout = nil
  @stderr = nil
  @status = nil
  @exec = nil
  @curthread = nil
end

#input(opts = {}) ⇒ Object

Manages the taktuk command input

Example

tak.exec("wc -w")
tak.input(:data => "data data data data")

tak.exec("tar xvf -")
tak.input(:file => "test_file.tar")

Parameters:

  • opts (Hash) (defaults to: {})

    Options for the type of data

Options Hash (opts):

  • :data (String)

    Raw data to be used as the input of a command

  • :filename (String)

    a file to be used as the input of a command



563
564
565
566
567
568
# File 'lib/cute/taktuk.rb', line 563

def input(opts = {})
  mode = "broadcast"
  @commands << "#{mode} input #{opts.keys.first}"
  @commands << "[ #{opts.values.first} ]"
  @commands << ';'
end

#kill!Object



463
464
465
466
467
468
469
# File 'lib/cute/taktuk.rb', line 463

def kill!()
  unless @exec.nil?
    @exec.kill
    @exec = nil
  end
  free!()
end

#loopObject

It executes the commands so far stored in the @commands variable and reinitialize the variable for post utilization.



456
457
458
459
460
461
# File 'lib/cute/taktuk.rb', line 456

def loop ()
  run!()
  $stdout.print(@stdout)
  $stderr.print(@stderr)
  @commands = Commands.new
end

#put(source, dest) ⇒ Object

It transfers a file to all the machines in parallel.

Example

tak.put("hosts.allow_template", "/etc/hosts.allow")

Parameters:

  • source (String)

    Source path for the file to be transfer

  • dest (String)

    Destination path for the file to be transfer



524
525
526
527
528
529
530
# File 'lib/cute/taktuk.rb', line 524

def put(source,dest)
  mode = "broadcast"
  @commands << "#{mode} put"
  @commands << "[ #{source} ]"
  @commands << "[ #{dest} ]"
  @commands << ';' # TakTuk command separator
end

#raw!(string) ⇒ Object



491
492
493
494
# File 'lib/cute/taktuk.rb', line 491

def raw!(string)
  @commands << string.strip
  self
end

#run!(opts = {}) ⇒ Object



412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
# File 'lib/cute/taktuk.rb', line 412

def run!(opts = {})
  @curthread = Thread.current
  @args = []
  @args += @options.to_cmd

  @streams.types.each{ |name|
    @args << '-o'
    @args << "#{name}=#{@streams.to_cmd}"
  }

  connector = build_connector
  @args += ["--connector", "#{connector}"] unless connector.nil?

  @args += @hostlist.to_cmd
  @args += @commands.to_cmd

  hosts = @hostlist.to_a
  outputs_size = opts[:outputs_size] || 0
  @exec_cmd = Cute::Execute[@binary,*@args].run!(
                                       :stdout_size => outputs_size * hosts.size,
                                       :stderr_size => outputs_size * hosts.size,
                                       :stdin => false
                                          )
  @status, @stdout, @stderr, emptypipes = @exec_cmd.wait({:checkstatus=>false})

  unless @status.success?
    @curthread = nil
    return false
  end

  unless emptypipes
    @curthread = nil
    @stderr = "Too much data on the TakTuk command's stdout/stderr"
    return false
  end

  results = @streams.parse(@stdout)
  @curthread = nil

  results
end