foreman_maintain 0.3.6 → 0.4.1

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 (62) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +30 -16
  3. data/bin/passenger-recycler +22 -22
  4. data/config/foreman_maintain.yml.example +7 -0
  5. data/config/foreman_maintain.yml.packaging +4 -0
  6. data/definitions/checks/candlepin/db_up.rb +1 -1
  7. data/definitions/checks/check_hotfix_installed.rb +90 -0
  8. data/definitions/checks/check_tmout.rb +20 -0
  9. data/definitions/checks/disk/performance.rb +1 -11
  10. data/definitions/checks/maintenance_mode/check_consistency.rb +62 -0
  11. data/definitions/checks/puppet/verify_no_empty_cacert_requests.rb +24 -0
  12. data/definitions/checks/repositories/check_upstream_repository.rb +22 -0
  13. data/definitions/checks/repositories/validate.rb +2 -2
  14. data/definitions/features/cron.rb +29 -0
  15. data/definitions/features/downstream.rb +3 -3
  16. data/definitions/features/foreman_1_7_x.rb +0 -35
  17. data/definitions/features/foreman_database.rb +0 -6
  18. data/definitions/features/iptables.rb +58 -0
  19. data/definitions/features/mongo.rb +7 -9
  20. data/definitions/features/pulp.rb +2 -4
  21. data/definitions/features/puppet_server.rb +45 -4
  22. data/definitions/features/service.rb +33 -2
  23. data/definitions/features/sync_plans.rb +50 -25
  24. data/definitions/features/system_repos.rb +50 -0
  25. data/definitions/features/tar.rb +1 -0
  26. data/definitions/procedures/backup/config_files.rb +1 -4
  27. data/definitions/procedures/backup/offline/mongo.rb +1 -1
  28. data/definitions/procedures/backup/online/pg_global_objects.rb +5 -1
  29. data/definitions/procedures/backup/pulp.rb +6 -1
  30. data/definitions/procedures/backup/snapshot/logical_volume_confirmation.rb +2 -2
  31. data/definitions/procedures/backup/snapshot/mount_mongo.rb +14 -6
  32. data/definitions/procedures/backup/snapshot/mount_pulp.rb +6 -4
  33. data/definitions/procedures/crond/start.rb +19 -0
  34. data/definitions/procedures/crond/stop.rb +18 -0
  35. data/definitions/procedures/iptables/add_maintenance_mode_chain.rb +15 -0
  36. data/definitions/procedures/iptables/remove_maintenance_mode_chain.rb +15 -0
  37. data/definitions/procedures/maintenance_mode/is_enabled.rb +16 -0
  38. data/definitions/procedures/passenger_recycler.rb +3 -2
  39. data/definitions/procedures/puppet/delete_empty_ca_cert_request_files.rb +37 -0
  40. data/definitions/procedures/repositories/disable.rb +13 -0
  41. data/definitions/procedures/service/base.rb +3 -2
  42. data/definitions/procedures/sync_plans/disable.rb +2 -2
  43. data/definitions/procedures/sync_plans/enable.rb +1 -1
  44. data/definitions/scenarios/backup.rb +10 -10
  45. data/definitions/scenarios/maintenance_mode.rb +53 -0
  46. data/lib/foreman_maintain.rb +1 -0
  47. data/lib/foreman_maintain/cli.rb +3 -0
  48. data/lib/foreman_maintain/cli/base.rb +17 -0
  49. data/lib/foreman_maintain/cli/maintenance_mode_command.rb +50 -0
  50. data/lib/foreman_maintain/concerns/directory_marker.rb +35 -0
  51. data/lib/foreman_maintain/concerns/system_service.rb +5 -1
  52. data/lib/foreman_maintain/config.rb +12 -1
  53. data/lib/foreman_maintain/param.rb +2 -1
  54. data/lib/foreman_maintain/reporter/cli_reporter.rb +1 -1
  55. data/lib/foreman_maintain/utils/command_runner.rb +1 -1
  56. data/lib/foreman_maintain/utils/service.rb +4 -0
  57. data/lib/foreman_maintain/utils/service/systemd.rb +1 -1
  58. data/lib/foreman_maintain/version.rb +1 -1
  59. metadata +21 -6
  60. data/definitions/features/puppet.rb +0 -23
  61. data/definitions/procedures/maintenance_mode/disable.rb +0 -13
  62. data/definitions/procedures/maintenance_mode/enable.rb +0 -13
@@ -0,0 +1,50 @@
1
+ class Features::SystemRepos < ForemanMaintain::Feature
2
+ metadata do
3
+ label :system_repos
4
+ description 'Feature for operations on yum repositories of system'
5
+ end
6
+
7
+ def upstream_repos
8
+ repositories = {}
9
+ enabled_repos_hash.each do |repo, url|
10
+ upstream_repo_urls.each do |regex|
11
+ repositories[repo] = url if url =~ regex
12
+ end
13
+ end
14
+ repositories
15
+ end
16
+
17
+ def enabled_repos_hash
18
+ repos = execute("yum repolist enabled -d 6 -e 0 2> /dev/null | grep -E 'Repo-id|Repo-baseurl'")
19
+ return {} if repos.empty?
20
+
21
+ Hash[*repos.delete!(' ').split("\n")]
22
+ end
23
+
24
+ def upstream_repos_ids
25
+ trim_repoids(upstream_repos.keys)
26
+ end
27
+
28
+ def disable_repos(repo_ids)
29
+ execute!("yum-config-manager --disable #{repo_ids.join(',')}")
30
+ end
31
+
32
+ private
33
+
34
+ def trim_repoids(repos)
35
+ repos.map { |r| r.gsub(%r{Repo-id:|\/+\w*}, '') }
36
+ end
37
+
38
+ def upstream_repo_urls
39
+ repo_urls = { :Foreman => %r{yum.theforeman.org\/},
40
+ :Katello => %r{fedorapeople.org\/groups\/katello\/releases\/yum\/[\/|\w|.]*} }
41
+ [/#{repo_urls[:Foreman]}+releases/,
42
+ /#{repo_urls[:Foreman]}+plugins/,
43
+ /#{repo_urls[:Katello]}+katello/,
44
+ /#{repo_urls[:Katello]}+client/,
45
+ /#{repo_urls[:Katello]}+candlepin/,
46
+ /#{repo_urls[:Katello]}+pulp/,
47
+ %r{yum.puppetlabs.com\/el\/[\w|\/|\.]*\/x86_64},
48
+ %r{repos.fedorapeople.org\/repos\/pulp\/[\/|\w|.]*\/x86_64}]
49
+ end
50
+ end
@@ -56,6 +56,7 @@ class Features::Tar < ForemanMaintain::Feature
56
56
  tar_command << options.fetch(:files, '*')
57
57
  end
58
58
 
59
+ logger.debug("Invoking tar from #{FileUtils.pwd}")
59
60
  execute!(tar_command.join(' '))
60
61
  end
61
62
  # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
@@ -11,8 +11,6 @@ module Procedures::Backup
11
11
  param :backup_dir, 'Directory where to backup to', :required => true
12
12
  param :proxy_features, 'List of proxy features to backup (default: all)',
13
13
  :array => true, :default => ['all']
14
- param :ignore_changed_files, 'Should packing tar ignore changed files',
15
- :flag => true, :default => false
16
14
  end
17
15
 
18
16
  def run
@@ -20,10 +18,9 @@ module Procedures::Backup
20
18
  increments = File.join(@backup_dir, '.config.snar')
21
19
  with_spinner('Collecting config files to backup') do
22
20
  configs = config_files.join(' ')
23
- statuses = @ignore_changed_files ? [0, 1] : [0]
24
21
  execute!("tar --selinux --create --gzip --file=#{tarball} " \
25
22
  "--listed-incremental=#{increments} --ignore-failed-read " \
26
- "#{configs}", :valid_exit_statuses => statuses)
23
+ "#{configs}")
27
24
  end
28
25
  end
29
26
 
@@ -26,7 +26,7 @@ module Procedures::Backup
26
26
  def data_dir
27
27
  return nil if @mount_dir.nil?
28
28
  mount_point = File.join(@mount_dir, 'mongodb')
29
- dir = feature(:mongo).find_base_directory(mount_point)
29
+ dir = feature(:mongo).find_marked_directory(mount_point)
30
30
  fail!("Snapshot of Mongo DB was not found mounted in #{mount_point}") if dir.nil?
31
31
  dir
32
32
  end
@@ -14,7 +14,11 @@ module Procedures::Backup
14
14
 
15
15
  def run
16
16
  if feature(:instance).postgresql_local?
17
- local_db = feature(:foreman_database).local? ? :foreman_database : :candlepin_database
17
+ local_db = if feature(:instance).database_local?(:foreman_database)
18
+ :foreman_database
19
+ else
20
+ :candlepin_database
21
+ end
18
22
  feature(local_db).backup_global_objects(File.join(@backup_dir, 'pg_globals.dump'))
19
23
  else
20
24
  skip 'Backup of global objects is not supported for remote databases.'
@@ -41,7 +41,12 @@ module Procedures::Backup
41
41
  def pulp_dir
42
42
  return feature(:pulp).data_dir if @mount_dir.nil?
43
43
  mount_point = File.join(@mount_dir, 'pulp')
44
- feature(:pulp).find_base_directory(mount_point)
44
+ dir = feature(:pulp).find_marked_directory(mount_point)
45
+ unless dir
46
+ raise ForemanMaintain::Error::Fail,
47
+ "Pulp base directory not found in the mount point (#{mount_point})"
48
+ end
49
+ dir
45
50
  end
46
51
 
47
52
  def ensure_dir_unchanged
@@ -37,9 +37,9 @@ module Procedures::Backup
37
37
  '*** It is highly suggested to backup to a different logical volume than' \
38
38
  " the #{shared_lv.join(', ')} database.\n" \
39
39
  '*** If you would like to continue, the snapshot size will be required to be at least' \
40
- "the size of the actual #{shared_lv.join(', ')} database.\n" \
40
+ " the size of the actual #{shared_lv.join(', ')} database.\n" \
41
41
  "*** You can skip this confirmation with the '-y' flag.\n\n" \
42
- 'Do you want to proceed(y/n)?', 'y(yes), q(quit)')
42
+ 'Do you want to proceed?', 'y(yes), q(quit)')
43
43
  abort! unless answer == :yes
44
44
  end
45
45
  end
@@ -17,12 +17,7 @@ module Procedures::Backup
17
17
 
18
18
  def run
19
19
  if feature(:mongo).local?
20
- with_spinner('Creating snapshot of Mongo DB') do |spinner|
21
- lv_info = get_lv_info(feature(:mongo).data_dir)
22
- create_lv_snapshot('mongodb-snap', @block_size, lv_info[0])
23
- spinner.update("Mounting snapshot of Mongo DB on #{mount_location('mongodb')}")
24
- mount_snapshot('mongodb', lv_info[1])
25
- end
20
+ mount_local
26
21
  else
27
22
  puts 'LV snapshots are not supported for remote databases. Doing dump instead...'
28
23
  with_spinner('Getting dump of Mongo DB') do
@@ -30,6 +25,19 @@ module Procedures::Backup
30
25
  end
31
26
  end
32
27
  end
28
+
29
+ private
30
+
31
+ def mount_local
32
+ with_spinner('Creating snapshot of Mongo DB') do |spinner|
33
+ feature(:mongo).with_marked_directory(feature(:mongo).data_dir) do
34
+ lv_info = get_lv_info(feature(:mongo).data_dir)
35
+ create_lv_snapshot('mongodb-snap', @block_size, lv_info[0])
36
+ spinner.update("Mounting snapshot of Mongo DB on #{mount_location('mongodb')}")
37
+ mount_snapshot('mongodb', lv_info[1])
38
+ end
39
+ end
40
+ end
33
41
  end
34
42
  end
35
43
  end
@@ -13,10 +13,12 @@ module Procedures::Backup
13
13
  def run
14
14
  skip if @skip
15
15
  with_spinner('Creating snapshot of Pulp') do |spinner|
16
- lv_info = get_lv_info(feature(:pulp).data_dir)
17
- create_lv_snapshot('pulp-snap', @block_size, lv_info[0])
18
- spinner.update("Mounting snapshot of Pulp on #{mount_location('pulp')}")
19
- mount_snapshot('pulp', lv_info[1])
16
+ feature(:pulp).with_marked_directory(feature(:pulp).data_dir) do
17
+ lv_info = get_lv_info(feature(:pulp).data_dir)
18
+ create_lv_snapshot('pulp-snap', @block_size, lv_info[0])
19
+ spinner.update("Mounting snapshot of Pulp on #{mount_location('pulp')}")
20
+ mount_snapshot('pulp', lv_info[1])
21
+ end
20
22
  end
21
23
  end
22
24
  end
@@ -0,0 +1,19 @@
1
+ require 'procedures/service/base'
2
+
3
+ module Procedures::Crond
4
+ class Start < Procedures::Service::Base
5
+ metadata do
6
+ description 'Start cron service'
7
+
8
+ for_feature :cron
9
+ tags :post_migrations, :maintenance_mode_off
10
+
11
+ after :iptables_remove_maintenance_mode_chain
12
+ advanced_run false
13
+ end
14
+
15
+ def run
16
+ run_service_action('start', :only => [feature(:cron).service_name])
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ require 'procedures/service/base'
2
+
3
+ module Procedures::Crond
4
+ class Stop < Procedures::Service::Base
5
+ metadata do
6
+ description 'Stop cron service'
7
+ tags :pre_migrations, :maintenance_mode_on
8
+ for_feature :cron
9
+
10
+ after :iptables_add_maintenance_mode_chain
11
+ advanced_run false
12
+ end
13
+
14
+ def run
15
+ run_service_action('stop', :only => [feature(:cron).service_name])
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ module Procedures::Iptables
2
+ class AddMaintenanceModeChain < ForemanMaintain::Procedure
3
+ metadata do
4
+ label :iptables_add_maintenance_mode_chain
5
+ for_feature :iptables
6
+ description 'Add maintenance_mode chain to iptables'
7
+ tags :pre_migrations, :maintenance_mode_on
8
+ after :sync_plans_disable
9
+ end
10
+
11
+ def run
12
+ feature(:iptables).add_maintenance_mode_chain
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module Procedures::Iptables
2
+ class RemoveMaintenanceModeChain < ForemanMaintain::Procedure
3
+ metadata do
4
+ label :iptables_remove_maintenance_mode_chain
5
+ for_feature :iptables
6
+ description 'Remove maintenance_mode chain from iptables'
7
+ tags :post_migrations, :maintenance_mode_off
8
+ after :sync_plans_enable
9
+ end
10
+
11
+ def run
12
+ feature(:iptables).remove_maintenance_mode_chain
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ module Procedures::MaintenanceMode
2
+ class IsEnabled < ForemanMaintain::Procedure
3
+ metadata do
4
+ description 'Showing status code for maintenance_mode'
5
+ for_feature :iptables
6
+ advanced_run false
7
+ end
8
+
9
+ attr_reader :status_code
10
+
11
+ def run
12
+ @status_code = feature(:iptables).maintenance_mode_chain_exist? ? 1 : 0
13
+ puts "Maintenance mode is #{@status_code == 0 ? 'Off' : 'On'}"
14
+ end
15
+ end
16
+ end
@@ -3,11 +3,12 @@ class Procedures::PassengerRecycler < ForemanMaintain::Procedure
3
3
  description 'Perform Passenger memory recycling'
4
4
 
5
5
  confine do
6
- execute?('which scl') && execute?('which passenger-recycler')
6
+ execute?('which passenger-recycler')
7
7
  end
8
8
  end
9
9
 
10
10
  def run
11
- execute!('scl enable tfm -- ruby passenger-recycler')
11
+ passenger_recycler_path = execute('which passenger-recycler')
12
+ execute!(passenger_recycler_path)
12
13
  end
13
14
  end
@@ -0,0 +1,37 @@
1
+ module Procedures::Puppet
2
+ class DeleteEmptyCaCertRequestFiles < ForemanMaintain::Procedure
3
+ metadata do
4
+ description 'Delete empty CA cert request files'
5
+ confine do
6
+ feature(:puppet_server)
7
+ end
8
+ end
9
+
10
+ def run
11
+ cacert_dir_path = feature(:puppet_server).cacert_requests_directory
12
+ if feature(:puppet_server).cacert_requests_dir_exists?
13
+ files = feature(:puppet_server).find_empty_cacert_request_files
14
+ if files.empty?
15
+ puts "No empty file(s) under #{cacert_dir_path}"
16
+ else
17
+ print_files_details(files, cacert_dir_path)
18
+ with_spinner('Deleting empty CA cert request files') do |spinner|
19
+ feature(:puppet_server).delete_empty_cacert_files
20
+ spinner.update 'Done with deleting empty cert request files'
21
+ end
22
+ end
23
+ else
24
+ skip "#{cacert_dir_path} directory not found"
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def print_files_details(files, cacert_dir_path)
31
+ puts "Empty CA cert file(s) under #{cacert_dir_path}:"
32
+ files.each_with_index do |file_name, index|
33
+ puts "#{index + 1}. #{file_name}"
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,13 @@
1
+ module Procedures::Repositories
2
+ class Disable < ForemanMaintain::Procedure
3
+ metadata do
4
+ param :repos, 'List of repositories to disable'
5
+ description 'Disable repositories'
6
+ end
7
+ def run
8
+ with_spinner('Disabling repositories') do
9
+ feature(:system_repos).disable_repos(@repos)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -7,8 +7,9 @@ module Procedures
7
7
 
8
8
  def self.common_params(context)
9
9
  context.instance_eval do
10
- param :only, 'A comma-separated list of services to include', :array => true
10
+ param :only, 'A comma-separated list of services to run', :array => true
11
11
  param :exclude, 'A comma-separated list of services to skip', :array => true
12
+ param :include, 'A comma-separated list of services to include', :array => true
12
13
  end
13
14
  end
14
15
 
@@ -24,7 +25,7 @@ module Procedures
24
25
  end
25
26
 
26
27
  def common_options
27
- { :only => @only, :exclude => @exclude }
28
+ { :only => @only, :exclude => @exclude, :include => @include }
28
29
  end
29
30
 
30
31
  private
@@ -4,7 +4,7 @@ module Procedures::SyncPlans
4
4
  metadata do
5
5
  for_feature :sync_plans
6
6
  description 'disable active sync plans'
7
- tags :pre_migrations
7
+ tags :pre_migrations, :maintenance_mode_on
8
8
 
9
9
  confine do
10
10
  feature(:katello)
@@ -21,7 +21,7 @@ module Procedures::SyncPlans
21
21
  default_storage = ForemanMaintain.storage(:default)
22
22
  feature(:sync_plans).load_from_storage(default_storage)
23
23
  with_spinner('disabling sync plans') do |spinner|
24
- ids = feature(:sync_plans).sync_plan_ids_by_status(true)
24
+ ids = feature(:sync_plans).ids_by_status(true)
25
25
  feature(:sync_plans).make_disable(ids)
26
26
  spinner.update "Total #{ids.length} sync plans are now disabled."
27
27
  end
@@ -4,7 +4,7 @@ module Procedures::SyncPlans
4
4
  metadata do
5
5
  for_feature :sync_plans
6
6
  description 're-enable sync plans'
7
- tags :post_migrations
7
+ tags :post_migrations, :maintenance_mode_off
8
8
  before :disk_io
9
9
 
10
10
  confine do
@@ -19,6 +19,7 @@ module ForemanMaintain::Scenarios
19
19
  param :tar_volume_size, 'Size of tar volume (indicates splitting)'
20
20
  end
21
21
 
22
+ # rubocop:disable Metrics/MethodLength
22
23
  def compose
23
24
  check_valid_startegy
24
25
  safety_confirmation
@@ -26,6 +27,7 @@ module ForemanMaintain::Scenarios
26
27
  prepare_directory
27
28
  logical_volume_confirmation
28
29
  add_step_with_context(Procedures::Backup::Metadata)
30
+ add_step_with_context(Procedures::Backup::ConfigFiles)
29
31
 
30
32
  case strategy
31
33
  when :online
@@ -33,10 +35,11 @@ module ForemanMaintain::Scenarios
33
35
  when :offline
34
36
  add_offline_backup_steps
35
37
  when :snapshot
36
- add_snaphot_backup_steps
38
+ add_snapshot_backup_steps
37
39
  end
38
40
  add_step_with_context(Procedures::Backup::CompressData)
39
41
  end
42
+ # rubocop:enable Metrics/MethodLength
40
43
 
41
44
  # rubocop:disable Metrics/MethodLength
42
45
  def set_context_mapping
@@ -127,15 +130,14 @@ module ForemanMaintain::Scenarios
127
130
  def add_offline_backup_steps
128
131
  include_dumps if include_db_dumps?
129
132
  add_steps_with_context(
130
- Procedures::MaintenanceMode::Enable,
133
+ find_procedures(:maintenance_mode_on),
131
134
  Procedures::Service::Stop,
132
- Procedures::Backup::ConfigFiles,
133
135
  Procedures::Backup::Pulp,
134
136
  Procedures::Backup::Offline::Mongo,
135
137
  Procedures::Backup::Offline::CandlepinDB,
136
138
  Procedures::Backup::Offline::ForemanDB,
137
139
  Procedures::Service::Start,
138
- Procedures::MaintenanceMode::Disable
140
+ find_procedures(:maintenance_mode_off)
139
141
  )
140
142
  end
141
143
 
@@ -155,18 +157,17 @@ module ForemanMaintain::Scenarios
155
157
  end
156
158
 
157
159
  # rubocop:disable Metrics/MethodLength
158
- def add_snaphot_backup_steps
160
+ def add_snapshot_backup_steps
159
161
  add_steps_with_context(
160
162
  Procedures::Backup::Snapshot::PrepareMount,
161
- Procedures::MaintenanceMode::Enable,
163
+ find_procedures(:maintenance_mode_on),
162
164
  Procedures::Service::Stop,
163
- Procedures::Backup::ConfigFiles,
164
165
  Procedures::Backup::Snapshot::MountMongo,
165
166
  Procedures::Backup::Snapshot::MountPulp,
166
167
  Procedures::Backup::Snapshot::MountCandlepinDB,
167
168
  Procedures::Backup::Snapshot::MountForemanDB,
168
169
  Procedures::Service::Start,
169
- Procedures::MaintenanceMode::Disable,
170
+ find_procedures(:maintenance_mode_off),
170
171
  Procedures::Backup::Pulp
171
172
  )
172
173
  if feature(:instance).database_local?(:candlepin_database)
@@ -183,7 +184,6 @@ module ForemanMaintain::Scenarios
183
184
  # rubocop:enable Metrics/MethodLength
184
185
 
185
186
  def add_online_backup_steps
186
- add_step_with_context(Procedures::Backup::ConfigFiles, :ignore_changed_files => true)
187
187
  add_step_with_context(Procedures::Backup::Pulp, :ensure_unchanged => true)
188
188
  add_steps_with_context(
189
189
  Procedures::Backup::Online::Mongo,
@@ -219,7 +219,7 @@ module ForemanMaintain::Scenarios
219
219
 
220
220
  def compose
221
221
  add_step_with_context(Procedures::Service::Start) if strategy != :online
222
- add_step_with_context(Procedures::MaintenanceMode::Disable) if strategy != :online
222
+ add_steps_with_context(find_procedures(:maintenance_mode_off)) if strategy != :online
223
223
  add_step_with_context(Procedures::Backup::Snapshot::CleanMount) if strategy == :snapshot
224
224
  add_step_with_context(Procedures::Backup::Clean)
225
225
  end