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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +107 -25
  3. data/bin/foreman-maintain +1 -0
  4. data/definitions/checks/disk_speed_minimal.rb +31 -19
  5. data/definitions/checks/foreman_tasks/invalid/check_old.rb +20 -0
  6. data/definitions/checks/foreman_tasks/invalid/check_pending_state.rb +20 -0
  7. data/definitions/checks/foreman_tasks/invalid/check_planning_state.rb +20 -0
  8. data/definitions/checks/foreman_tasks/not_paused.rb +29 -0
  9. data/definitions/checks/foreman_tasks/not_running.rb +14 -0
  10. data/definitions/checks/sync_plans/with_disabled_status.rb +18 -0
  11. data/definitions/checks/sync_plans/with_enabled_status.rb +18 -0
  12. data/definitions/checks/system_registration.rb +31 -0
  13. data/definitions/features/downstream.rb +5 -3
  14. data/definitions/features/foreman_1_11_x.rb +4 -2
  15. data/definitions/features/foreman_1_7_x.rb +5 -3
  16. data/definitions/features/foreman_database.rb +11 -5
  17. data/definitions/features/foreman_tasks.rb +118 -9
  18. data/definitions/features/sync_plans.rb +75 -0
  19. data/definitions/features/upstream.rb +5 -3
  20. data/definitions/procedures/foreman_tasks/delete.rb +33 -0
  21. data/definitions/procedures/foreman_tasks/resume.rb +14 -0
  22. data/definitions/procedures/foreman_tasks/ui_investigate.rb +19 -0
  23. data/definitions/procedures/hammer_setup.rb +50 -0
  24. data/definitions/procedures/install_package.rb +17 -0
  25. data/definitions/procedures/sync_plans/disable.rb +22 -0
  26. data/definitions/procedures/sync_plans/enable.rb +21 -0
  27. data/definitions/scenarios/pre_upgrade_check_foreman_1_14.rb +7 -6
  28. data/definitions/scenarios/pre_upgrade_check_satellite_6_0_z.rb +8 -6
  29. data/definitions/scenarios/pre_upgrade_check_satellite_6_1.rb +8 -6
  30. data/definitions/scenarios/pre_upgrade_check_satellite_6_1_z.rb +8 -6
  31. data/definitions/scenarios/pre_upgrade_check_satellite_6_2.rb +8 -6
  32. data/definitions/scenarios/pre_upgrade_check_satellite_6_2_z.rb +8 -6
  33. data/definitions/scenarios/pre_upgrade_check_satellite_6_3.rb +8 -6
  34. data/lib/foreman_maintain.rb +52 -5
  35. data/lib/foreman_maintain/check.rb +18 -12
  36. data/lib/foreman_maintain/cli/base.rb +9 -2
  37. data/lib/foreman_maintain/cli/health_command.rb +2 -1
  38. data/lib/foreman_maintain/cli/upgrade_command.rb +2 -0
  39. data/lib/foreman_maintain/concerns/hammer.rb +20 -0
  40. data/lib/foreman_maintain/concerns/logger.rb +1 -5
  41. data/lib/foreman_maintain/concerns/metadata.rb +138 -31
  42. data/lib/foreman_maintain/concerns/system_helpers.rb +36 -32
  43. data/lib/foreman_maintain/config.rb +40 -5
  44. data/lib/foreman_maintain/core_ext.rb +24 -0
  45. data/lib/foreman_maintain/detector.rb +12 -13
  46. data/lib/foreman_maintain/error.rb +28 -0
  47. data/lib/foreman_maintain/executable.rb +86 -11
  48. data/lib/foreman_maintain/feature.rb +1 -0
  49. data/lib/foreman_maintain/param.rb +47 -0
  50. data/lib/foreman_maintain/reporter.rb +20 -3
  51. data/lib/foreman_maintain/reporter/cli_reporter.rb +166 -66
  52. data/lib/foreman_maintain/runner.rb +56 -13
  53. data/lib/foreman_maintain/runner/execution.rb +8 -0
  54. data/lib/foreman_maintain/scenario.rb +46 -2
  55. data/lib/foreman_maintain/top_level_modules.rb +3 -0
  56. data/lib/foreman_maintain/utils.rb +2 -0
  57. data/lib/foreman_maintain/utils/command_runner.rb +101 -0
  58. data/lib/foreman_maintain/utils/disk/device.rb +5 -9
  59. data/lib/foreman_maintain/utils/hammer.rb +78 -0
  60. data/lib/foreman_maintain/version.rb +1 -1
  61. data/lib/foreman_maintain/yaml_storage.rb +48 -0
  62. metadata +27 -9
  63. data/definitions/checks/foreman_tasks_not_paused.rb +0 -14
  64. data/definitions/checks/foreman_tasks_not_running.rb +0 -10
  65. data/definitions/procedures/foreman_tasks_resume.rb +0 -13
  66. 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
@@ -11,3 +11,6 @@ end
11
11
 
12
12
  module Scenarios
13
13
  end
14
+
15
+ # do not include this names in autogenerated labels
16
+ ForemanMaintain::Concerns::Metadata.top_level_modules = [Features, Checks, Procedures, Scenarios]
@@ -1 +1,3 @@
1
+ require 'foreman_maintain/utils/command_runner'
1
2
  require 'foreman_maintain/utils/disk'
3
+ require 'foreman_maintain/utils/hammer'
@@ -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(fuseblk nfs).freeze
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
@@ -1,3 +1,3 @@
1
1
  module ForemanMaintain
2
- VERSION = '0.0.2'.freeze
2
+ VERSION = '0.0.3'.freeze
3
3
  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.2
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-03-16 00:00:00.000000000 Z
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
- Provides various features that helps keeping the Foreman/Satellite up and
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/foreman_tasks_not_paused.rb
113
- - definitions/checks/foreman_tasks_not_running.rb
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/foreman_tasks_resume.rb
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/logger.rb
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