foreman_maintain 0.7.0 → 0.7.6

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/definitions/checks/candlepin/db_up.rb +10 -6
  3. data/definitions/checks/disk/available_space_candlepin.rb +27 -0
  4. data/definitions/checks/foreman/db_up.rb +10 -6
  5. data/definitions/checks/foreman_tasks/not_paused.rb +10 -13
  6. data/definitions/checks/mongo/db_up.rb +10 -6
  7. data/definitions/features/candlepin.rb +4 -0
  8. data/definitions/features/dynflow_sidekiq.rb +7 -4
  9. data/definitions/features/foreman_cockpit.rb +15 -0
  10. data/definitions/features/foreman_tasks.rb +12 -2
  11. data/definitions/features/mongo.rb +10 -0
  12. data/definitions/features/pulpcore.rb +11 -13
  13. data/definitions/features/service.rb +37 -18
  14. data/definitions/procedures/backup/online/safety_confirmation.rb +11 -6
  15. data/definitions/procedures/content/migration_reset.rb +12 -0
  16. data/definitions/procedures/content/prepare.rb +2 -1
  17. data/definitions/procedures/foreman_tasks/delete.rb +3 -4
  18. data/definitions/procedures/foreman_tasks/resume.rb +5 -0
  19. data/definitions/procedures/prep_6_10_upgrade.rb +1 -3
  20. data/definitions/procedures/pulp/remove.rb +87 -0
  21. data/definitions/procedures/service/base.rb +1 -2
  22. data/definitions/procedures/service/list.rb +13 -2
  23. data/definitions/scenarios/backup.rb +2 -0
  24. data/definitions/scenarios/content.rb +38 -6
  25. data/definitions/scenarios/restore.rb +1 -1
  26. data/lib/foreman_maintain.rb +2 -0
  27. data/lib/foreman_maintain/cli.rb +2 -3
  28. data/lib/foreman_maintain/cli/content_command.rb +12 -0
  29. data/lib/foreman_maintain/cli/upgrade_command.rb +3 -0
  30. data/lib/foreman_maintain/concerns/base_database.rb +11 -0
  31. data/lib/foreman_maintain/concerns/primary_checks.rb +23 -0
  32. data/lib/foreman_maintain/package_manager/dnf.rb +1 -0
  33. data/lib/foreman_maintain/reporter/cli_reporter.rb +6 -2
  34. data/lib/foreman_maintain/runner.rb +8 -5
  35. data/lib/foreman_maintain/utils/backup.rb +1 -1
  36. data/lib/foreman_maintain/utils/disk/io_device.rb +4 -0
  37. data/lib/foreman_maintain/utils/service/systemd.rb +2 -1
  38. data/lib/foreman_maintain/version.rb +1 -1
  39. metadata +7 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4151b9d6dbc810f7f85aa093bdcfc4f967530dbeddcf7e13e88ce998125211dc
4
- data.tar.gz: e7db5a3881d9652bae19c61f95ff95076745f36212c6e36f4cf582d4b5f33c8f
3
+ metadata.gz: 743d74ea6833807f28ea4f14096821c03d080ede64f8cc74ee4146b4dd8eea26
4
+ data.tar.gz: 4b54030179cb8019c0a5936f5accfb8a91f6a092c9221cd1b03e9d342c5bbaa3
5
5
  SHA512:
6
- metadata.gz: 56165e03d708aa74d5b370cd7f2ca96a0121b2b97d14f326372181ef2c464eb9856dbafd1f60ad99aea89c9a610a1579a334a4a69c12abee38b70d2eb84a899a
7
- data.tar.gz: e43c42dbbe5aab6752e16429dae6fd70367510be2df57f026aa5ad53bb1efb9ef9e4eb2efc4331aef3823b93729412b789bc8c3e8396e03b4563bc82cf42199b
6
+ metadata.gz: 89f47a46c1061c416d9042c116dea5ad0acbf973418d4452e44500a8ebbb55cd598d3d3001332ec92970094dd2ebd36af8a92fde9d28835a5544e96d6bd333d0
7
+ data.tar.gz: 370b409946044d658e102e0aa64733842163b5834289b7cf059dd16733ee2e6f1263aa6221212caa3b5fcb1f77fd81519c414e542357cac8df579f0d4031c7fd
@@ -9,15 +9,19 @@ module Checks
9
9
 
10
10
  def run
11
11
  status = false
12
- with_spinner('Checking connection to the Candlepin DB') do
13
- status = feature(:candlepin_database).ping
12
+ if feature(:candlepin_database).psql_cmd_available?
13
+ with_spinner('Checking connection to the Candlepin DB') do
14
+ status = feature(:candlepin_database).ping
15
+ end
16
+ assert(status, 'Candlepin DB is not responding. ' \
17
+ 'It needs to be up and running to perform the following steps',
18
+ :next_steps => start_pgsql)
19
+ else
20
+ feature(:candlepin_database).raise_psql_missing_error
14
21
  end
15
- assert(status, 'Candlepin DB is not responding. ' \
16
- 'It needs to be up and running to perform the following steps',
17
- :next_steps => next_steps)
18
22
  end
19
23
 
20
- def next_steps
24
+ def start_pgsql
21
25
  if feature(:candlepin_database).local?
22
26
  [Procedures::Service::Start.new(:only => 'postgresql')]
23
27
  else
@@ -0,0 +1,27 @@
1
+ module Checks
2
+ module Disk
3
+ class AvailableSpaceCandlepin < ForemanMaintain::Check
4
+ metadata do
5
+ label :available_space_cp
6
+ description 'Check to make sure /var/lib/candlepin has enough space'
7
+ tags :pre_upgrade
8
+ confine do
9
+ feature(:candlepin) && check_min_version('candlepin', '3.1')
10
+ end
11
+ end
12
+
13
+ MAX_USAGE_IN_PERCENT = 90
14
+
15
+ def run
16
+ assert(enough_space?, "System has more than #{MAX_USAGE_IN_PERCENT}% space used"\
17
+ " on #{feature(:candlepin).work_dir}.\n"\
18
+ 'See https://bugzilla.redhat.com/show_bug.cgi?id=1898605')
19
+ end
20
+
21
+ def enough_space?
22
+ io_obj = ForemanMaintain::Utils::Disk::IODevice.new(feature(:candlepin).work_dir)
23
+ io_obj.space_used_in_percent < MAX_USAGE_IN_PERCENT
24
+ end
25
+ end
26
+ end
27
+ end
@@ -9,15 +9,19 @@ module Checks
9
9
 
10
10
  def run
11
11
  status = false
12
- with_spinner('Checking connection to the Foreman DB') do
13
- status = feature(:foreman_database).ping
12
+ if feature(:foreman_database).psql_cmd_available?
13
+ with_spinner('Checking connection to the Foreman DB') do
14
+ status = feature(:foreman_database).ping
15
+ end
16
+ assert(status, 'Foreman DB is not responding. ' \
17
+ 'It needs to be up and running to perform the following steps',
18
+ :next_steps => start_pgsql)
19
+ else
20
+ feature(:foreman_database).raise_psql_missing_error
14
21
  end
15
- assert(status, 'Foreman DB is not responding. ' \
16
- 'It needs to be up and running to perform the following steps',
17
- :next_steps => next_steps)
18
22
  end
19
23
 
20
- def next_steps
24
+ def start_pgsql
21
25
  if feature(:foreman_database).local?
22
26
  [Procedures::Service::Start.new(:only => 'postgresql')]
23
27
  else
@@ -9,23 +9,20 @@ module Checks::ForemanTasks
9
9
  end
10
10
 
11
11
  def run
12
- paused_tasks_count = feature(:foreman_tasks).paused_tasks_count(ignored_tasks)
12
+ paused_tasks_count = feature(:foreman_tasks).paused_tasks_count()
13
13
  assert(paused_tasks_count == 0,
14
14
  "There are currently #{paused_tasks_count} paused tasks in the system",
15
- :next_steps =>
16
- [Procedures::ForemanTasks::Resume.new,
17
- Procedures::ForemanTasks::UiInvestigate.new('search_query' => scoped_search_query)])
15
+ :next_steps => next_procedures)
18
16
  end
19
17
 
20
- # Note: this is for UI link generation only: we are not using scoped search for querying
21
- # the tasks itself as we use direct SQL instead
22
- def scoped_search_query
23
- "state = paused AND label !^(#{ignored_tasks.join(' ')})"
24
- end
25
-
26
- def ignored_tasks
27
- %w[Actions::Candlepin::ListenOnCandlepinEvents
28
- Actions::Katello::EventQueue::Monitor]
18
+ def next_procedures
19
+ if assumeyes?
20
+ return [Procedures::ForemanTasks::Resume.new,
21
+ Procedures::ForemanTasks::Delete.new(:state => :paused)]
22
+ end
23
+ [Procedures::ForemanTasks::Resume.new,
24
+ Procedures::ForemanTasks::Delete.new(:state => :paused),
25
+ Procedures::ForemanTasks::UiInvestigate.new('search_query' => 'state = paused')]
29
26
  end
30
27
  end
31
28
  end
@@ -9,15 +9,19 @@ module Checks
9
9
 
10
10
  def run
11
11
  status = false
12
- with_spinner('Checking connection to the Mongo DB') do
13
- status = feature(:mongo).ping
12
+ if feature(:mongo).mongo_cmd_available?
13
+ with_spinner('Checking connection to the Mongo DB') do
14
+ status = feature(:mongo).ping
15
+ end
16
+ assert(status, 'Mongo DB is not responding. ' \
17
+ 'It needs to be up and running to perform the following steps.',
18
+ :next_steps => start_mongodb)
19
+ else
20
+ feature(:mongo).raise_mongo_client_missing_error
14
21
  end
15
- assert(status, 'Mongo DB is not responding. ' \
16
- 'It needs to be up and running to perform the following steps.',
17
- :next_steps => next_steps)
18
22
  end
19
23
 
20
- def next_steps
24
+ def start_mongodb
21
25
  if feature(:mongo).local?
22
26
  [Procedures::Service::Start.new(:only => feature(:mongo).services)]
23
27
  else
@@ -7,6 +7,10 @@ class Features::Candlepin < ForemanMaintain::Feature
7
7
  end
8
8
  end
9
9
 
10
+ def work_dir
11
+ '/var/lib/candlepin'
12
+ end
13
+
10
14
  def services
11
15
  [
12
16
  system_service('tomcat', 20),
@@ -7,10 +7,6 @@ class Features::DynflowSidekiq < ForemanMaintain::Feature
7
7
  end
8
8
  end
9
9
 
10
- def services
11
- service_names.map { |service| system_service service, instance_priority(service) }
12
- end
13
-
14
10
  def config_files
15
11
  # Workaround until foreman-installer can deploy scaled workers
16
12
  service_symlinks = configured_instances.map do |service|
@@ -22,6 +18,13 @@ class Features::DynflowSidekiq < ForemanMaintain::Feature
22
18
  ].flatten
23
19
  end
24
20
 
21
+ def services
22
+ service_names.map do |service|
23
+ system_service service, instance_priority(service),
24
+ :instance_parent_unit => 'dynflow-sidekiq@'
25
+ end
26
+ end
27
+
25
28
  private
26
29
 
27
30
  def instance_priority(instance)
@@ -0,0 +1,15 @@
1
+ class Features::ForemanCockpit < ForemanMaintain::Feature
2
+ metadata do
3
+ label :foreman_cockpit
4
+
5
+ confine do
6
+ server? && find_package('tfm-rubygem-foreman_remote_execution-cockpit')
7
+ end
8
+ end
9
+
10
+ def services
11
+ [
12
+ system_service('foreman-cockpit')
13
+ ]
14
+ end
15
+ end
@@ -89,13 +89,19 @@ class Features::ForemanTasks < ForemanMaintain::Feature
89
89
 
90
90
  if state == :old
91
91
  old_tasks_condition
92
+ elsif state == :paused
93
+ paused_tasks_condition
92
94
  else
93
95
  tasks_condition(state)
94
96
  end
95
97
  end
96
98
 
97
99
  def resume_task_using_hammer
98
- feature(:hammer).run('task resume')
100
+ if feature(:satellite) && feature(:satellite).current_minor_version == '6.8'
101
+ feature(:hammer).run('task resume --search "" --fields="Total tasks resumed"')
102
+ else
103
+ feature(:hammer).run('task resume --fields="Total tasks resumed"')
104
+ end
99
105
  end
100
106
 
101
107
  def fetch_tasks_status(state, spinner)
@@ -176,6 +182,10 @@ class Features::ForemanTasks < ForemanMaintain::Feature
176
182
  "foreman_tasks_tasks.started_at < CURRENT_DATE - INTERVAL '#{MIN_AGE} days'"
177
183
  end
178
184
 
185
+ def paused_tasks_condition(state = "'paused'")
186
+ "foreman_tasks_tasks.state IN (#{state})"
187
+ end
188
+
179
189
  def prepare_for_backup(state)
180
190
  dir = backup_dir(state)
181
191
  execute("mkdir -p #{dir}")
@@ -193,6 +203,6 @@ class Features::ForemanTasks < ForemanMaintain::Feature
193
203
  end
194
204
 
195
205
  def valid(state)
196
- %w[old planning pending].include?(state.to_s)
206
+ %w[old planning pending paused].include?(state.to_s)
197
207
  end
198
208
  end
@@ -140,6 +140,16 @@ class Features::Mongo < ForemanMaintain::Feature
140
140
  end
141
141
  end
142
142
 
143
+ def mongo_cmd_available?
144
+ exit_status, _output = execute_with_status("which #{core.client_command}")
145
+ exit_status == 0
146
+ end
147
+
148
+ def raise_mongo_client_missing_error
149
+ raise ForemanMaintain::Error::Fail, "The #{core.client_command} command not found."\
150
+ " Make sure system has #{core.client_command} utility installed."
151
+ end
152
+
143
153
  private
144
154
 
145
155
  def load_mongo_core_default(version)
@@ -11,18 +11,19 @@ class Features::Pulpcore < ForemanMaintain::Feature
11
11
  end
12
12
 
13
13
  def services
14
- pulpcore_common_services + [
14
+ self.class.pulpcore_common_services + [
15
+ system_service('rh-redis5-redis', 5),
15
16
  system_service('pulpcore-worker@*', 20, :all => true, :skip_enablement => true),
16
17
  system_service('httpd', 30)
17
18
  ]
18
19
  end
19
20
 
20
- def pulpcore_migration_services
21
+ def self.pulpcore_migration_services
21
22
  pulpcore_common_services + [
22
- system_service('pulpcore-worker@1', 20),
23
- system_service('pulpcore-worker@2', 20),
24
- system_service('pulpcore-worker@3', 20),
25
- system_service('pulpcore-worker@4', 20)
23
+ ForemanMaintain::Utils.system_service('pulpcore-worker@1', 20),
24
+ ForemanMaintain::Utils.system_service('pulpcore-worker@2', 20),
25
+ ForemanMaintain::Utils.system_service('pulpcore-worker@3', 20),
26
+ ForemanMaintain::Utils.system_service('pulpcore-worker@4', 20)
26
27
  ]
27
28
  end
28
29
 
@@ -32,14 +33,11 @@ class Features::Pulpcore < ForemanMaintain::Feature
32
33
  ]
33
34
  end
34
35
 
35
- private
36
-
37
- def pulpcore_common_services
36
+ def self.pulpcore_common_services
38
37
  [
39
- system_service('rh-redis5-redis', 5),
40
- system_service('pulpcore-api', 10, :socket => 'pulpcore-api'),
41
- system_service('pulpcore-content', 10, :socket => 'pulpcore-content'),
42
- system_service('pulpcore-resource-manager', 10)
38
+ ForemanMaintain::Utils.system_service('pulpcore-api', 10, :socket => 'pulpcore-api'),
39
+ ForemanMaintain::Utils.system_service('pulpcore-content', 10, :socket => 'pulpcore-content'),
40
+ ForemanMaintain::Utils.system_service('pulpcore-resource-manager', 10)
43
41
  ]
44
42
  end
45
43
  end
@@ -8,7 +8,6 @@ class Features::Service < ForemanMaintain::Feature
8
8
  # { :only => ["httpd"] }
9
9
  # { :exclude => ["pulp-workers", "tomcat"] }
10
10
  # { :include => ["crond"] }
11
-
12
11
  if feature(:instance).downstream && feature(:instance).downstream.less_than_version?('6.3')
13
12
  use_katello_service(action, options)
14
13
  else
@@ -27,11 +26,12 @@ class Features::Service < ForemanMaintain::Feature
27
26
  end
28
27
 
29
28
  def filtered_services(options)
30
- service_list = include_unregistered_services(existing_services, options[:include])
31
- service_list = filter_services(service_list, options)
32
- raise 'No services found matching your parameters' unless service_list.any?
29
+ services = include_unregistered_services(existing_services, options[:include])
30
+ services = filter_services(services, options)
31
+ raise 'No services found matching your parameters' unless services.any?
32
+ return services unless options[:reverse]
33
33
 
34
- options[:reverse] ? service_list.reverse : service_list
34
+ Hash[services.sort_by { |k, _| k.to_i }.reverse]
35
35
  end
36
36
 
37
37
  def action_noun(action)
@@ -61,40 +61,59 @@ class Features::Service < ForemanMaintain::Feature
61
61
  def run_action_on_services(action, options, spinner)
62
62
  status = 0
63
63
  failed_services = []
64
+ filtered_services(options).each_value do |group|
65
+ systemctl_status, _output = execute_with_status('systemctl ' \
66
+ "#{action} #{group.map(&:name).join(' ')}")
67
+ display_status(group, options, action, spinner)
68
+ if systemctl_status > 0
69
+ status = systemctl_status
70
+ failed_services |= failed_services_by_status(action, group, spinner)
71
+ end
72
+ end
73
+ [status, failed_services]
74
+ end
64
75
 
65
- filtered_services(options).each do |service|
76
+ def display_status(services, options, action, spinner)
77
+ services.each do |service|
66
78
  spinner.update("#{action_noun(action)} #{service}")
67
- item_status, output = service.send(action.to_sym)
68
-
69
- formatted = format_status(output, item_status, options)
79
+ formatted = format_status(service.status, options, action)
70
80
  puts formatted unless formatted.empty?
71
-
72
- if item_status > 0
73
- status = item_status
74
- failed_services << service
75
- end
76
81
  end
77
- [status, failed_services]
78
82
  end
79
83
 
80
- def format_status(output, exit_code, options)
84
+ def format_status(service_status, options, action)
85
+ exit_code, output = service_status
81
86
  status = ''
82
87
  if !options[:failing] || exit_code > 0
83
88
  if options[:brief]
84
89
  status += format_brief_status(exit_code)
85
- elsif !(output.nil? || output.empty?)
90
+ elsif include_output?(action, exit_code)
86
91
  status += "\n" + output
87
92
  end
88
93
  end
89
94
  status
90
95
  end
91
96
 
97
+ def include_output?(action, status)
98
+ (action == 'start' && status > 0) ||
99
+ action == 'status'
100
+ end
101
+
92
102
  def format_brief_status(exit_code)
93
103
  result = exit_code == 0 ? reporter.status_label(:success) : reporter.status_label(:fail)
94
104
  padding = reporter.max_length - reporter.last_line.to_s.length - 30
95
105
  "#{' ' * padding} #{result}"
96
106
  end
97
107
 
108
+ def failed_services_by_status(action, services, spinner)
109
+ failed_services = []
110
+ services.each do |service|
111
+ spinner.update("#{action_noun(action)} #{service}")
112
+ failed_services << service unless service.running?
113
+ end
114
+ failed_services
115
+ end
116
+
98
117
  def allowed_action?(action)
99
118
  %w[start stop restart status enable disable].include?(action)
100
119
  end
@@ -119,7 +138,7 @@ class Features::Service < ForemanMaintain::Feature
119
138
  end
120
139
 
121
140
  service_list = extend_service_list_with_sockets(service_list, options)
122
- service_list.sort
141
+ service_list.group_by(&:priority).to_h
123
142
  end
124
143
 
125
144
  def include_unregistered_services(service_list, services_filter)
@@ -4,21 +4,26 @@ module Procedures::Backup
4
4
  metadata do
5
5
  description 'Data consistency warning'
6
6
  tags :backup
7
+ param :include_db_dumps, 'Are database dumps included in backup', :flag => true,
8
+ :default => false
7
9
  end
8
10
 
9
11
  def run
10
- answer = ask_decision(
11
- "*** WARNING: The online backup is intended for making a copy of the data\n" \
12
+ answer = ask_decision(warning_message(@include_db_dumps), actions_msg: 'y(yes), q(quit)')
13
+ abort! unless answer == :yes
14
+ end
15
+
16
+ def warning_message(include_db_dumps)
17
+ substr = include_db_dumps ? 'database dump' : 'online backup'
18
+ "*** WARNING: The #{substr} is intended for making a copy of the data\n" \
12
19
  '*** for debugging purposes only.' \
13
20
  " The backup routine can not ensure 100% consistency while the\n" \
14
21
  "*** backup is taking place as there is a chance there may be data mismatch between\n" \
15
22
  '*** Mongo and Postgres databases while the services are live.' \
16
- " If you wish to utilize the online backup\n" \
23
+ " If you wish to utilize the #{substr}\n" \
17
24
  '*** for production use you need to ensure that there are' \
18
25
  " no modifications occurring during\n" \
19
- "*** your backup run.\n\nDo you want to proceed?", actions_msg: 'y(yes), q(quit)'
20
- )
21
- abort! unless answer == :yes
26
+ "*** your backup run.\n\nDo you want to proceed?"
22
27
  end
23
28
  end
24
29
  end
@@ -0,0 +1,12 @@
1
+ module Procedures::Content
2
+ class MigrationReset < ForemanMaintain::Procedure
3
+ metadata do
4
+ description 'Reset the Pulp 2 to Pulp 3 migration data (pre-switchover)'
5
+ for_feature :pulpcore
6
+ end
7
+
8
+ def run
9
+ puts execute!('foreman-rake katello:pulp3_migration_reset')
10
+ end
11
+ end
12
+ end
@@ -6,7 +6,8 @@ module Procedures::Content
6
6
  end
7
7
 
8
8
  def run
9
- puts execute!('foreman-rake katello:pulp3_migration')
9
+ # use interactive to get realtime output
10
+ puts execute!('foreman-rake katello:pulp3_migration', :interactive => true)
10
11
  end
11
12
  end
12
13
  end
@@ -1,6 +1,6 @@
1
1
  module Procedures::ForemanTasks
2
2
  class Delete < ForemanMaintain::Procedure
3
- ALLOWED_STATES_VALUES = %w[old planning pending].freeze
3
+ ALLOWED_STATES_VALUES = %w[old planning pending paused].freeze
4
4
 
5
5
  metadata do
6
6
  param :state,
@@ -19,12 +19,11 @@ module Procedures::ForemanTasks
19
19
  feature(:foreman_tasks).backup_tasks(@state) do |backup_progress|
20
20
  spinner.update backup_progress
21
21
  end
22
-
23
- spinner.update "Deleting #{@state} tasks [running]"
22
+ spinner.update "Deleting #{count_tasks_before} #{@state} tasks [running]"
24
23
  count_tasks_later = feature(:foreman_tasks).delete(@state)
25
24
  spinner.update "Deleting #{@state} tasks [DONE]"
26
25
  spinner.update(
27
- "Deleted #{@state} stopped and paused tasks: #{count_tasks_before - count_tasks_later}"
26
+ "Deleted #{@state} tasks: #{count_tasks_before - count_tasks_later}"
28
27
  )
29
28
  end
30
29
  end
@@ -6,8 +6,13 @@ module Procedures::ForemanTasks
6
6
  description 'Resume paused tasks'
7
7
  end
8
8
 
9
+ WAIT_TIME = 30
10
+
9
11
  def run
10
12
  output << feature(:foreman_tasks).resume_task_using_hammer
13
+ with_spinner('Waiting 30 seconds for resumed tasks to start.') do
14
+ sleep WAIT_TIME
15
+ end
11
16
  end
12
17
  end
13
18
  end
@@ -3,8 +3,7 @@ class Procedures::Prep610Upgrade < ForemanMaintain::Procedure
3
3
  description 'Preparations for the Satellite 6.10 upgrade'
4
4
 
5
5
  confine do
6
- ::Scenarios.const_defined?('Satellite_6_10') &&
7
- feature(:satellite) &&
6
+ feature(:satellite) &&
8
7
  feature(:satellite).current_minor_version == '6.9'
9
8
  end
10
9
  end
@@ -18,7 +17,6 @@ class Procedures::Prep610Upgrade < ForemanMaintain::Procedure
18
17
  execute!('find /var/lib/pulp/content -type d -perm -g-s -exec chmod g+s {} \;')
19
18
  spinner.update('$ chown -R :pulp /var/lib/pulp/content')
20
19
  FileUtils.chown_R nil, 'pulp', '/var/lib/pulp/content'
21
- # TODO: Install Pulp 3 without starting services?
22
20
  end
23
21
  end
24
22
 
@@ -0,0 +1,87 @@
1
+ module Procedures::Pulp
2
+ class Remove < ForemanMaintain::Procedure
3
+ metadata do
4
+ description 'Remove pulp2'
5
+
6
+ confine do
7
+ check_min_version('katello-common', '4.0')
8
+ end
9
+ end
10
+
11
+ def sys
12
+ ForemanMaintain::Utils::SystemHelpers.new
13
+ end
14
+
15
+ def pulp_data_dirs
16
+ [
17
+ '/var/lib/pulp/published',
18
+ '/var/lib/pulp/content',
19
+ '/var/lib/pulp/importers',
20
+ '/var/lib/pulp/uploads',
21
+ '/var/lib/mongodb/'
22
+ ]
23
+ end
24
+
25
+ def pulp_packages
26
+ [
27
+ 'pulp-server', 'python-pulp-streamer', 'pulp-puppet-plugins',
28
+ 'python-pulp-rpm-common', 'python-pulp-common',
29
+ 'pulp-selinux', 'python-pulp-oid_validation',
30
+ 'python-pulp-puppet-common', 'python-pulp-repoauth',
31
+ 'pulp-rpm-plugins', 'python-blinker', 'python-celery',
32
+ 'python-django', 'python-isodate', 'python-ldap',
33
+ 'python-mongoengine', 'python-nectar', 'python-oauth2',
34
+ 'python-pymongo'
35
+ ]
36
+ end
37
+
38
+ def data_dir_removal_cmds
39
+ pulp_data_dirs.collect { |dir| "rm -rf #{dir}" }
40
+ end
41
+
42
+ def ask_to_proceed(rm_cmds)
43
+ question = "\nWARNING: All pulp2 packages will be removed with the following commands:\n" \
44
+ "\n# yum remove #{pulp_packages.join(' ')}" \
45
+ "\n# yum remove rh-mongodb34-*" \
46
+ "\n\nAll pulp2 data will be removed.\n"
47
+ question += rm_cmds.collect { |cmd| "\n# #{cmd}" }.join
48
+ question += "\n\nDo you want to proceed?"
49
+ answer = ask_decision(question, actions_msg: 'y(yes), q(quit)')
50
+ abort! if answer != :yes
51
+ end
52
+
53
+ def run
54
+ rm_cmds = data_dir_removal_cmds
55
+ ask_to_proceed(rm_cmds)
56
+
57
+ remove_pulp
58
+
59
+ remove_mongo
60
+
61
+ delete_pulp_data(rm_cmds)
62
+ end
63
+
64
+ def remove_pulp
65
+ with_spinner('Removing pulp2 packages') do
66
+ packages_action(:remove, pulp_packages, :assumeyes => true)
67
+ end
68
+ end
69
+
70
+ def remove_mongo
71
+ with_spinner('Removing mongo packages') do
72
+ packages_action(:remove, ['rh-mongodb34-*'], :assumeyes => true)
73
+ end
74
+ end
75
+
76
+ def delete_pulp_data(rm_cmds)
77
+ with_spinner('Deleting pulp2 data directories') do |spinner|
78
+ rm_cmds.each do |cmd|
79
+ if File.directory?(cmd.split[2])
80
+ execute!(cmd)
81
+ end
82
+ end
83
+ spinner.update('Done deleting pulp2 data directories')
84
+ end
85
+ end
86
+ end
87
+ end
@@ -18,7 +18,6 @@ module Procedures
18
18
  puts "\n#{action_noun} the following service(s):"
19
19
  services = feature(:service).filtered_services(options)
20
20
  print_services(services)
21
-
22
21
  with_spinner('') do |spinner|
23
22
  feature(:service).handle_services(spinner, action, options)
24
23
  end
@@ -31,7 +30,7 @@ module Procedures
31
30
  private
32
31
 
33
32
  def print_services(services)
34
- puts services.map(&:to_s).join(', ')
33
+ puts services.values.flatten(1).join(', ')
35
34
  end
36
35
  end
37
36
  end
@@ -9,6 +9,7 @@ module Procedures::Service
9
9
 
10
10
  def run
11
11
  services = feature(:service).filtered_services(common_options)
12
+ services = services.values.flatten(1)
12
13
  unit_files = unit_files_list(services)
13
14
  puts unit_files + "\n"
14
15
  puts 'All services listed'
@@ -16,12 +17,22 @@ module Procedures::Service
16
17
 
17
18
  def unit_files_list(services)
18
19
  if systemd_installed?
19
- regex = services.map { |service| "^#{service.name}.service" }.join('\|')
20
- execute("systemctl list-unit-files | grep '#{regex}'")
20
+ execute("systemctl list-unit-files --type=service | \
21
+ grep '#{build_regex_for_services(services)}'")
21
22
  else
22
23
  regex = services.map { |service| "^#{service.name} " }.join('\|')
23
24
  execute("chkconfig --list 2>&1 | grep '#{regex}'")
24
25
  end
25
26
  end
27
+
28
+ def build_regex_for_services(services)
29
+ services.map do |service|
30
+ if service.respond_to?(:instance_parent_unit) && service.instance_parent_unit
31
+ "^#{service.instance_parent_unit}.service"
32
+ else
33
+ "^#{service.name}.service"
34
+ end
35
+ end.join('\|')
36
+ end
26
37
  end
27
38
  end
@@ -94,6 +94,8 @@ module ForemanMaintain::Scenarios
94
94
  Procedures::Backup::Snapshot::MountPulp => :skip)
95
95
  context.map(:tar_volume_size,
96
96
  Procedures::Backup::Pulp => :tar_volume_size)
97
+ context.map(:include_db_dumps,
98
+ Procedures::Backup::Online::SafetyConfirmation => :include_db_dumps)
97
99
  end
98
100
  # rubocop:enable Metrics/MethodLength
99
101
 
@@ -12,6 +12,8 @@ module ForemanMaintain::Scenarios
12
12
  enable_and_start_services
13
13
  add_step(Procedures::Content::Prepare)
14
14
  disable_and_stop_services
15
+ elsif !feature(:satellite)
16
+ add_step(Procedures::Content::Prepare)
15
17
  end
16
18
  end
17
19
 
@@ -20,16 +22,16 @@ module ForemanMaintain::Scenarios
20
22
  def enable_and_start_services
21
23
  add_step(Procedures::Service::Start)
22
24
  add_step(Procedures::Service::Enable.
23
- new(:only => feature(:pulpcore).pulpcore_migration_services))
25
+ new(:only => Features::Pulpcore.pulpcore_migration_services))
24
26
  add_step(Procedures::Service::Start.
25
- new(:only => feature(:pulpcore).pulpcore_migration_services))
27
+ new(:only => Features::Pulpcore.pulpcore_migration_services))
26
28
  end
27
29
 
28
30
  def disable_and_stop_services
29
31
  add_step(Procedures::Service::Stop.
30
- new(:only => feature(:pulpcore).pulpcore_migration_services))
32
+ new(:only => Features::Pulpcore.pulpcore_migration_services))
31
33
  add_step(Procedures::Service::Disable.
32
- new(:only => feature(:pulpcore).pulpcore_migration_services))
34
+ new(:only => Features::Pulpcore.pulpcore_migration_services))
33
35
  end
34
36
  end
35
37
 
@@ -57,7 +59,7 @@ module ForemanMaintain::Scenarios
57
59
  end
58
60
 
59
61
  def compose
60
- if feature(:satellite) && feature(:satellite).at_least_version?('6.9')
62
+ if !feature(:satellite) || feature(:satellite).at_least_version?('6.9')
61
63
  add_step(Procedures::Content::PrepareAbort)
62
64
  end
63
65
  end
@@ -71,10 +73,40 @@ module ForemanMaintain::Scenarios
71
73
  end
72
74
 
73
75
  def compose
74
- if feature(:satellite) && feature(:satellite).at_least_version?('6.9')
76
+ if !feature(:satellite) || feature(:satellite).at_least_version?('6.9')
75
77
  add_step(Procedures::Content::MigrationStats)
76
78
  end
77
79
  end
78
80
  end
81
+
82
+ class MigrationReset < ForemanMaintain::Scenario
83
+ metadata do
84
+ label :content_migration_reset
85
+ description 'Reset the Pulp 2 to Pulp 3 migration data (pre-switchover)'
86
+ manual_detection
87
+ end
88
+
89
+ def compose
90
+ if feature(:satellite) && feature(:satellite).at_least_version?('6.9')
91
+ enable_and_start_services
92
+ add_step(Procedures::Content::MigrationReset)
93
+ disable_and_stop_services
94
+ elsif !feature(:satellite)
95
+ add_step(Procedures::Content::MigrationReset)
96
+ end
97
+ end
98
+ end
99
+
100
+ class RemovePulp2 < ForemanMaintain::Scenario
101
+ metadata do
102
+ label :content_remove_pulp2
103
+ description 'Remove Pulp2 and mongodb packages and data'
104
+ manual_detection
105
+ end
106
+
107
+ def compose
108
+ add_step_with_context(Procedures::Pulp::Remove)
109
+ end
110
+ end
79
111
  end
80
112
  end
@@ -103,7 +103,7 @@ module ForemanMaintain::Scenarios
103
103
 
104
104
  class RestoreRescue < ForemanMaintain::Scenario
105
105
  metadata do
106
- description 'Resuce Restore backup'
106
+ description 'Rescue Restore backup'
107
107
  manual_detection
108
108
  end
109
109
 
@@ -21,6 +21,7 @@ module ForemanMaintain
21
21
  require 'foreman_maintain/concerns/base_database'
22
22
  require 'foreman_maintain/concerns/directory_marker'
23
23
  require 'foreman_maintain/concerns/downstream'
24
+ require 'foreman_maintain/concerns/primary_checks'
24
25
  require 'foreman_maintain/top_level_modules'
25
26
  require 'foreman_maintain/yaml_storage'
26
27
  require 'foreman_maintain/config'
@@ -41,6 +42,7 @@ module ForemanMaintain
41
42
  require 'foreman_maintain/error'
42
43
 
43
44
  class << self
45
+ include ForemanMaintain::Concerns::PrimaryChecks
44
46
  attr_accessor :config, :logger
45
47
 
46
48
  LOGGER_LEVEL_MAPPING = {
@@ -27,9 +27,8 @@ module ForemanMaintain
27
27
  subcommand 'content', 'Content related commands', ContentCommand
28
28
  subcommand 'maintenance-mode', 'Control maintenance-mode for application',
29
29
  MaintenanceModeCommand
30
- if ::Scenarios.const_defined?('Satellite_6_10') &&
31
- ForemanMaintain.detector.feature('satellite') &&
32
- ForemanMaintain.detector.feature('satellite').current_minor_version == '6.9'
30
+ if ForemanMaintain.detector.feature(:satellite) &&
31
+ ForemanMaintain.detector.feature(:satellite).current_minor_version == '6.9'
33
32
  subcommand 'prep-6.10-upgrade', 'Preparations for the Satellite 6.10 upgrade' do
34
33
  def execute
35
34
  run_scenarios_and_exit(Scenarios::Prep610Upgrade.new)
@@ -27,6 +27,18 @@ module ForemanMaintain
27
27
  run_scenarios_and_exit(Scenarios::Content::MigrationStats.new)
28
28
  end
29
29
  end
30
+
31
+ subcommand 'migration-reset', 'Reset the Pulp 2 to Pulp 3 migration data (pre-switchover)' do
32
+ def execute
33
+ run_scenarios_and_exit(Scenarios::Content::MigrationReset.new)
34
+ end
35
+ end
36
+
37
+ subcommand 'remove-pulp2', 'Remove pulp2 and mongodb packages and data' do
38
+ def execute
39
+ run_scenarios_and_exit(Scenarios::Content::RemovePulp2.new)
40
+ end
41
+ end
30
42
  end
31
43
  end
32
44
  end
@@ -56,6 +56,7 @@ module ForemanMaintain
56
56
  disable_self_upgrade_option
57
57
 
58
58
  def execute
59
+ ForemanMaintain.validate_downstream_packages
59
60
  ForemanMaintain.perform_self_upgrade unless disable_self_upgrade?
60
61
  print_versions(UpgradeRunner.available_targets)
61
62
  end
@@ -67,6 +68,7 @@ module ForemanMaintain
67
68
  disable_self_upgrade_option
68
69
 
69
70
  def execute
71
+ ForemanMaintain.validate_downstream_packages
70
72
  ForemanMaintain.perform_self_upgrade unless disable_self_upgrade?
71
73
  upgrade_runner.run_phase(:pre_upgrade_checks)
72
74
  exit upgrade_runner.exit_code
@@ -86,6 +88,7 @@ module ForemanMaintain
86
88
  end
87
89
 
88
90
  def execute
91
+ ForemanMaintain.validate_downstream_packages
89
92
  ForemanMaintain.perform_self_upgrade unless disable_self_upgrade?
90
93
  if phase
91
94
  upgrade_runner.run_phase(phase.to_sym)
@@ -119,6 +119,7 @@ module ForemanMaintain
119
119
  SQL
120
120
  result = query(sql)
121
121
  return false if result.nil? || (result && result.empty?)
122
+
122
123
  result.first['exists'].eql?('t')
123
124
  end
124
125
 
@@ -161,6 +162,16 @@ module ForemanMaintain
161
162
  end
162
163
  end
163
164
 
165
+ def psql_cmd_available?
166
+ exit_status, _output = execute_with_status('which psql')
167
+ exit_status == 0
168
+ end
169
+
170
+ def raise_psql_missing_error
171
+ raise Error::Fail, 'The psql command not found.'\
172
+ ' Make sure system has psql utility installed.'
173
+ end
174
+
164
175
  private
165
176
 
166
177
  def base_command(config, command = 'psql')
@@ -0,0 +1,23 @@
1
+ module ForemanMaintain
2
+ module Concerns
3
+ module PrimaryChecks
4
+ def validate_downstream_packages
5
+ return unless detector.feature(:installer) && detector.feature(:installer).with_scenarios?
6
+ if (package = package_name) && !package_manager.installed?(package)
7
+ raise ForemanMaintain::Error::Fail,
8
+ "Error: Important rpm package #{package} is not installed!"\
9
+ "\nInstall #{package} rpm to ensure system consistency."
10
+ end
11
+ end
12
+
13
+ def package_name
14
+ installed_scenario = detector.feature(:installer).last_scenario
15
+ if installed_scenario == 'satellite'
16
+ 'satellite'
17
+ elsif installed_scenario == 'capsule'
18
+ 'satellite-capsule'
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -8,6 +8,7 @@ module ForemanMaintain::PackageManager
8
8
  private
9
9
 
10
10
  def dnf_action(action, packages, with_status: false, assumeyes: false)
11
+ packages = [packages].flatten(1)
11
12
  yum_options = []
12
13
  yum_options << '-y' if assumeyes
13
14
  if with_status
@@ -67,6 +67,7 @@ module ForemanMaintain
67
67
  end
68
68
  end
69
69
 
70
+ attr_accessor :select_option_counter
70
71
  attr_reader :last_line, :max_length
71
72
 
72
73
  def initialize(stdout = STDOUT, stdin = STDIN, options = {})
@@ -81,6 +82,7 @@ module ForemanMaintain
81
82
  @spinner = Spinner.new(self)
82
83
  @spinner.start_spinner if @stdout.tty?
83
84
  @last_line = ''
85
+ @select_option_counter = 0
84
86
  end
85
87
 
86
88
  def before_scenario_starts(scenario)
@@ -212,8 +214,10 @@ module ForemanMaintain
212
214
  # rubocop:disable Metrics/MethodLength
213
215
  def ask_to_select(message, steps, run_strategy)
214
216
  if assumeyes?
215
- puts('(assuming first option)')
216
- return steps.first
217
+ step = steps[@select_option_counter]
218
+ @select_option_counter += 1
219
+ puts("(assuming option #{@select_option_counter})")
220
+ return step
217
221
  end
218
222
 
219
223
  until_valid_decision do
@@ -18,6 +18,7 @@ module ForemanMaintain
18
18
  @last_scenario = nil
19
19
  @last_scenario_continuation_confirmed = false
20
20
  @exit_code = 0
21
+ @procedure_step_counter = 0
21
22
  end
22
23
 
23
24
  def quit?
@@ -143,14 +144,16 @@ module ForemanMaintain
143
144
 
144
145
  # rubocop:disable Metrics/MethodLength
145
146
  def ask_about_offered_steps(step, scenario)
146
- if assumeyes? && rerun_check?(step)
147
- @reporter.puts 'Check still failing after attempt to fix. Skipping'
148
- return :no
149
- end
150
147
  if step.next_steps && !step.next_steps.empty?
151
148
  @last_decision_step = step
149
+ @procedure_step_counter += 1
152
150
  steps = step.next_steps.map(&:ensure_instance)
153
-
151
+ if assumeyes? && @procedure_step_counter > steps.length
152
+ @procedure_step_counter = 0
153
+ @reporter.select_option_counter = 0
154
+ @reporter.puts 'Check still failing after attempt to fix. Skipping'
155
+ return :no
156
+ end
154
157
  decision = @reporter.on_next_steps(steps, scenario.run_strategy)
155
158
  case decision
156
159
  when :quit
@@ -163,7 +163,7 @@ module ForemanMaintain
163
163
  def validate_hostname?
164
164
  # make sure that the system hostname is the same as the backup
165
165
  config_tarball = file_map[:config_files][:path]
166
- tar_cmd = "tar zxf #{config_tarball} etc/httpd/conf/httpd.conf --to-stdout"
166
+ tar_cmd = "tar zxf #{config_tarball} etc/httpd/conf/httpd.conf --to-stdout --occurrence=1"
167
167
  status, httpd_config = execute_with_status(tar_cmd)
168
168
 
169
169
  # Incremental backups sometimes don't include httpd.conf. Since a "base" backup
@@ -22,6 +22,10 @@ module ForemanMaintain
22
22
  convert_kb_to_mb(execute!("df #{dir}|awk {'print $4'}|tail -1").to_i)
23
23
  end
24
24
 
25
+ def space_used_in_percent
26
+ execute!("df #{dir}|awk {'print $5'}|tail -1").to_i
27
+ end
28
+
25
29
  private
26
30
 
27
31
  # In fio command, --direct option bypass the cache page
@@ -1,16 +1,17 @@
1
1
  module ForemanMaintain::Utils
2
2
  module Service
3
3
  class Systemd < Abstract
4
+ attr_reader :instance_parent_unit
4
5
  def initialize(name, priority, options = {})
5
6
  super
6
7
  @sys = SystemHelpers.new
8
+ @instance_parent_unit = options.fetch(:instance_parent_unit, nil)
7
9
  end
8
10
 
9
11
  def command(action, options = {})
10
12
  do_wait = options.fetch(:wait, true) # wait for service to start
11
13
  all = @options.fetch(:all, false)
12
14
  skip_enablement = @options.fetch(:skip_enablement, false)
13
-
14
15
  if skip_enablement && %w[enable disable].include?(action)
15
16
  return skip_enablement_message(action, @name)
16
17
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanMaintain
2
- VERSION = '0.7.0'.freeze
2
+ VERSION = '0.7.6'.freeze
3
3
  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.7.0
4
+ version: 0.7.6
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: 2020-12-02 00:00:00.000000000 Z
11
+ date: 2021-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clamp
@@ -125,6 +125,7 @@ files:
125
125
  - definitions/checks/check_hotfix_installed.rb
126
126
  - definitions/checks/check_tmout.rb
127
127
  - definitions/checks/disk/available_space.rb
128
+ - definitions/checks/disk/available_space_candlepin.rb
128
129
  - definitions/checks/disk/performance.rb
129
130
  - definitions/checks/env_proxy.rb
130
131
  - definitions/checks/foreman/check_checkpoint_segments.rb
@@ -170,6 +171,7 @@ files:
170
171
  - definitions/features/dynflow_sidekiq.rb
171
172
  - definitions/features/foreman_1_11_x.rb
172
173
  - definitions/features/foreman_1_7_x.rb
174
+ - definitions/features/foreman_cockpit.rb
173
175
  - definitions/features/foreman_database.rb
174
176
  - definitions/features/foreman_openscap.rb
175
177
  - definitions/features/foreman_proxy.rb
@@ -220,6 +222,7 @@ files:
220
222
  - definitions/procedures/backup/snapshot/mount_pulpcore_db.rb
221
223
  - definitions/procedures/backup/snapshot/prepare_mount.rb
222
224
  - definitions/procedures/candlepin/delete_orphaned_records_from_env_content.rb
225
+ - definitions/procedures/content/migration_reset.rb
223
226
  - definitions/procedures/content/migration_stats.rb
224
227
  - definitions/procedures/content/prepare.rb
225
228
  - definitions/procedures/content/prepare_abort.rb
@@ -257,6 +260,7 @@ files:
257
260
  - definitions/procedures/passenger_recycler.rb
258
261
  - definitions/procedures/prep_6_10_upgrade.rb
259
262
  - definitions/procedures/pulp/migrate.rb
263
+ - definitions/procedures/pulp/remove.rb
260
264
  - definitions/procedures/pulpcore/migrate.rb
261
265
  - definitions/procedures/puppet/delete_empty_ca_cert_request_files.rb
262
266
  - definitions/procedures/remote_execution/remove_existing_settingsd.rb
@@ -346,6 +350,7 @@ files:
346
350
  - lib/foreman_maintain/concerns/hammer.rb
347
351
  - lib/foreman_maintain/concerns/logger.rb
348
352
  - lib/foreman_maintain/concerns/metadata.rb
353
+ - lib/foreman_maintain/concerns/primary_checks.rb
349
354
  - lib/foreman_maintain/concerns/reporter.rb
350
355
  - lib/foreman_maintain/concerns/scenario_metadata.rb
351
356
  - lib/foreman_maintain/concerns/system_helpers.rb