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, delete: 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.
27 28 29 30 31 32 33 34 |
# File 'lib/blower/host.rb', line 27 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.
18 19 20 |
# File 'lib/blower/host.rb', line 18 def address @address end |
#name ⇒ Object
Returns the value of attribute name.
20 21 22 |
# File 'lib/blower/host.rb', line 20 def name @name end |
#user ⇒ Object
The default remote user.
15 16 17 |
# File 'lib/blower/host.rb', line 15 def user @user 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.
57 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 94 95 96 97 |
# File 'lib/blower/host.rb', line 57 def cp (froms, to, as: nil, quiet: false, delete: false) sleep DELAY if defined?(DELAY) 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"] if File.exist?(".blowignore") command += ["--exclude-from", ".blowignore"] end command += ["--delete"] if delete 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
154 155 156 |
# File 'lib/blower/host.rb', line 154 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.
148 149 150 |
# File 'lib/blower/host.rb', line 148 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.
45 46 47 48 49 50 51 52 53 |
# File 'lib/blower/host.rb', line 45 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.
107 108 109 |
# File 'lib/blower/host.rb', line 107 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.
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 140 141 142 143 144 |
# File 'lib/blower/host.rb', line 113 def sh (command, as: nil, quiet: false) sleep DELAY if defined?(DELAY) 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 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.
37 38 39 |
# File 'lib/blower/host.rb', line 37 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.
101 102 103 |
# File 'lib/blower/host.rb', line 101 def write (string, to, as: nil, quiet: false) cp StringIO.new(string), to, as: as, quiet: quiet end |