class ForemanMaintain::Runner

Class responsible for running the scenario

Constants

FAILURE_EXIT_CODE
WARNING_EXIT_CODE

Attributes

exit_code[R]
reporter[R]

Public Class Methods

new(reporter, scenarios, options = {}) click to toggle source
# File lib/foreman_maintain/runner.rb, line 12
def initialize(reporter, scenarios, options = {})
  options.validate_options!(:assumeyes, :whitelist, :force, :rescue_scenario)
  @assumeyes = options.fetch(:assumeyes, false)
  @whitelist = options.fetch(:whitelist, [])
  @force = options.fetch(:force, false)
  @rescue_scenario = options.fetch(:rescue_scenario, nil)
  @reporter = reporter
  @scenarios = Array(scenarios)
  @quit = false
  @rescue = false
  @last_scenario = nil
  @last_scenario_continuation_confirmed = false
  @exit_code = 0
  @procedure_step_counter = 0
end

Public Instance Methods

add_steps(*steps) click to toggle source
# File lib/foreman_maintain/runner.rb, line 96
def add_steps(*steps)
  # we we add the steps at the beginning, but still keeping the
  # order of steps passed in the arguments
  steps.reverse_each do |step|
    @steps_to_run.unshift(step)
  end
end
ask_to_quit(exit_code = 1) click to toggle source
# File lib/foreman_maintain/runner.rb, line 91
def ask_to_quit(exit_code = 1)
  @quit = true
  @exit_code = exit_code
end
assumeyes?() click to toggle source
# File lib/foreman_maintain/runner.rb, line 32
def assumeyes?
  @assumeyes
end
confirm_scenario(scenario) click to toggle source
# File lib/foreman_maintain/runner.rb, line 75
def confirm_scenario(scenario)
  return if @last_scenario.nil? || @last_scenario_continuation_confirmed

  decision = if @last_scenario.steps_with_error(:whitelisted => false).any? ||
                @last_scenario.steps_with_abort(:whitelisted => false).any?
               :quit
             elsif @last_scenario.steps_with_warning(:whitelisted => false).any?
               @last_scenario_continuation_confirmed = true
               reporter.ask_decision("Continue with [#{scenario.description}]",
                 run_strategy: scenario.run_strategy)
             end

  ask_to_quit if [:quit, :no].include?(decision)
  decision
end
quit?() click to toggle source
# File lib/foreman_maintain/runner.rb, line 28
def quit?
  @quit
end
rescue?() click to toggle source
# File lib/foreman_maintain/runner.rb, line 36
def rescue?
  @rescue
end
run() click to toggle source
# File lib/foreman_maintain/runner.rb, line 40
def run
  @scenarios.each do |scenario|
    run_scenario(scenario)
    next unless @quit

    if @rescue_scenario
      @rescue = true
      logger.debug('=== Rescue scenario found. Executing ===')
      execute_scenario_steps(@rescue_scenario, true)
    end
    break
  end
end
run_scenario(scenario) click to toggle source
# File lib/foreman_maintain/runner.rb, line 54
def run_scenario(scenario)
  return if scenario.steps.empty?
  raise 'The runner is already in quit state' if quit? && !rescue?

  confirm_scenario(scenario)
  return if quit? && !rescue?

  execute_scenario_steps(scenario)
ensure
  unless scenario.steps.empty?
    @last_scenario = scenario
    @last_scenario_continuation_confirmed = false
  end
  @exit_code = WARNING_EXIT_CODE if scenario.warning?
  @exit_code = FAILURE_EXIT_CODE if scenario.failed?
end
storage() click to toggle source
# File lib/foreman_maintain/runner.rb, line 104
def storage
  ForemanMaintain.storage(:default)
end
whitelisted_step?(step) click to toggle source
# File lib/foreman_maintain/runner.rb, line 71
def whitelisted_step?(step)
  @whitelist.include?(step.label_dashed.to_s)
end

Private Instance Methods

ask_about_offered_steps(step, scenario) click to toggle source

rubocop:disable Metrics/MethodLength

# File lib/foreman_maintain/runner.rb, line 155
def ask_about_offered_steps(step, scenario)
  if step.next_steps && !step.next_steps.empty?
    @last_decision_step = step
    @procedure_step_counter += 1
    steps = step.next_steps.map(&:ensure_instance)
    if assumeyes? && @procedure_step_counter > steps.length
      @procedure_step_counter = 0
      @reporter.select_option_counter = 0
      @reporter.puts 'Check still failing after attempt to fix. Skipping'
      return :no
    end
    decision = @reporter.on_next_steps(steps, scenario.run_strategy)
    case decision
    when :quit
      ask_to_quit
    when Executable
      chosen_steps = [decision]
      chosen_steps << step if step.is_a?(Check)
      add_steps(*chosen_steps)
      :yes
    end
  end
end
execute_scenario_steps(scenario, force = false) click to toggle source
# File lib/foreman_maintain/runner.rb, line 110
def execute_scenario_steps(scenario, force = false)
  scenario.before_scenarios.flatten.each { |before_scenario| run_scenario(before_scenario) }
  confirm_scenario(scenario)
  return if !force && quit? # the before scenarios caused the stop of the execution

  @reporter.before_scenario_starts(scenario)
  run_steps(scenario, scenario.steps)
  @reporter.after_scenario_finishes(scenario)
end
post_step_decisions(scenario, execution) click to toggle source
# File lib/foreman_maintain/runner.rb, line 140
def post_step_decisions(scenario, execution)
  step = execution.step
  if execution.aborted?
    ask_to_quit
  else
    next_steps_decision = ask_about_offered_steps(step, scenario)
    if next_steps_decision != :yes &&
       execution.fail? && !execution.whitelisted? &&
       scenario.run_strategy == :fail_fast
      ask_to_quit
    end
  end
end
rerun_check?(step) click to toggle source

rubocop:enable Metrics/MethodLength

# File lib/foreman_maintain/runner.rb, line 180
def rerun_check?(step)
  @last_decision_step == step
end
run_step(step) click to toggle source
# File lib/foreman_maintain/runner.rb, line 128
def run_step(step)
  @reporter.puts('Rerunning the check after fix procedure') if rerun_check?(step)
  execution = Execution.new(step, @reporter,
    :whitelisted => whitelisted_step?(step),
    :storage => storage,
    :force => @force)
  execution.run
  execution
ensure
  storage.save
end
run_steps(scenario, steps) click to toggle source
# File lib/foreman_maintain/runner.rb, line 120
def run_steps(scenario, steps)
  @steps_to_run = ForemanMaintain::DependencyGraph.sort(steps)
  while (scenario.run_strategy == :fail_slow || !@quit) && !@steps_to_run.empty?
    execution = run_step(@steps_to_run.shift)
    post_step_decisions(scenario, execution) unless execution.success?
  end
end