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
 
| 
         @@ -1,15 +1,21 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            class Features::ForemanDatabase < ForemanMaintain::Feature
         
     | 
| 
       2 
     | 
    
         
            -
               
     | 
| 
      
 2 
     | 
    
         
            +
              metadata do
         
     | 
| 
      
 3 
     | 
    
         
            +
                label :foreman_database
         
     | 
| 
       3 
4 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
      
 5 
     | 
    
         
            +
                confine do
         
     | 
| 
      
 6 
     | 
    
         
            +
                  File.exist?('/etc/foreman/database.yml')
         
     | 
| 
      
 7 
     | 
    
         
            +
                end
         
     | 
| 
       6 
8 
     | 
    
         
             
              end
         
     | 
| 
       7 
9 
     | 
    
         | 
| 
       8 
10 
     | 
    
         
             
              def query(sql)
         
     | 
| 
       9 
     | 
    
         
            -
                parse_csv( 
     | 
| 
      
 11 
     | 
    
         
            +
                parse_csv(query_csv(sql))
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              def query_csv(sql)
         
     | 
| 
      
 15 
     | 
    
         
            +
                psql(%{COPY (#{sql}) TO STDOUT WITH CSV HEADER})
         
     | 
| 
       10 
16 
     | 
    
         
             
              end
         
     | 
| 
       11 
17 
     | 
    
         | 
| 
       12 
18 
     | 
    
         
             
              def psql(query)
         
     | 
| 
       13 
     | 
    
         
            -
                execute("su - postgres -c 'psql -d foreman'", query)
         
     | 
| 
      
 19 
     | 
    
         
            +
                execute("su - postgres -c 'psql -d foreman'", :stdin => query)
         
     | 
| 
       14 
20 
     | 
    
         
             
              end
         
     | 
| 
       15 
21 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,9 +1,35 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            class Features::ForemanTasks < ForemanMaintain::Feature
         
     | 
| 
       2 
     | 
    
         
            -
               
     | 
| 
      
 2 
     | 
    
         
            +
              MIN_AGE = 30
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
               
     | 
| 
       5 
     | 
    
         
            -
                 
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
      
 4 
     | 
    
         
            +
              SAFE_TO_DELETE = %w[
         
     | 
| 
      
 5 
     | 
    
         
            +
                Actions::Katello::Host::GenerateApplicability
         
     | 
| 
      
 6 
     | 
    
         
            +
                Actions::Katello::RepositorySet::ScanCdn
         
     | 
| 
      
 7 
     | 
    
         
            +
                Actions::Katello::Host::Hypervisors
         
     | 
| 
      
 8 
     | 
    
         
            +
                Actions::Katello::Host::HypervisorsUpdate
         
     | 
| 
      
 9 
     | 
    
         
            +
                Actions::Foreman::Host::ImportFacts
         
     | 
| 
      
 10 
     | 
    
         
            +
                Actions::Candlepin::ListenOnCandlepinEvents
         
     | 
| 
      
 11 
     | 
    
         
            +
                Actions::Katello::EventQueue::Monitor
         
     | 
| 
      
 12 
     | 
    
         
            +
              ].freeze
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              metadata do
         
     | 
| 
      
 15 
     | 
    
         
            +
                label :foreman_tasks
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                confine do
         
     | 
| 
      
 18 
     | 
    
         
            +
                  check_min_version('ruby193-rubygem-foreman-tasks', '0.6') ||
         
     | 
| 
      
 19 
     | 
    
         
            +
                    check_min_version('tfm-rubygem-foreman-tasks', '0.7')
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              def backup_tasks(state)
         
     | 
| 
      
 24 
     | 
    
         
            +
                backup_table('dynflow_execution_plans', state, 'uuid') { |status| yield(status) }
         
     | 
| 
      
 25 
     | 
    
         
            +
                backup_table('dynflow_steps', state) { |status| yield(status) }
         
     | 
| 
      
 26 
     | 
    
         
            +
                backup_table('dynflow_actions', state) { |status| yield(status) }
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                yield('Backup Tasks [running]')
         
     | 
| 
      
 29 
     | 
    
         
            +
                export_csv("SELECT * FROM foreman_tasks_tasks WHERE #{condition(state)}",
         
     | 
| 
      
 30 
     | 
    
         
            +
                           'foreman_tasks_tasks.csv', state)
         
     | 
| 
      
 31 
     | 
    
         
            +
                yield('Backup Tasks [DONE]')
         
     | 
| 
      
 32 
     | 
    
         
            +
                @backup_dir = nil
         
     | 
| 
       7 
33 
     | 
    
         
             
              end
         
     | 
| 
       8 
34 
     | 
    
         | 
| 
       9 
35 
     | 
    
         
             
              def running_tasks_count
         
     | 
| 
         @@ -13,10 +39,93 @@ class Features::ForemanTasks < ForemanMaintain::Feature 
     | 
|
| 
       13 
39 
     | 
    
         
             
                0
         
     | 
| 
       14 
40 
     | 
    
         
             
              end
         
     | 
| 
       15 
41 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
              def paused_tasks_count
         
     | 
| 
       17 
     | 
    
         
            -
                 
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
      
 42 
     | 
    
         
            +
              def paused_tasks_count(ignored_tasks = [])
         
     | 
| 
      
 43 
     | 
    
         
            +
                sql = <<-SQL
         
     | 
| 
      
 44 
     | 
    
         
            +
                  SELECT count(*) AS count
         
     | 
| 
      
 45 
     | 
    
         
            +
                    FROM foreman_tasks_tasks
         
     | 
| 
      
 46 
     | 
    
         
            +
                    WHERE state IN ('paused')
         
     | 
| 
      
 47 
     | 
    
         
            +
                SQL
         
     | 
| 
      
 48 
     | 
    
         
            +
                unless ignored_tasks.empty?
         
     | 
| 
      
 49 
     | 
    
         
            +
                  sql << "AND label NOT IN (#{quotize(ignored_tasks)})"
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
                feature(:foreman_database).query(sql).first['count'].to_i
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
              def count(state)
         
     | 
| 
      
 55 
     | 
    
         
            +
                feature(:foreman_database).query(<<-SQL).first['count'].to_i
         
     | 
| 
      
 56 
     | 
    
         
            +
                 SELECT count(*) AS count FROM foreman_tasks_tasks WHERE #{condition(state)}
         
     | 
| 
      
 57 
     | 
    
         
            +
                SQL
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              def delete(state)
         
     | 
| 
      
 61 
     | 
    
         
            +
                tasks_condition = condition(state)
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                feature(:foreman_database).psql(<<-SQL)
         
     | 
| 
      
 64 
     | 
    
         
            +
                 BEGIN;
         
     | 
| 
      
 65 
     | 
    
         
            +
                   DELETE FROM dynflow_steps USING foreman_tasks_tasks WHERE (foreman_tasks_tasks.external_id = dynflow_steps.execution_plan_uuid) AND #{tasks_condition};
         
     | 
| 
      
 66 
     | 
    
         
            +
                   DELETE FROM dynflow_actions USING foreman_tasks_tasks WHERE (foreman_tasks_tasks.external_id = dynflow_actions.execution_plan_uuid) AND #{tasks_condition};
         
     | 
| 
      
 67 
     | 
    
         
            +
                   DELETE FROM dynflow_execution_plans USING foreman_tasks_tasks WHERE (foreman_tasks_tasks.external_id = dynflow_execution_plans.uuid) AND #{tasks_condition};
         
     | 
| 
      
 68 
     | 
    
         
            +
                   DELETE FROM foreman_tasks_tasks WHERE #{tasks_condition};
         
     | 
| 
      
 69 
     | 
    
         
            +
                 COMMIT;
         
     | 
| 
      
 70 
     | 
    
         
            +
                SQL
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                count(state)
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
              def condition(state)
         
     | 
| 
      
 76 
     | 
    
         
            +
                raise 'Invalid State' unless valid(state)
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                if state == :old
         
     | 
| 
      
 79 
     | 
    
         
            +
                  old_tasks_condition
         
     | 
| 
      
 80 
     | 
    
         
            +
                else
         
     | 
| 
      
 81 
     | 
    
         
            +
                  tasks_condition(state)
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
              end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
              private
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
              def backup_dir(state)
         
     | 
| 
      
 88 
     | 
    
         
            +
                @backup_dir ||=
         
     | 
| 
      
 89 
     | 
    
         
            +
                  "/var/lib/foreman/backup-tasks/#{state}/#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}"
         
     | 
| 
      
 90 
     | 
    
         
            +
              end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
              def backup_table(table, state, fkey = 'execution_plan_uuid')
         
     | 
| 
      
 93 
     | 
    
         
            +
                yield("Backup #{table} [running]")
         
     | 
| 
      
 94 
     | 
    
         
            +
                sql = "SELECT #{table}.* FROM foreman_tasks_tasks JOIN #{table} ON\
         
     | 
| 
      
 95 
     | 
    
         
            +
                   (foreman_tasks_tasks.external_id = #{table}.#{fkey})"
         
     | 
| 
      
 96 
     | 
    
         
            +
                export_csv(sql, "#{table}.csv", state)
         
     | 
| 
      
 97 
     | 
    
         
            +
                yield("Backup #{table} [DONE]")
         
     | 
| 
      
 98 
     | 
    
         
            +
              end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
              def export_csv(sql, file_name, state)
         
     | 
| 
      
 101 
     | 
    
         
            +
                dir = prepare_for_backup(state)
         
     | 
| 
      
 102 
     | 
    
         
            +
                filepath = "#{dir}/#{file_name}"
         
     | 
| 
      
 103 
     | 
    
         
            +
                execute("echo \"COPY (#{sql}) TO STDOUT WITH CSV;\" \
         
     | 
| 
      
 104 
     | 
    
         
            +
                  | su - postgres -c '/usr/bin/psql -d foreman' | bzip2 -9 > #{filepath}.bz2")
         
     | 
| 
      
 105 
     | 
    
         
            +
              end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
              def old_tasks_condition(state = "'stopped', 'paused'")
         
     | 
| 
      
 108 
     | 
    
         
            +
                "foreman_tasks_tasks.state IN (#{state}) AND " \
         
     | 
| 
      
 109 
     | 
    
         
            +
                   "foreman_tasks_tasks.started_at < CURRENT_DATE - INTERVAL '#{MIN_AGE} days'"
         
     | 
| 
      
 110 
     | 
    
         
            +
              end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
              def prepare_for_backup(state)
         
     | 
| 
      
 113 
     | 
    
         
            +
                dir = backup_dir(state)
         
     | 
| 
      
 114 
     | 
    
         
            +
                execute("mkdir -p #{dir}")
         
     | 
| 
      
 115 
     | 
    
         
            +
                dir
         
     | 
| 
      
 116 
     | 
    
         
            +
              end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
              def quotize(array)
         
     | 
| 
      
 119 
     | 
    
         
            +
                array.map { |el| "'#{el}'" }.join(',')
         
     | 
| 
      
 120 
     | 
    
         
            +
              end
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
              def tasks_condition(state)
         
     | 
| 
      
 123 
     | 
    
         
            +
                safe_to_delete_tasks = quotize(SAFE_TO_DELETE)
         
     | 
| 
      
 124 
     | 
    
         
            +
                "foreman_tasks_tasks.state = '#{state}' AND " \
         
     | 
| 
      
 125 
     | 
    
         
            +
                "foreman_tasks_tasks.label IN (#{safe_to_delete_tasks})"
         
     | 
| 
      
 126 
     | 
    
         
            +
              end
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
              def valid(state)
         
     | 
| 
      
 129 
     | 
    
         
            +
                [:old, :planning, :pending].include?(state)
         
     | 
| 
       21 
130 
     | 
    
         
             
              end
         
     | 
| 
       22 
131 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,75 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Features::SyncPlans < ForemanMaintain::Feature
         
     | 
| 
      
 2 
     | 
    
         
            +
              metadata do
         
     | 
| 
      
 3 
     | 
    
         
            +
                label :sync_plans
         
     | 
| 
      
 4 
     | 
    
         
            +
              end
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              def active_sync_plans_count
         
     | 
| 
      
 7 
     | 
    
         
            +
                feature(:foreman_database).query(
         
     | 
| 
      
 8 
     | 
    
         
            +
                  <<-SQL
         
     | 
| 
      
 9 
     | 
    
         
            +
                    SELECT count(*) AS count FROM katello_sync_plans WHERE enabled ='t'
         
     | 
| 
      
 10 
     | 
    
         
            +
                  SQL
         
     | 
| 
      
 11 
     | 
    
         
            +
                ).first['count'].to_i
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              def ids_by_status(enabled = true)
         
     | 
| 
      
 15 
     | 
    
         
            +
                enabled = enabled ? 't' : 'f'
         
     | 
| 
      
 16 
     | 
    
         
            +
                feature(:foreman_database).query(
         
     | 
| 
      
 17 
     | 
    
         
            +
                  <<-SQL
         
     | 
| 
      
 18 
     | 
    
         
            +
                    SELECT id FROM katello_sync_plans WHERE enabled ='#{enabled}'
         
     | 
| 
      
 19 
     | 
    
         
            +
                  SQL
         
     | 
| 
      
 20 
     | 
    
         
            +
                ).map { |r| r['id'].to_i }
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              def disabled_plans_count
         
     | 
| 
      
 24 
     | 
    
         
            +
                data[:disabled].length
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              def make_disable(ids)
         
     | 
| 
      
 28 
     | 
    
         
            +
                update_records(ids, false)
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              def make_enable
         
     | 
| 
      
 32 
     | 
    
         
            +
                update_records(data[:disabled], true)
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              private
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              def update_records(ids, enabled)
         
     | 
| 
      
 38 
     | 
    
         
            +
                updated_record_ids = []
         
     | 
| 
      
 39 
     | 
    
         
            +
                ids.each do |sp_id|
         
     | 
| 
      
 40 
     | 
    
         
            +
                  result = hammer("sync-plan update --id #{sp_id} --enabled #{enabled}")
         
     | 
| 
      
 41 
     | 
    
         
            +
                  if result.include?('Sync plan updated')
         
     | 
| 
      
 42 
     | 
    
         
            +
                    updated_record_ids << sp_id
         
     | 
| 
      
 43 
     | 
    
         
            +
                  else
         
     | 
| 
      
 44 
     | 
    
         
            +
                    raise result
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
                updated_record_ids
         
     | 
| 
      
 48 
     | 
    
         
            +
              ensure
         
     | 
| 
      
 49 
     | 
    
         
            +
                new_data = sync_plan_data(enabled, updated_record_ids)
         
     | 
| 
      
 50 
     | 
    
         
            +
                save_state(new_data)
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
              def data
         
     | 
| 
      
 54 
     | 
    
         
            +
                upgrade_storage = ForemanMaintain.storage(:upgrade)
         
     | 
| 
      
 55 
     | 
    
         
            +
                @data ||= upgrade_storage.data.fetch(:sync_plans, :enabled => [], :disabled => [])
         
     | 
| 
      
 56 
     | 
    
         
            +
                @data
         
     | 
| 
      
 57 
     | 
    
         
            +
              end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
              def sync_plan_data(enabled, new_ids)
         
     | 
| 
      
 60 
     | 
    
         
            +
                sync_plan_hash = data
         
     | 
| 
      
 61 
     | 
    
         
            +
                if enabled
         
     | 
| 
      
 62 
     | 
    
         
            +
                  sync_plan_hash[:disabled] -= new_ids
         
     | 
| 
      
 63 
     | 
    
         
            +
                  sync_plan_hash[:enabled] = new_ids
         
     | 
| 
      
 64 
     | 
    
         
            +
                else
         
     | 
| 
      
 65 
     | 
    
         
            +
                  sync_plan_hash[:disabled].concat(new_ids)
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
                sync_plan_hash
         
     | 
| 
      
 68 
     | 
    
         
            +
              end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
              def save_state(sync_plan_hash = {})
         
     | 
| 
      
 71 
     | 
    
         
            +
                storage = ForemanMaintain.storage(:upgrade)
         
     | 
| 
      
 72 
     | 
    
         
            +
                storage[:sync_plans] = sync_plan_hash
         
     | 
| 
      
 73 
     | 
    
         
            +
                storage.save
         
     | 
| 
      
 74 
     | 
    
         
            +
              end
         
     | 
| 
      
 75 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Procedures::ForemanTasks
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Delete < ForemanMaintain::Procedure
         
     | 
| 
      
 3 
     | 
    
         
            +
                metadata do
         
     | 
| 
      
 4 
     | 
    
         
            +
                  param :state, 'In what state should the task be deleted'
         
     | 
| 
      
 5 
     | 
    
         
            +
                end
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def run
         
     | 
| 
      
 8 
     | 
    
         
            +
                  with_spinner("Deleting #{@state} task") do |spinner|
         
     | 
| 
      
 9 
     | 
    
         
            +
                    count_tasks_before = feature(:foreman_tasks).count(@state)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                    if count_tasks_before > 0
         
     | 
| 
      
 12 
     | 
    
         
            +
                      spinner.update "Backup #{@state} tasks"
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                      feature(:foreman_tasks).backup_tasks(@state) do |backup_progress|
         
     | 
| 
      
 15 
     | 
    
         
            +
                        spinner.update backup_progress
         
     | 
| 
      
 16 
     | 
    
         
            +
                      end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                      spinner.update "Deleting #{@state} tasks [running]"
         
     | 
| 
      
 19 
     | 
    
         
            +
                      count_tasks_later = feature(:foreman_tasks).delete(@state)
         
     | 
| 
      
 20 
     | 
    
         
            +
                      spinner.update "Deleting #{@state} tasks [DONE]"
         
     | 
| 
      
 21 
     | 
    
         
            +
                    end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                    spinner.update(
         
     | 
| 
      
 24 
     | 
    
         
            +
                      "Deleted #{@state} stopped and paused tasks: #{count_tasks_before - count_tasks_later}"
         
     | 
| 
      
 25 
     | 
    
         
            +
                    )
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                def description
         
     | 
| 
      
 30 
     | 
    
         
            +
                  "Delete #{@state} tasks"
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Procedures::ForemanTasks
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Resume < ForemanMaintain::Procedure
         
     | 
| 
      
 3 
     | 
    
         
            +
                include ForemanMaintain::Concerns::Hammer
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                metadata do
         
     | 
| 
      
 6 
     | 
    
         
            +
                  for_feature :foreman_tasks
         
     | 
| 
      
 7 
     | 
    
         
            +
                  description 'resume paused tasks'
         
     | 
| 
      
 8 
     | 
    
         
            +
                end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                def run
         
     | 
| 
      
 11 
     | 
    
         
            +
                  output << hammer('task resume')
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'cgi'
         
     | 
| 
      
 2 
     | 
    
         
            +
            module Procedures::ForemanTasks
         
     | 
| 
      
 3 
     | 
    
         
            +
              class UiInvestigate < ForemanMaintain::Procedure
         
     | 
| 
      
 4 
     | 
    
         
            +
                metadata do
         
     | 
| 
      
 5 
     | 
    
         
            +
                  for_feature :foreman_tasks
         
     | 
| 
      
 6 
     | 
    
         
            +
                  description 'investigate the tasks via UI'
         
     | 
| 
      
 7 
     | 
    
         
            +
                  param :search_query
         
     | 
| 
      
 8 
     | 
    
         
            +
                end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                attr_reader :search_query
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def run
         
     | 
| 
      
 13 
     | 
    
         
            +
                  ask(<<-MESSAGE.strip_heredoc)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    Go to https://#{hostname}/foreman_tasks/tasks?search=#{CGI.escape(@search_query.to_s)}
         
     | 
| 
      
 15 
     | 
    
         
            +
                    press ENTER after the paused tasks are resolved.
         
     | 
| 
      
 16 
     | 
    
         
            +
                  MESSAGE
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,50 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Procedures::HammerSetup < ForemanMaintain::Procedure
         
     | 
| 
      
 2 
     | 
    
         
            +
              def run
         
     | 
| 
      
 3 
     | 
    
         
            +
                setup_from_default || setup_from_answers
         
     | 
| 
      
 4 
     | 
    
         
            +
                puts "New settings saved into #{hammer.config_file}"
         
     | 
| 
      
 5 
     | 
    
         
            +
                hammer.run_command('architecture list') # if not setup properly, an error will be risen
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              def necessary?
         
     | 
| 
      
 9 
     | 
    
         
            +
                !hammer.ready?
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              def description
         
     | 
| 
      
 13 
     | 
    
         
            +
                'Setup hammer'
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              private
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              def setup_from_default
         
     | 
| 
      
 19 
     | 
    
         
            +
                used_default_file = hammer.setup_from_default
         
     | 
| 
      
 20 
     | 
    
         
            +
                if used_default_file
         
     | 
| 
      
 21 
     | 
    
         
            +
                  puts "Using defaults from #{used_default_file}"
         
     | 
| 
      
 22 
     | 
    
         
            +
                  true
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              def setup_from_answers
         
     | 
| 
      
 27 
     | 
    
         
            +
                loop do
         
     | 
| 
      
 28 
     | 
    
         
            +
                  username, password = ask_for_credentials
         
     | 
| 
      
 29 
     | 
    
         
            +
                  break if username.nil?
         
     | 
| 
      
 30 
     | 
    
         
            +
                  if hammer.setup_from_answers(username, password)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    return true
         
     | 
| 
      
 32 
     | 
    
         
            +
                  else
         
     | 
| 
      
 33 
     | 
    
         
            +
                    puts 'Invalid credentials'
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
              def ask_for_credentials
         
     | 
| 
      
 39 
     | 
    
         
            +
                username = ask('Hammer username [admin]:')
         
     | 
| 
      
 40 
     | 
    
         
            +
                return if username.nil?
         
     | 
| 
      
 41 
     | 
    
         
            +
                username = 'admin' if username.empty?
         
     | 
| 
      
 42 
     | 
    
         
            +
                password = ask('Hammer password:', :password => true)
         
     | 
| 
      
 43 
     | 
    
         
            +
                return if password.nil?
         
     | 
| 
      
 44 
     | 
    
         
            +
                [username.strip, password.strip]
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              def hammer
         
     | 
| 
      
 48 
     | 
    
         
            +
                ForemanMaintain::Utils::Hammer.instance
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Procedures::InstallPackage < ForemanMaintain::Procedure
         
     | 
| 
      
 2 
     | 
    
         
            +
              metadata do
         
     | 
| 
      
 3 
     | 
    
         
            +
                param :packages, 'List of packages to install', :array => true
         
     | 
| 
      
 4 
     | 
    
         
            +
              end
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              def run
         
     | 
| 
      
 7 
     | 
    
         
            +
                install_packages(@packages, :assumeyes => assumeyes?)
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              def necessary?
         
     | 
| 
      
 11 
     | 
    
         
            +
                @packages.any? { |package| package_version(package).nil? }
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              def description
         
     | 
| 
      
 15 
     | 
    
         
            +
                "Install package(s) #{@packages.join(', ')}"
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Procedures::SyncPlans
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Disable < ForemanMaintain::Procedure
         
     | 
| 
      
 3 
     | 
    
         
            +
                metadata do
         
     | 
| 
      
 4 
     | 
    
         
            +
                  for_feature :sync_plans
         
     | 
| 
      
 5 
     | 
    
         
            +
                  description 'disable active sync plans'
         
     | 
| 
      
 6 
     | 
    
         
            +
                end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                def run
         
     | 
| 
      
 9 
     | 
    
         
            +
                  disable_all_enabled_sync_plans
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                private
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                def disable_all_enabled_sync_plans
         
     | 
| 
      
 15 
     | 
    
         
            +
                  with_spinner('disabling sync plans') do |spinner|
         
     | 
| 
      
 16 
     | 
    
         
            +
                    ids = feature(:sync_plans).ids_by_status(true)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    feature(:sync_plans).make_disable(ids)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    spinner.update "Total #{ids.length} sync plans are now disabled."
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     |