Class: Loom::Runner

Inherits:
Object
  • Object
show all
Includes:
Loom::RunnerModule::SSHKitConnector
Defined in:
lib/loom/runner.rb

Overview

TODO: Make Loom::Runner a module and move this to Loom::Runner::Core. Loom::RunnerModule is set up as a temporary namespace until that happens.

Constant Summary collapse

PatternExecutionError =
Class.new Loom::LoomError
FailFastExecutionError =
Class.new PatternExecutionError

Constants included from Loom::RunnerModule::SSHKitConnector

Loom::RunnerModule::SSHKitConnector::SSHConnectionError, Loom::RunnerModule::SSHKitConnector::UnexpectedHostError

Instance Method Summary collapse

Methods included from Loom::RunnerModule::SSHKitConnector

#on_host

Constructor Details

#initialize(loom_config, pattern_slugs = [], other_facts = {}) ⇒ Runner

Returns a new instance of Runner.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/loom/runner.rb', line 12

def initialize(loom_config, pattern_slugs=[], other_facts={})
  @pattern_slugs = pattern_slugs
  @loom_config = loom_config
  @other_facts = other_facts

  @run_failures = []
  @result_reports = []

  # these are initialized in +load+
  @inventory_list = nil
  @active_hosts = nil
  @pattern_refs = nil
  @mod_loader = nil

  Loom.log.debug1(self) do
    "initialized runner with config => #{loom_config.dump}"
  end

  @caught_sig_int = false
end

Instance Method Details

#run(dry_run) ⇒ Object



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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/loom/runner.rb', line 33

def run(dry_run)
  install_signal_traps

  begin
    load

    if @pattern_refs.empty?
      Loom.log.warn "no patterns given, there's no work to do"
      return
    end
    if @active_hosts.empty?
      Loom.log.warn "no hosts in the active inventory"
      return
    end

    hostnames = @active_hosts.map(&:hostname)
    Loom.log.info do
      "executing patterns #{@pattern_slugs} across hosts #{hostnames}"
    end

    run_internal dry_run

    unless @run_failures.empty?
      raise PatternExecutionError, @run_failures
    end
  rescue Loom::Trap::SignalExit => e
    Loom.log.error "exiting on signal  => #{e.signal}"
    # Exit with the signal code or 40 for unknown Signal
    code = Signal.list[e.signal] || 40
    exit code
  rescue PatternExecutionError => e
    num_patterns_failed = @run_failures.size
    Loom.log.error "error executing #{num_patterns_failed} patterns => #{e}, run with -d for more"
    Loom.log.debug e.backtrace.join "\n\t"
    # TODO: I think the max return code is 255. Cap this if so.
    exit 100 + num_patterns_failed
  rescue SSHKit::Runner::ExecuteError => e
    Loom.log.error "wrapped SSHKit::Runner::ExecuteError, run with -d for more"
    Loom.log.error e.cause
    Loom.log.debug e.cause.backtrace.join "\n\t"
    Loom.log.debug1(self) { "Original error:" }
    Loom.log.debug1(self) { e.inspect }
    Loom.log.debug1(self) { e.backtrace.join "\n\t" }
    exit 97
  rescue Loom::LoomError => e
    Loom.log.error "Loom::LoomError => #{e.inspect}, run with -d for more"
    backtrace = e.cause.nil? ? e.backtrace : e.cause.backtrace
    Loom.log.debug backtrace.join "\n\t"
    Loom.log.debug backtrace.join "\n\t"
    exit 98
  rescue => e
    # TODO: Make error/exception logging look like this everywhere
    Loom.log.fatal "fatal error =>\n#{e.inspect}\n\t#{e.backtrace.join("\n\t\t")}"

    loom_files = @loom_config.files.loom_files
    loom_errors = e.backtrace.select { |line| line =~ /(#{loom_files.join("|")})/ }
    Loom.log.error "Loom file errors: \n\t" + loom_errors.join("\n\t")
    exit 99
  end
end