Class: Blower::Host
- Extended by:
- Forwardable
- Includes:
- MonitorMixin
- Defined in:
- lib/blower/host.rb
Instance Attribute Summary collapse
-
#address ⇒ Object
The host adress.
-
#name ⇒ Object
Returns the value of attribute name.
-
#user ⇒ Object
The default remote user.
-
#via ⇒ Object
The gateway host.
Instance Method Summary collapse
-
#cp(froms, to, as: nil, quiet: false) ⇒ Object
private
Copy files or directories to the host.
-
#gateway ⇒ Object
private
Connect to the host as a Gateway.
-
#initialize(address, data: {}, user: "root", via: nil, name: address) ⇒ Host
constructor
A new instance of Host.
-
#log ⇒ Object
private
Produce a Logger prefixed with the host name.
-
#ping ⇒ Object
private
Attempt to connect to port 22 on the host.
-
#read(filename, as: nil, quiet: false) ⇒ Object
private
Read a host file.
-
#sh(command, as: nil, quiet: false) ⇒ Object
private
Execute a command on the host and return its output.
-
#to_s ⇒ Object
Represent the host as a string.
-
#write(string, to, as: nil, quiet: false) ⇒ Object
private
Write a string to a host file.
Constructor Details
#initialize(address, data: {}, user: "root", via: nil, name: address) ⇒ Host
Returns a new instance of Host.
28 29 30 31 32 33 34 35 |
# File 'lib/blower/host.rb', line 28 def initialize (address, data: {}, user: "root", via: nil, name: address) @address = address @name = name @user = user @data = data @via = via super() end |
Instance Attribute Details
#address ⇒ Object
The host adress.
19 20 21 |
# File 'lib/blower/host.rb', line 19 def address @address end |
#name ⇒ Object
Returns the value of attribute name.
21 22 23 |
# File 'lib/blower/host.rb', line 21 def name @name end |
#user ⇒ Object
The default remote user.
16 17 18 |
# File 'lib/blower/host.rb', line 16 def user @user end |
Instance Method Details
#cp(froms, to, as: nil, quiet: 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.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/blower/host.rb', line 58 def cp (froms, to, as: nil, quiet: 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_command, "-r"] command += [*from, "#{as}@#{@address}:#{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 |
#gateway ⇒ 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.
Connect to the host as a Gateway
149 150 151 |
# File 'lib/blower/host.rb', line 149 def gateway () Net::SSH::Gateway.new(address, user) end |
#log ⇒ 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.
Produce a Logger prefixed with the host name.
143 144 145 |
# File 'lib/blower/host.rb', line 143 def log @log ||= Logger.instance.with_prefix("on #{self}: ") end |
#ping ⇒ 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.
Attempt to connect to port 22 on the host.
46 47 48 49 50 51 52 53 54 |
# File 'lib/blower/host.rb', line 46 def ping () log.debug "Pinging" Timeout.timeout(1) do TCPSocket.new(address, 22).close end true rescue Timeout::Error, Errno::ECONNREFUSED fail "Failed to ping #{self}" end |
#read(filename, as: nil, quiet: 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.
Read a host file.
103 104 105 |
# File 'lib/blower/host.rb', line 103 def read (filename, as: nil, quiet: false) Base64.decode64 sh("cat #{filename.shellescape} | base64", as: as, quiet: quiet) end |
#sh(command, as: nil, quiet: 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.
Execute a command on the host and return its output.
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/blower/host.rb', line 109 def sh (command, as: nil, quiet: false) as ||= @user output = "" synchronize do log.debug "sh #{command}", quiet: quiet result = nil ch = ssh(as).open_channel do |ch| ch.request_pty do |ch, success| "failed to acquire pty" unless success ch.exec(command) do |_, success| fail "failed to execute command" unless success ch.on_data do |_, data| log.trace "received #{data.bytesize} bytes stdout", quiet: quiet output << data end ch.on_extended_data do |_, _, data| log.trace "received #{data.bytesize} bytes stderr", quiet: quiet output << data.colorize(:red) end ch.on_request("exit-status") do |_, data| result = data.read_long log.trace "received exit-status #{result}", quiet: quiet end end end end ch.wait fail FailedCommand, output if result != 0 output end end |
#to_s ⇒ Object
Represent the host as a string.
38 39 40 |
# File 'lib/blower/host.rb', line 38 def to_s "#{@user}@#{@address}" end |
#write(string, to, as: nil, quiet: 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.
Write a string to a host file.
97 98 99 |
# File 'lib/blower/host.rb', line 97 def write (string, to, as: nil, quiet: false) cp StringIO.new(string), to, as: as, quiet: quiet end |