foreman_maintain 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/README.md +107 -25
 - data/bin/foreman-maintain +1 -0
 - data/definitions/checks/disk_speed_minimal.rb +31 -19
 - data/definitions/checks/foreman_tasks/invalid/check_old.rb +20 -0
 - data/definitions/checks/foreman_tasks/invalid/check_pending_state.rb +20 -0
 - data/definitions/checks/foreman_tasks/invalid/check_planning_state.rb +20 -0
 - data/definitions/checks/foreman_tasks/not_paused.rb +29 -0
 - data/definitions/checks/foreman_tasks/not_running.rb +14 -0
 - data/definitions/checks/sync_plans/with_disabled_status.rb +18 -0
 - data/definitions/checks/sync_plans/with_enabled_status.rb +18 -0
 - data/definitions/checks/system_registration.rb +31 -0
 - data/definitions/features/downstream.rb +5 -3
 - data/definitions/features/foreman_1_11_x.rb +4 -2
 - data/definitions/features/foreman_1_7_x.rb +5 -3
 - data/definitions/features/foreman_database.rb +11 -5
 - data/definitions/features/foreman_tasks.rb +118 -9
 - data/definitions/features/sync_plans.rb +75 -0
 - data/definitions/features/upstream.rb +5 -3
 - data/definitions/procedures/foreman_tasks/delete.rb +33 -0
 - data/definitions/procedures/foreman_tasks/resume.rb +14 -0
 - data/definitions/procedures/foreman_tasks/ui_investigate.rb +19 -0
 - data/definitions/procedures/hammer_setup.rb +50 -0
 - data/definitions/procedures/install_package.rb +17 -0
 - data/definitions/procedures/sync_plans/disable.rb +22 -0
 - data/definitions/procedures/sync_plans/enable.rb +21 -0
 - data/definitions/scenarios/pre_upgrade_check_foreman_1_14.rb +7 -6
 - data/definitions/scenarios/pre_upgrade_check_satellite_6_0_z.rb +8 -6
 - data/definitions/scenarios/pre_upgrade_check_satellite_6_1.rb +8 -6
 - data/definitions/scenarios/pre_upgrade_check_satellite_6_1_z.rb +8 -6
 - data/definitions/scenarios/pre_upgrade_check_satellite_6_2.rb +8 -6
 - data/definitions/scenarios/pre_upgrade_check_satellite_6_2_z.rb +8 -6
 - data/definitions/scenarios/pre_upgrade_check_satellite_6_3.rb +8 -6
 - data/lib/foreman_maintain.rb +52 -5
 - data/lib/foreman_maintain/check.rb +18 -12
 - data/lib/foreman_maintain/cli/base.rb +9 -2
 - data/lib/foreman_maintain/cli/health_command.rb +2 -1
 - data/lib/foreman_maintain/cli/upgrade_command.rb +2 -0
 - data/lib/foreman_maintain/concerns/hammer.rb +20 -0
 - data/lib/foreman_maintain/concerns/logger.rb +1 -5
 - data/lib/foreman_maintain/concerns/metadata.rb +138 -31
 - data/lib/foreman_maintain/concerns/system_helpers.rb +36 -32
 - data/lib/foreman_maintain/config.rb +40 -5
 - data/lib/foreman_maintain/core_ext.rb +24 -0
 - data/lib/foreman_maintain/detector.rb +12 -13
 - data/lib/foreman_maintain/error.rb +28 -0
 - data/lib/foreman_maintain/executable.rb +86 -11
 - data/lib/foreman_maintain/feature.rb +1 -0
 - data/lib/foreman_maintain/param.rb +47 -0
 - data/lib/foreman_maintain/reporter.rb +20 -3
 - data/lib/foreman_maintain/reporter/cli_reporter.rb +166 -66
 - data/lib/foreman_maintain/runner.rb +56 -13
 - data/lib/foreman_maintain/runner/execution.rb +8 -0
 - data/lib/foreman_maintain/scenario.rb +46 -2
 - data/lib/foreman_maintain/top_level_modules.rb +3 -0
 - data/lib/foreman_maintain/utils.rb +2 -0
 - data/lib/foreman_maintain/utils/command_runner.rb +101 -0
 - data/lib/foreman_maintain/utils/disk/device.rb +5 -9
 - data/lib/foreman_maintain/utils/hammer.rb +78 -0
 - data/lib/foreman_maintain/version.rb +1 -1
 - data/lib/foreman_maintain/yaml_storage.rb +48 -0
 - metadata +27 -9
 - data/definitions/checks/foreman_tasks_not_paused.rb +0 -14
 - data/definitions/checks/foreman_tasks_not_running.rb +0 -10
 - data/definitions/procedures/foreman_tasks_resume.rb +0 -13
 - data/lib/foreman_maintain/logger.rb +0 -11
 
| 
         @@ -3,6 +3,8 @@ module ForemanMaintain 
     | 
|
| 
       3 
3 
     | 
    
         
             
                # Class representing an execution of a single step in scenario
         
     | 
| 
       4 
4 
     | 
    
         
             
                class Execution
         
     | 
| 
       5 
5 
     | 
    
         
             
                  include Concerns::Logger
         
     | 
| 
      
 6 
     | 
    
         
            +
                  extend Forwardable
         
     | 
| 
      
 7 
     | 
    
         
            +
                  def_delegators :@reporter, :with_spinner, :puts, :print, :ask, :assumeyes?
         
     | 
| 
       6 
8 
     | 
    
         | 
| 
       7 
9 
     | 
    
         
             
                  # Step performed as part of the execution
         
     | 
| 
       8 
10 
     | 
    
         
             
                  attr_reader :step
         
     | 
| 
         @@ -16,6 +18,8 @@ module ForemanMaintain 
     | 
|
| 
       16 
18 
     | 
    
         
             
                  # Output of the execution, to be filled by execution step
         
     | 
| 
       17 
19 
     | 
    
         
             
                  attr_accessor :output
         
     | 
| 
       18 
20 
     | 
    
         | 
| 
      
 21 
     | 
    
         
            +
                  attr_reader :reporter
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
       19 
23 
     | 
    
         
             
                  def initialize(step, reporter)
         
     | 
| 
       20 
24 
     | 
    
         
             
                    @step = step
         
     | 
| 
       21 
25 
     | 
    
         
             
                    @reporter = reporter
         
     | 
| 
         @@ -35,6 +39,10 @@ module ForemanMaintain 
     | 
|
| 
       35 
39 
     | 
    
         
             
                    @status == :fail
         
     | 
| 
       36 
40 
     | 
    
         
             
                  end
         
     | 
| 
       37 
41 
     | 
    
         | 
| 
      
 42 
     | 
    
         
            +
                  def warning?
         
     | 
| 
      
 43 
     | 
    
         
            +
                    @status == :warning
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
       38 
46 
     | 
    
         
             
                  def run
         
     | 
| 
       39 
47 
     | 
    
         
             
                    @status = :running
         
     | 
| 
       40 
48 
     | 
    
         
             
                    @reporter.before_execution_starts(self)
         
     | 
| 
         @@ -8,13 +8,14 @@ module ForemanMaintain 
     | 
|
| 
       8 
8 
     | 
    
         
             
                attr_reader :steps
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
                class FilteredScenario < Scenario
         
     | 
| 
       11 
     | 
    
         
            -
                  manual_detection
         
     | 
| 
      
 11 
     | 
    
         
            +
                  metadata { manual_detection }
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
       12 
13 
     | 
    
         
             
                  attr_reader :filter_label, :filter_tags
         
     | 
| 
       13 
14 
     | 
    
         | 
| 
       14 
15 
     | 
    
         
             
                  def initialize(filter)
         
     | 
| 
       15 
16 
     | 
    
         
             
                    @filter_tags = filter[:tags]
         
     | 
| 
       16 
17 
     | 
    
         
             
                    @filter_label = filter[:label]
         
     | 
| 
       17 
     | 
    
         
            -
                    @steps = ForemanMaintain.available_checks(filter)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    @steps = ForemanMaintain.available_checks(filter).map(&:ensure_instance)
         
     | 
| 
       18 
19 
     | 
    
         
             
                  end
         
     | 
| 
       19 
20 
     | 
    
         | 
| 
       20 
21 
     | 
    
         
             
                  def description
         
     | 
| 
         @@ -36,6 +37,23 @@ module ForemanMaintain 
     | 
|
| 
       36 
37 
     | 
    
         
             
                  end
         
     | 
| 
       37 
38 
     | 
    
         
             
                end
         
     | 
| 
       38 
39 
     | 
    
         | 
| 
      
 40 
     | 
    
         
            +
                class PreparationScenario < Scenario
         
     | 
| 
      
 41 
     | 
    
         
            +
                  metadata do
         
     | 
| 
      
 42 
     | 
    
         
            +
                    manual_detection
         
     | 
| 
      
 43 
     | 
    
         
            +
                    description 'preparation steps required to run the next scenarios'
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  attr_reader :main_scenario
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                  def initialize(main_scenario)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    @main_scenario = main_scenario
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                  def steps
         
     | 
| 
      
 53 
     | 
    
         
            +
                    @steps ||= main_scenario.preparation_steps.find_all(&:necessary?)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
       39 
57 
     | 
    
         
             
                def initialize
         
     | 
| 
       40 
58 
     | 
    
         
             
                  @steps = []
         
     | 
| 
       41 
59 
     | 
    
         
             
                  compose
         
     | 
| 
         @@ -44,6 +62,32 @@ module ForemanMaintain 
     | 
|
| 
       44 
62 
     | 
    
         
             
                # Override to compose steps for the scenario
         
     | 
| 
       45 
63 
     | 
    
         
             
                def compose; end
         
     | 
| 
       46 
64 
     | 
    
         | 
| 
      
 65 
     | 
    
         
            +
                def preparation_steps
         
     | 
| 
      
 66 
     | 
    
         
            +
                  # we first take the preparation steps defined for the scenario + collect
         
     | 
| 
      
 67 
     | 
    
         
            +
                  # preparation steps for the steps inside the scenario
         
     | 
| 
      
 68 
     | 
    
         
            +
                  steps.inject(super.dup) do |results, step|
         
     | 
| 
      
 69 
     | 
    
         
            +
                    results.concat(step.preparation_steps)
         
     | 
| 
      
 70 
     | 
    
         
            +
                  end.uniq
         
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                # scenarios to be run before this scenario
         
     | 
| 
      
 74 
     | 
    
         
            +
                def before_scenarios
         
     | 
| 
      
 75 
     | 
    
         
            +
                  scenarios = []
         
     | 
| 
      
 76 
     | 
    
         
            +
                  preparation_scenario = PreparationScenario.new(self)
         
     | 
| 
      
 77 
     | 
    
         
            +
                  scenarios << [preparation_scenario] unless preparation_scenario.steps.empty?
         
     | 
| 
      
 78 
     | 
    
         
            +
                  scenarios
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                def add_steps(steps)
         
     | 
| 
      
 82 
     | 
    
         
            +
                  steps.each do |step|
         
     | 
| 
      
 83 
     | 
    
         
            +
                    self.steps << step.ensure_instance
         
     | 
| 
      
 84 
     | 
    
         
            +
                  end
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                def add_step(step)
         
     | 
| 
      
 88 
     | 
    
         
            +
                  add_steps([step])
         
     | 
| 
      
 89 
     | 
    
         
            +
                end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
       47 
91 
     | 
    
         
             
                def self.inspect
         
     | 
| 
       48 
92 
     | 
    
         
             
                  "Scenario Class #{metadata[:description]}<#{name}>"
         
     | 
| 
       49 
93 
     | 
    
         
             
                end
         
     | 
| 
         @@ -0,0 +1,101 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'English'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'tempfile'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module ForemanMaintain
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Utils
         
     | 
| 
      
 6 
     | 
    
         
            +
                # Wrapper around running a command
         
     | 
| 
      
 7 
     | 
    
         
            +
                class CommandRunner
         
     | 
| 
      
 8 
     | 
    
         
            +
                  attr_reader :logger, :command
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def initialize(logger, command, options)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    options.validate_options!(:stdin, :hidden_patterns, :interactive)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @logger = logger
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @command = command
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @stdin = options[:stdin]
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @hidden_patterns = Array(options[:hidden_patterns])
         
     | 
| 
      
 16 
     | 
    
         
            +
                    @interactive = options[:interactive]
         
     | 
| 
      
 17 
     | 
    
         
            +
                    @options = options
         
     | 
| 
      
 18 
     | 
    
         
            +
                    raise ArgumentError, 'Can not pass stdin for interactive command' if @interactive && @stdin
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  def run
         
     | 
| 
      
 22 
     | 
    
         
            +
                    logger.debug(hide_strings("Running command #{@command} with stdin #{@stdin.inspect}"))
         
     | 
| 
      
 23 
     | 
    
         
            +
                    if @interactive
         
     | 
| 
      
 24 
     | 
    
         
            +
                      run_interactively
         
     | 
| 
      
 25 
     | 
    
         
            +
                    else
         
     | 
| 
      
 26 
     | 
    
         
            +
                      run_non_interactively
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
                    logger.debug("output of the command:\n #{hide_strings(output)}")
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  def interactive?
         
     | 
| 
      
 32 
     | 
    
         
            +
                    @interactive
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  def output
         
     | 
| 
      
 36 
     | 
    
         
            +
                    raise 'Command not yet executed' unless defined? @output
         
     | 
| 
      
 37 
     | 
    
         
            +
                    @output
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  def exit_status
         
     | 
| 
      
 41 
     | 
    
         
            +
                    raise 'Command not yet executed' unless defined? @exit_status
         
     | 
| 
      
 42 
     | 
    
         
            +
                    @exit_status
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                  def success?
         
     | 
| 
      
 46 
     | 
    
         
            +
                    exit_status == 0
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  def execution_error
         
     | 
| 
      
 50 
     | 
    
         
            +
                    raise Error::ExecutionError.new(hide_strings(@command),
         
     | 
| 
      
 51 
     | 
    
         
            +
                                                    exit_status,
         
     | 
| 
      
 52 
     | 
    
         
            +
                                                    hide_strings(@stdin),
         
     | 
| 
      
 53 
     | 
    
         
            +
                                                    @interactive ? nil : hide_strings(@output))
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  private
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                  # rubocop:disable Metrics/AbcSize
         
     | 
| 
      
 59 
     | 
    
         
            +
                  def run_interactively
         
     | 
| 
      
 60 
     | 
    
         
            +
                    # use tmp files to capture output and exit status of the command when
         
     | 
| 
      
 61 
     | 
    
         
            +
                    # running interactively
         
     | 
| 
      
 62 
     | 
    
         
            +
                    log_file = Tempfile.open('captured-output')
         
     | 
| 
      
 63 
     | 
    
         
            +
                    exit_file = Tempfile.open('captured-exit-code')
         
     | 
| 
      
 64 
     | 
    
         
            +
                    Kernel.system("script -qc '#{full_command}; echo $? > #{exit_file.path}' #{log_file.path}")
         
     | 
| 
      
 65 
     | 
    
         
            +
                    File.open(log_file.path) { |f| @output = f.read }
         
     | 
| 
      
 66 
     | 
    
         
            +
                    File.open(exit_file.path) do |f|
         
     | 
| 
      
 67 
     | 
    
         
            +
                      exit_status = f.read.strip
         
     | 
| 
      
 68 
     | 
    
         
            +
                      @exit_status = if exit_status.empty?
         
     | 
| 
      
 69 
     | 
    
         
            +
                                       256
         
     | 
| 
      
 70 
     | 
    
         
            +
                                     else
         
     | 
| 
      
 71 
     | 
    
         
            +
                                       exit_status.to_i
         
     | 
| 
      
 72 
     | 
    
         
            +
                                     end
         
     | 
| 
      
 73 
     | 
    
         
            +
                    end
         
     | 
| 
      
 74 
     | 
    
         
            +
                  ensure
         
     | 
| 
      
 75 
     | 
    
         
            +
                    log_file.close
         
     | 
| 
      
 76 
     | 
    
         
            +
                    exit_file.close
         
     | 
| 
      
 77 
     | 
    
         
            +
                  end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                  def run_non_interactively
         
     | 
| 
      
 80 
     | 
    
         
            +
                    IO.popen(full_command, 'r+') do |f|
         
     | 
| 
      
 81 
     | 
    
         
            +
                      if @stdin
         
     | 
| 
      
 82 
     | 
    
         
            +
                        f.puts(@stdin)
         
     | 
| 
      
 83 
     | 
    
         
            +
                        f.close_write
         
     | 
| 
      
 84 
     | 
    
         
            +
                      end
         
     | 
| 
      
 85 
     | 
    
         
            +
                      @output = f.read.strip
         
     | 
| 
      
 86 
     | 
    
         
            +
                    end
         
     | 
| 
      
 87 
     | 
    
         
            +
                    @exit_status = $CHILD_STATUS.exitstatus
         
     | 
| 
      
 88 
     | 
    
         
            +
                  end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                  def full_command
         
     | 
| 
      
 91 
     | 
    
         
            +
                    "#{@command} 2>&1"
         
     | 
| 
      
 92 
     | 
    
         
            +
                  end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                  def hide_strings(string)
         
     | 
| 
      
 95 
     | 
    
         
            +
                    @hidden_patterns.reduce(string) do |result, hidden_pattern|
         
     | 
| 
      
 96 
     | 
    
         
            +
                      result.gsub(hidden_pattern, '[FILTERED]')
         
     | 
| 
      
 97 
     | 
    
         
            +
                    end
         
     | 
| 
      
 98 
     | 
    
         
            +
                  end
         
     | 
| 
      
 99 
     | 
    
         
            +
                end
         
     | 
| 
      
 100 
     | 
    
         
            +
              end
         
     | 
| 
      
 101 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -2,28 +2,24 @@ module ForemanMaintain 
     | 
|
| 
       2 
2 
     | 
    
         
             
              module Utils
         
     | 
| 
       3 
3 
     | 
    
         
             
                module Disk
         
     | 
| 
       4 
4 
     | 
    
         
             
                  class Device
         
     | 
| 
      
 5 
     | 
    
         
            +
                    extend Forwardable
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
       5 
7 
     | 
    
         
             
                    include ForemanMaintain::Concerns::SystemHelpers
         
     | 
| 
       6 
8 
     | 
    
         | 
| 
       7 
     | 
    
         
            -
                    EXTERNAL_MOUNT_TYPE = %w 
     | 
| 
      
 9 
     | 
    
         
            +
                    EXTERNAL_MOUNT_TYPE = %w[fuseblk nfs].freeze
         
     | 
| 
       8 
10 
     | 
    
         | 
| 
       9 
11 
     | 
    
         
             
                    attr_accessor :dir, :name, :unit, :read_speed
         
     | 
| 
       10 
12 
     | 
    
         | 
| 
       11 
13 
     | 
    
         
             
                    attr_reader :io_device
         
     | 
| 
       12 
14 
     | 
    
         | 
| 
      
 15 
     | 
    
         
            +
                    def_delegators :io_device, :unit, :read_speed
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
       13 
17 
     | 
    
         
             
                    def initialize(dir)
         
     | 
| 
       14 
18 
     | 
    
         
             
                      @dir = dir
         
     | 
| 
       15 
19 
     | 
    
         
             
                      @name = find_device
         
     | 
| 
       16 
20 
     | 
    
         
             
                      @io_device = init_io_device
         
     | 
| 
       17 
21 
     | 
    
         
             
                    end
         
     | 
| 
       18 
22 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
                    def unit
         
     | 
| 
       20 
     | 
    
         
            -
                      @unit ||= io_device.unit
         
     | 
| 
       21 
     | 
    
         
            -
                    end
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                    def read_speed
         
     | 
| 
       24 
     | 
    
         
            -
                      @read_speed ||= io_device.read_speed
         
     | 
| 
       25 
     | 
    
         
            -
                    end
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
23 
     | 
    
         
             
                    def slow_disk_error_msg
         
     | 
| 
       28 
24 
     | 
    
         
             
                      "Slow disk detected #{dir} mounted on #{name}.
         
     | 
| 
       29 
25 
     | 
    
         
             
                         Actual disk speed: #{read_speed} #{default_unit}
         
     | 
| 
         @@ -0,0 +1,78 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module ForemanMaintain
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Utils
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Hammer
         
     | 
| 
      
 4 
     | 
    
         
            +
                  class CredentialsError < RuntimeError
         
     | 
| 
      
 5 
     | 
    
         
            +
                  end
         
     | 
| 
      
 6 
     | 
    
         
            +
                  include Concerns::SystemHelpers
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  attr_reader :settings
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def self.instance
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @instance ||= new
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def config_file
         
     | 
| 
      
 15 
     | 
    
         
            +
                    config_dir = File.dirname(ForemanMaintain.config_file)
         
     | 
| 
      
 16 
     | 
    
         
            +
                    File.join(config_dir, 'foreman-maintain-hammer.yml')
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  # tries to setup hammer based on default configuration and returns true
         
     | 
| 
      
 20 
     | 
    
         
            +
                  # if it succeeds
         
     | 
| 
      
 21 
     | 
    
         
            +
                  # rubocop:disable Metrics/AbcSize
         
     | 
| 
      
 22 
     | 
    
         
            +
                  def setup_from_default
         
     | 
| 
      
 23 
     | 
    
         
            +
                    return unless File.exist?(default_config_file)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    hammer_config = YAML.load_file(default_config_file)
         
     | 
| 
      
 25 
     | 
    
         
            +
                    foreman_config = hammer_config.fetch(:foreman, {})
         
     | 
| 
      
 26 
     | 
    
         
            +
                    if !foreman_config[:username].to_s.empty? && !foreman_config[:password].to_s.empty?
         
     | 
| 
      
 27 
     | 
    
         
            +
                      save_config(hammer_config)
         
     | 
| 
      
 28 
     | 
    
         
            +
                      ready? && default_config_file
         
     | 
| 
      
 29 
     | 
    
         
            +
                    end
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  def setup_from_answers(username = nil, password = nil)
         
     | 
| 
      
 33 
     | 
    
         
            +
                    save_config(:foreman => { :username => username, :password => password })
         
     | 
| 
      
 34 
     | 
    
         
            +
                    ready?
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  # Run a hammer command, examples:
         
     | 
| 
      
 38 
     | 
    
         
            +
                  # run_command('host list')
         
     | 
| 
      
 39 
     | 
    
         
            +
                  def run_command(args)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    output = execute("#{command_base} #{args}")
         
     | 
| 
      
 41 
     | 
    
         
            +
                    if output =~ /Invalid username or password/
         
     | 
| 
      
 42 
     | 
    
         
            +
                      raise CredentialsError, 'Invalid hammer credentials: '\
         
     | 
| 
      
 43 
     | 
    
         
            +
                        'we expect the hammer username/password to be stored'\
         
     | 
| 
      
 44 
     | 
    
         
            +
                        "in #{config_file}"
         
     | 
| 
      
 45 
     | 
    
         
            +
                    end
         
     | 
| 
      
 46 
     | 
    
         
            +
                    output
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  def configured?
         
     | 
| 
      
 50 
     | 
    
         
            +
                    File.exist?(config_file)
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  def ready?
         
     | 
| 
      
 54 
     | 
    
         
            +
                    return @ready if defined? @ready
         
     | 
| 
      
 55 
     | 
    
         
            +
                    return false unless configured?
         
     | 
| 
      
 56 
     | 
    
         
            +
                    run_command('architecture list')
         
     | 
| 
      
 57 
     | 
    
         
            +
                    @ready = true
         
     | 
| 
      
 58 
     | 
    
         
            +
                  rescue CredentialsError
         
     | 
| 
      
 59 
     | 
    
         
            +
                    @ready = false
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                  private
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                  def default_config_file
         
     | 
| 
      
 65 
     | 
    
         
            +
                    @default_config_file ||= File.expand_path('~/.hammer/cli.modules.d/foreman.yml')
         
     | 
| 
      
 66 
     | 
    
         
            +
                  end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                  def command_base
         
     | 
| 
      
 69 
     | 
    
         
            +
                    %(LANG=en_US.utf-8 hammer -c "#{config_file}" --interactive=no)
         
     | 
| 
      
 70 
     | 
    
         
            +
                  end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                  def save_config(config)
         
     | 
| 
      
 73 
     | 
    
         
            +
                    remove_instance_variable '@ready' if defined? @ready
         
     | 
| 
      
 74 
     | 
    
         
            +
                    File.open(config_file, 'w', 0o600) { |f| f.puts YAML.dump(config) }
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
              end
         
     | 
| 
      
 78 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,48 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module ForemanMaintain
         
     | 
| 
      
 2 
     | 
    
         
            +
              class YamlStorage
         
     | 
| 
      
 3 
     | 
    
         
            +
                extend Forwardable
         
     | 
| 
      
 4 
     | 
    
         
            +
                attr_reader :sub_key, :data
         
     | 
| 
      
 5 
     | 
    
         
            +
                def_delegators :data, :[], :[]=
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def initialize(sub_key, data = {})
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @sub_key = sub_key
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @data = data
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def save
         
     | 
| 
      
 13 
     | 
    
         
            +
                  self.class.save_sub_key(sub_key, data)
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 17 
     | 
    
         
            +
                  def load_file
         
     | 
| 
      
 18 
     | 
    
         
            +
                    if File.exist?(storage_file_path)
         
     | 
| 
      
 19 
     | 
    
         
            +
                      YAML.load_file(storage_file_path) || {}
         
     | 
| 
      
 20 
     | 
    
         
            +
                    else
         
     | 
| 
      
 21 
     | 
    
         
            +
                      {}
         
     | 
| 
      
 22 
     | 
    
         
            +
                    end
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  def storage_file_path
         
     | 
| 
      
 26 
     | 
    
         
            +
                    File.expand_path(ForemanMaintain.config.storage_file)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  def storage_register
         
     | 
| 
      
 30 
     | 
    
         
            +
                    @storage_register ||= {}
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  def load(sub_key)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    storage_register[sub_key] ||= load_file.fetch(sub_key, {})
         
     | 
| 
      
 35 
     | 
    
         
            +
                    YamlStorage.new(sub_key, storage_register[sub_key])
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  def save_sub_key(sub_key, data_val)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    new_data = load_file.merge(sub_key => data_val)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    File.open(storage_file_path, 'w') { |f| f.write new_data.to_yaml }
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                  def save_all
         
     | 
| 
      
 44 
     | 
    
         
            +
                    storage_register.values.each(&:save)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: foreman_maintain
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0.0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.0.3
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Ivan Nečas
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2017- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2017-05-16 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: clamp
         
     | 
| 
         @@ -94,9 +94,8 @@ dependencies: 
     | 
|
| 
       94 
94 
     | 
    
         
             
                - - ">="
         
     | 
| 
       95 
95 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       96 
96 
     | 
    
         
             
                    version: '0'
         
     | 
| 
       97 
     | 
    
         
            -
            description:  
     | 
| 
       98 
     | 
    
         
            -
               
     | 
| 
       99 
     | 
    
         
            -
              running.
         
     | 
| 
      
 97 
     | 
    
         
            +
            description: Provides various features that helps keeping the Foreman/Satellite up
         
     | 
| 
      
 98 
     | 
    
         
            +
              and running.
         
     | 
| 
       100 
99 
     | 
    
         
             
            email: inecas@redhat.com
         
     | 
| 
       101 
100 
     | 
    
         
             
            executables:
         
     | 
| 
       102 
101 
     | 
    
         
             
            - foreman-maintain
         
     | 
| 
         @@ -109,15 +108,28 @@ files: 
     | 
|
| 
       109 
108 
     | 
    
         
             
            - README.md
         
     | 
| 
       110 
109 
     | 
    
         
             
            - bin/foreman-maintain
         
     | 
| 
       111 
110 
     | 
    
         
             
            - definitions/checks/disk_speed_minimal.rb
         
     | 
| 
       112 
     | 
    
         
            -
            - definitions/checks/ 
     | 
| 
       113 
     | 
    
         
            -
            - definitions/checks/ 
     | 
| 
      
 111 
     | 
    
         
            +
            - definitions/checks/foreman_tasks/invalid/check_old.rb
         
     | 
| 
      
 112 
     | 
    
         
            +
            - definitions/checks/foreman_tasks/invalid/check_pending_state.rb
         
     | 
| 
      
 113 
     | 
    
         
            +
            - definitions/checks/foreman_tasks/invalid/check_planning_state.rb
         
     | 
| 
      
 114 
     | 
    
         
            +
            - definitions/checks/foreman_tasks/not_paused.rb
         
     | 
| 
      
 115 
     | 
    
         
            +
            - definitions/checks/foreman_tasks/not_running.rb
         
     | 
| 
      
 116 
     | 
    
         
            +
            - definitions/checks/sync_plans/with_disabled_status.rb
         
     | 
| 
      
 117 
     | 
    
         
            +
            - definitions/checks/sync_plans/with_enabled_status.rb
         
     | 
| 
      
 118 
     | 
    
         
            +
            - definitions/checks/system_registration.rb
         
     | 
| 
       114 
119 
     | 
    
         
             
            - definitions/features/downstream.rb
         
     | 
| 
       115 
120 
     | 
    
         
             
            - definitions/features/foreman_1_11_x.rb
         
     | 
| 
       116 
121 
     | 
    
         
             
            - definitions/features/foreman_1_7_x.rb
         
     | 
| 
       117 
122 
     | 
    
         
             
            - definitions/features/foreman_database.rb
         
     | 
| 
       118 
123 
     | 
    
         
             
            - definitions/features/foreman_tasks.rb
         
     | 
| 
      
 124 
     | 
    
         
            +
            - definitions/features/sync_plans.rb
         
     | 
| 
       119 
125 
     | 
    
         
             
            - definitions/features/upstream.rb
         
     | 
| 
       120 
     | 
    
         
            -
            - definitions/procedures/ 
     | 
| 
      
 126 
     | 
    
         
            +
            - definitions/procedures/foreman_tasks/delete.rb
         
     | 
| 
      
 127 
     | 
    
         
            +
            - definitions/procedures/foreman_tasks/resume.rb
         
     | 
| 
      
 128 
     | 
    
         
            +
            - definitions/procedures/foreman_tasks/ui_investigate.rb
         
     | 
| 
      
 129 
     | 
    
         
            +
            - definitions/procedures/hammer_setup.rb
         
     | 
| 
      
 130 
     | 
    
         
            +
            - definitions/procedures/install_package.rb
         
     | 
| 
      
 131 
     | 
    
         
            +
            - definitions/procedures/sync_plans/disable.rb
         
     | 
| 
      
 132 
     | 
    
         
            +
            - definitions/procedures/sync_plans/enable.rb
         
     | 
| 
       121 
133 
     | 
    
         
             
            - definitions/scenarios/pre_upgrade_check_foreman_1_14.rb
         
     | 
| 
       122 
134 
     | 
    
         
             
            - definitions/scenarios/pre_upgrade_check_satellite_6_0_z.rb
         
     | 
| 
       123 
135 
     | 
    
         
             
            - definitions/scenarios/pre_upgrade_check_satellite_6_1.rb
         
     | 
| 
         @@ -132,14 +144,17 @@ files: 
     | 
|
| 
       132 
144 
     | 
    
         
             
            - lib/foreman_maintain/cli/health_command.rb
         
     | 
| 
       133 
145 
     | 
    
         
             
            - lib/foreman_maintain/cli/upgrade_command.rb
         
     | 
| 
       134 
146 
     | 
    
         
             
            - lib/foreman_maintain/concerns/finders.rb
         
     | 
| 
      
 147 
     | 
    
         
            +
            - lib/foreman_maintain/concerns/hammer.rb
         
     | 
| 
       135 
148 
     | 
    
         
             
            - lib/foreman_maintain/concerns/logger.rb
         
     | 
| 
       136 
149 
     | 
    
         
             
            - lib/foreman_maintain/concerns/metadata.rb
         
     | 
| 
       137 
150 
     | 
    
         
             
            - lib/foreman_maintain/concerns/system_helpers.rb
         
     | 
| 
       138 
151 
     | 
    
         
             
            - lib/foreman_maintain/config.rb
         
     | 
| 
      
 152 
     | 
    
         
            +
            - lib/foreman_maintain/core_ext.rb
         
     | 
| 
       139 
153 
     | 
    
         
             
            - lib/foreman_maintain/detector.rb
         
     | 
| 
      
 154 
     | 
    
         
            +
            - lib/foreman_maintain/error.rb
         
     | 
| 
       140 
155 
     | 
    
         
             
            - lib/foreman_maintain/executable.rb
         
     | 
| 
       141 
156 
     | 
    
         
             
            - lib/foreman_maintain/feature.rb
         
     | 
| 
       142 
     | 
    
         
            -
            - lib/foreman_maintain/ 
     | 
| 
      
 157 
     | 
    
         
            +
            - lib/foreman_maintain/param.rb
         
     | 
| 
       143 
158 
     | 
    
         
             
            - lib/foreman_maintain/procedure.rb
         
     | 
| 
       144 
159 
     | 
    
         
             
            - lib/foreman_maintain/reporter.rb
         
     | 
| 
       145 
160 
     | 
    
         
             
            - lib/foreman_maintain/reporter/cli_reporter.rb
         
     | 
| 
         @@ -148,13 +163,16 @@ files: 
     | 
|
| 
       148 
163 
     | 
    
         
             
            - lib/foreman_maintain/scenario.rb
         
     | 
| 
       149 
164 
     | 
    
         
             
            - lib/foreman_maintain/top_level_modules.rb
         
     | 
| 
       150 
165 
     | 
    
         
             
            - lib/foreman_maintain/utils.rb
         
     | 
| 
      
 166 
     | 
    
         
            +
            - lib/foreman_maintain/utils/command_runner.rb
         
     | 
| 
       151 
167 
     | 
    
         
             
            - lib/foreman_maintain/utils/disk.rb
         
     | 
| 
       152 
168 
     | 
    
         
             
            - lib/foreman_maintain/utils/disk/device.rb
         
     | 
| 
       153 
169 
     | 
    
         
             
            - lib/foreman_maintain/utils/disk/io.rb
         
     | 
| 
       154 
170 
     | 
    
         
             
            - lib/foreman_maintain/utils/disk/io/block_device.rb
         
     | 
| 
       155 
171 
     | 
    
         
             
            - lib/foreman_maintain/utils/disk/io/file_system.rb
         
     | 
| 
       156 
172 
     | 
    
         
             
            - lib/foreman_maintain/utils/disk/nil_device.rb
         
     | 
| 
      
 173 
     | 
    
         
            +
            - lib/foreman_maintain/utils/hammer.rb
         
     | 
| 
       157 
174 
     | 
    
         
             
            - lib/foreman_maintain/version.rb
         
     | 
| 
      
 175 
     | 
    
         
            +
            - lib/foreman_maintain/yaml_storage.rb
         
     | 
| 
       158 
176 
     | 
    
         
             
            homepage: https://github.com/theforeman/foreman_maintain
         
     | 
| 
       159 
177 
     | 
    
         
             
            licenses:
         
     | 
| 
       160 
178 
     | 
    
         
             
            - GPL-3.0
         
     |