Class: Blower::Target

Inherits:
Object show all
Extended by:
Forwardable
Includes:
MonitorMixin
Defined in:
lib/blower/target.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, ssh: "ssh", scp: "scp") ⇒ Target

Returns a new instance of Target.


16
17
18
19
20
# File 'lib/blower/target.rb', line 16

def initialize (name, ssh: "ssh", scp: "scp")
  @name, @ssh, @scp = name, ssh, scp
  @data = {}
  super()
end

Instance Attribute Details

#dataObject (readonly)

Returns the value of attribute data


12
13
14
# File 'lib/blower/target.rb', line 12

def data
  @data
end

#nameObject (readonly)

Returns the value of attribute name


12
13
14
# File 'lib/blower/target.rb', line 12

def name
  @name
end

Instance Method Details

#cp(froms, to, as: nil, quiet: false, delete: false) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Copy files or directories to the host.


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/blower/target.rb', line 29

def cp (froms, to, as: nil, quiet: false, delete: false)
  as ||= @user
  output = ""
  synchronize do
    [froms].flatten.each do |from|
      if from.is_a?(String)
        to += "/" if to[-1] != "/" && from.is_a?(Array)
        command = ["rsync", "-e", @ssh, "-r"]
        if File.exist?(".blowignore")
          command += ["--exclude-from", ".blowignore"]
        end
        command += ["--delete"] if delete
        command += [*from, ":#{to}"]
        log.trace command.shelljoin, quiet: quiet
        IO.popen(command, in: :close, err: %i(child out)) do |io|
          until io.eof?
            begin
              output << io.read_nonblock(100)
            rescue IO::WaitReadable
              IO.select([io])
              retry
            end
          end
          io.close
          if !$?.success?
            log.fatal "exit status #{$?.exitstatus}: #{command}", quiet: quiet
            log.fatal output, quiet: quiet
            fail "failed to copy files"
          end
        end
      elsif from.respond_to?(:read)
        cmd = "echo #{Base64.strict_encode64(from.read).shellescape} | base64 -d > #{to.shellescape}"
        sh cmd, quiet: quiet
      else
        fail "Don't know how to copy a #{from.class}: #{from}"
      end
    end
  end
  true
end

#logObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Produce a Logger prefixed with the host name.


91
92
93
# File 'lib/blower/target.rb', line 91

def log
  @log ||= Logger.instance.with_prefix("on #{name}: ")
end

#sh(command, as: nil, quiet: false) ⇒ Object


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/blower/target.rb', line 70

def sh (command, as: nil, quiet: false)
  marker, output = SecureRandom.hex(32), nil
  ssh do |i, o, _|
    i.puts "echo #{marker}"
    i.puts "sh -c #{command.shellescape} 2>&1"
    i.puts "STATUS_#{marker}=$?"
    i.puts "echo #{marker}"
    i.flush
    o.readline("#{marker}\n")
    output = o.readline("#{marker}\n")[0..-(marker.length + 2)]
    i.puts "echo $STATUS_#{marker}"
    status = o.readline.to_i
    if status != 0
      fail FailedCommand, output
    end
    output
  end
end

#to_sObject

Represent the host as a string.


23
24
25
# File 'lib/blower/target.rb', line 23

def to_s
  @name
end