class Warg::Host

Attributes

address[R]
id[R]
port[R]
uri[R]
user[R]

Public Class Methods

from(host_data) click to toggle source
# File lib/warg.rb, line 719
def self.from(host_data)
  case host_data
  when Host
    host_data
  when Hash
    attributes = host_data.transform_keys(&:to_sym)

    new(**attributes)
  when Array
    if host_data.length == 1 && Hash === host_data[0]
      from(host_data[0])
    elsif String === host_data[0]
      last_item_index = -1
      attributes = Parser.(host_data[0])

      if Hash === host_data[-1]
        last_item_index = -2

        more_properties = host_data[-1].transform_keys(&:to_sym)
        attributes[:properties].merge!(more_properties)
      end

      host_data[1..last_item_index].each do |property|
        name, value = property.to_s.split("=", 2)
        attributes[:properties][name.to_sym] = value
      end

      new(**attributes)
    else
      raise InvalidHostDataError.new(host_data)
    end
  when String
    new(**Parser.(host_data))
  else
    raise InvalidHostDataError.new(host_data)
  end
end
new(user: nil, address:, port: nil, properties: {}) click to toggle source
# File lib/warg.rb, line 763
def initialize(user: nil, address:, port: nil, properties: {})
  @user = user
  @address = address
  @port = port
  @properties = properties.transform_keys(&:to_s)

  build_uri!
end

Public Instance Methods

==(other) click to toggle source
# File lib/warg.rb, line 794
def ==(other)
  self.class == other.class && uri == other.uri
end
Also aliased as: eql?
[](name) click to toggle source
# File lib/warg.rb, line 782
def [](name)
  @properties[name.to_s]
end
[]=(name, value) click to toggle source
# File lib/warg.rb, line 786
def []=(name, value)
  @properties[name.to_s] = value

  build_uri!

  value
end
create_directory(directory) click to toggle source
# File lib/warg.rb, line 855
def create_directory(directory)
  command = "mkdir -p #{directory}"

  connection.open_channel do |channel|
    channel.exec(command)
    channel.wait
  end

  connection.loop
end
create_file_from(content, path:, mode: 0644) click to toggle source
# File lib/warg.rb, line 866
def create_file_from(content, path:, mode: 0644)
  filename = "#{id}-#{File.basename(path)}"

  tempfile = Tempfile.new(filename)
  tempfile.chmod(mode)
  tempfile.write(content)
  tempfile.rewind

  upload tempfile, to: path

  tempfile.unlink
end
download(path, to: nil) click to toggle source
# File lib/warg.rb, line 883
def download(path, to: nil)
  content = connection.scp.download!(path)

  if to
    file = File.new(to, "w+b")
  else
    file = Tempfile.new(path)
  end

  file.write(content)
  file.rewind

  file
end
eql?(other)
Alias for: ==
hash() click to toggle source
# File lib/warg.rb, line 800
def hash
  inspect.hash
end
inspect() click to toggle source
# File lib/warg.rb, line 898
def inspect
  %{#<#{self.class.name} uri=#{@uri.to_s}>}
end
matches?(filters) click to toggle source
# File lib/warg.rb, line 772
def matches?(filters)
  filters.all? do |name, value|
    if respond_to?(name)
      send(name) == value
    else
      @properties[name.to_s] == value
    end
  end
end
run_command(command, &setup) click to toggle source
# File lib/warg.rb, line 804
def run_command(command, &setup)
  outcome = CommandOutcome.new(self, command, &setup)

  connection.open_channel do |channel|
    channel.exec(command) do |_, success|
      outcome.command_started!

      channel.on_data do |_, data|
        outcome.collect_stdout(data)
      end

      channel.on_extended_data do |_, __, data|
        outcome.collect_stderr(data)
      end

      channel.on_request("exit-status") do |_, data|
        outcome.exit_status = data.read_long
      end

      channel.on_request("exit-signal") do |_, data|
        outcome.exit_signal = data.read_string
      end

      channel.on_open_failed do |_, code, reason|
        outcome.connection_failed(code, reason)
      end

      channel.on_close do |_|
        outcome.command_finished!
      end
    end

    channel.wait
  end

  connection.loop

  outcome
rescue SocketError, Errno::ECONNREFUSED, Net::SSH::AuthenticationFailed => error
  outcome.connection_failed(-1, "#{error.class}: #{error.message}")
  outcome
end
run_script(script, &setup) click to toggle source
# File lib/warg.rb, line 847
def run_script(script, &setup)
  create_directory script.install_directory

  create_file_from script.content, path: script.install_path, mode: 0755

  run_command(script.remote_path, &setup)
end
to_s() click to toggle source
# File lib/warg.rb, line 902
def to_s
  @uri.to_s
end
upload(file, to:) click to toggle source
# File lib/warg.rb, line 879
def upload(file, to:)
  connection.scp.upload!(file, to)
end

Private Instance Methods

build_uri!() click to toggle source
# File lib/warg.rb, line 922
def build_uri!
  @uri = URI.parse("ssh://")

  @uri.user = @user
  @uri.host = @address
  @uri.port = @port

  unless @properties.empty?
    @uri.query = @properties.map { |name, value| "#{name}=#{value}" }.join("&")
  end

  @id = Digest::SHA1.hexdigest(@uri.to_s)
end
connection() click to toggle source
# File lib/warg.rb, line 908
def connection
  if defined?(@connection)
    @connection
  else
    options = { non_interactive: true }

    if port
      options[:port] = port
    end

    @connection = Net::SSH.start(address, user || Warg.default_user, options)
  end
end