class Pennyworth::HostRunner

Public Class Methods

new(host_name, host_config, username = "root") click to toggle source
# File lib/pennyworth/host_runner.rb, line 20
def initialize(host_name, host_config, username = "root")
  @host_name = host_name
  @username = username
  config_file = host_config.config_file

  host = host_config.host(host_name)
  if !host
    raise InvalidHostError.new("Host '#{host_name}' is not defined in '#{config_file}'")
  end

  @ip = host["address"]
  @base_snapshot_id = host["base_snapshot_id"]
  if !@ip
    raise InvalidHostError.new(
      "Missing 'address' field for host '#{host_name}' in '#{config_file}'"
    )
  end
  if should_cleanup && !@base_snapshot_id
    raise InvalidHostError.new(
      "Missing 'base_snapshot_id' field for host '#{host_name}' in '#{config_file}'"
    )
  end

  @command_runner = RemoteCommandRunner.new(@ip, @username)
  @locker = LockService.new(host_config.lock_server_address)
end

Public Instance Methods

cleanup() click to toggle source
# File lib/pennyworth/host_runner.rb, line 62
def cleanup
  return if @cleaned_up || !@connected

  remote = RemoteCommandRunner.new(@ip, @username)
  remote.run "snapper", "create", "-c", "number", "--pre-number", @base_snapshot_id.to_s,
    "--description", "pennyworth_snapshot"
  remote.run "snapper", "cleanup", "number"
  remote.run "snapper", "undochange", "#{@base_snapshot_id}..0"
  remote.run "bash", "-c", "reboot &"
  @cleaned_up = true
end
start() click to toggle source
# File lib/pennyworth/host_runner.rb, line 47
def start
  if !@locker.request_lock(@host_name)
    raise LockError.new("Host '#{@host_name}' already locked")
  end

  connect

  if should_cleanup
    check_cleanup_capabilities
    install_cleanup_interrupt_handler
  end

  @ip
end
stop() click to toggle source
# File lib/pennyworth/host_runner.rb, line 74
def stop
  if should_cleanup
    cleanup
    uninstall_cleanup_interrupt_handler
  end

  @locker.release_lock(@host_name)
end

Private Instance Methods

check_cleanup_capabilities() click to toggle source
# File lib/pennyworth/host_runner.rb, line 98
def check_cleanup_capabilities
  begin
    RemoteCommandRunner.new(@ip, @username).run "snapper", "--help"
  rescue Cheetah::ExecutionFailed
    raise CommandNotFoundError.new(
      "Snapper needs to be installed on the test system '#{@ip}' for the automatic cleanup."
    )
  end
  @connected = true
end
connect() click to toggle source

Makes sure the we can connect to the remote system as root (without a password or passphrase)

# File lib/pennyworth/host_runner.rb, line 87
def connect
  Cheetah.run "ssh", "-q", "-o", "BatchMode=yes", "root@#{@ip}"
rescue Cheetah::ExecutionFailed
  raise SshConnectionFailed.new(
    "Could not establish SSH connection to host '#{@ip}'. Please make sure that " \
    "you can connect non-interactively as root, e.g. using ssh-agent.\n\n" \
    "To copy your default ssh key to the machine run:\n" \
    "ssh-copy-id root@#{@ip}"
  )
end
install_cleanup_interrupt_handler() click to toggle source
# File lib/pennyworth/host_runner.rb, line 113
def install_cleanup_interrupt_handler
  @old_interrupt_handler = trap("INT") do
    trap("INT") do
      exit!(1)
    end

    puts "RSpec is shutting down. Resetting test host '#{@ip}'." \
      "Interrupt again to force exit."
    cleanup
    puts "Done."

    @old_interrupt_handler.call
  end
end
should_cleanup() click to toggle source
# File lib/pennyworth/host_runner.rb, line 109
def should_cleanup
  !ENV["SKIP_HOST_CLEANUP"]
end
uninstall_cleanup_interrupt_handler() click to toggle source
# File lib/pennyworth/host_runner.rb, line 128
def uninstall_cleanup_interrupt_handler
  # Restore old interrupt handler
  trap("INT", @old_interrupt_handler) if defined?(@old_interrupt_handler)
end