foreman_maintain 0.1.6 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +48 -10
  3. data/bin/foreman-maintain-rotate-tar +18 -0
  4. data/definitions/checks/backup/certs_tar_exist.rb +24 -0
  5. data/definitions/checks/backup/directory_ready.rb +21 -0
  6. data/definitions/checks/candlepin/db_up.rb +29 -0
  7. data/definitions/checks/check_epel_repository.rb +21 -0
  8. data/definitions/checks/foreman/db_up.rb +29 -0
  9. data/definitions/checks/hammer_ping.rb +3 -1
  10. data/definitions/checks/mongo/db_up.rb +29 -0
  11. data/definitions/checks/mongo/tools_installed.rb +31 -0
  12. data/definitions/checks/repositories/validate.rb +0 -3
  13. data/definitions/checks/root_user.rb +12 -0
  14. data/definitions/features/candlepin.rb +16 -0
  15. data/definitions/features/candlepin_database.rb +3 -1
  16. data/definitions/features/downstream.rb +21 -22
  17. data/definitions/features/foreman_database.rb +2 -0
  18. data/definitions/features/foreman_proxy.rb +70 -7
  19. data/definitions/features/foreman_server.rb +29 -0
  20. data/definitions/features/foreman_tasks.rb +5 -1
  21. data/definitions/features/hammer.rb +158 -3
  22. data/definitions/features/installer.rb +106 -0
  23. data/definitions/features/instance.rb +39 -0
  24. data/definitions/features/katello.rb +43 -0
  25. data/definitions/features/mongo.rb +159 -0
  26. data/definitions/features/pulp.rb +30 -0
  27. data/definitions/features/puppet.rb +21 -0
  28. data/definitions/features/puppet_server.rb +2 -6
  29. data/definitions/features/service.rb +134 -0
  30. data/definitions/features/sync_plans.rb +1 -1
  31. data/definitions/features/tar.rb +69 -0
  32. data/definitions/procedures/backup/accessibility_confirmation.rb +14 -0
  33. data/definitions/procedures/backup/clean.rb +16 -0
  34. data/definitions/procedures/backup/compress_data.rb +26 -0
  35. data/definitions/procedures/backup/config_files.rb +36 -0
  36. data/definitions/procedures/backup/metadata.rb +56 -0
  37. data/definitions/procedures/backup/offline/candlepin_db.rb +57 -0
  38. data/definitions/procedures/backup/offline/foreman_db.rb +57 -0
  39. data/definitions/procedures/backup/offline/mongo.rb +56 -0
  40. data/definitions/procedures/backup/online/candlepin_db.rb +20 -0
  41. data/definitions/procedures/backup/online/foreman_db.rb +20 -0
  42. data/definitions/procedures/backup/online/mongo.rb +21 -0
  43. data/definitions/procedures/backup/online/pg_global_objects.rb +23 -0
  44. data/definitions/procedures/backup/online/safety_confirmation.rb +25 -0
  45. data/definitions/procedures/backup/prepare_directory.rb +29 -0
  46. data/definitions/procedures/backup/pulp.rb +68 -0
  47. data/definitions/procedures/backup/snapshot/clean_mount.rb +24 -0
  48. data/definitions/procedures/backup/snapshot/logical_volume_confirmation.rb +47 -0
  49. data/definitions/procedures/backup/snapshot/mount_base.rb +27 -0
  50. data/definitions/procedures/backup/snapshot/mount_candlepin_db.rb +48 -0
  51. data/definitions/procedures/backup/snapshot/mount_foreman_db.rb +48 -0
  52. data/definitions/procedures/backup/snapshot/mount_mongo.rb +35 -0
  53. data/definitions/procedures/backup/snapshot/mount_pulp.rb +24 -0
  54. data/definitions/procedures/backup/snapshot/prepare_mount.rb +16 -0
  55. data/definitions/procedures/foreman_tasks/fetch_tasks_status.rb +1 -0
  56. data/definitions/procedures/hammer_setup.rb +4 -39
  57. data/definitions/procedures/installer/upgrade.rb +1 -21
  58. data/definitions/procedures/repositories/setup.rb +0 -4
  59. data/definitions/procedures/service/base.rb +31 -0
  60. data/definitions/procedures/service/disable.rb +14 -0
  61. data/definitions/procedures/service/enable.rb +14 -0
  62. data/definitions/procedures/service/list.rb +26 -0
  63. data/definitions/procedures/service/restart.rb +49 -0
  64. data/definitions/procedures/service/start.rb +14 -0
  65. data/definitions/procedures/service/status.rb +14 -0
  66. data/definitions/procedures/service/stop.rb +14 -0
  67. data/definitions/scenarios/backup.rb +242 -0
  68. data/definitions/scenarios/services.rb +156 -0
  69. data/definitions/scenarios/upgrade_to_satellite_6_2.rb +2 -2
  70. data/definitions/scenarios/upgrade_to_satellite_6_2_z.rb +2 -2
  71. data/definitions/scenarios/upgrade_to_satellite_6_3.rb +2 -2
  72. data/definitions/scenarios/upgrade_to_satellite_6_3_z.rb +2 -2
  73. data/definitions/scenarios/upgrade_to_satellite_6_4.rb +79 -0
  74. data/definitions/scenarios/upgrade_to_satellite_6_4_z.rb +79 -0
  75. data/lib/foreman_maintain.rb +5 -0
  76. data/lib/foreman_maintain/cli.rb +4 -0
  77. data/lib/foreman_maintain/cli/backup_command.rb +157 -0
  78. data/lib/foreman_maintain/cli/base.rb +18 -8
  79. data/lib/foreman_maintain/cli/service_command.rb +112 -0
  80. data/lib/foreman_maintain/cli/transform_clamp_options.rb +1 -1
  81. data/lib/foreman_maintain/concerns/base_database.rb +57 -5
  82. data/lib/foreman_maintain/concerns/hammer.rb +0 -9
  83. data/lib/foreman_maintain/concerns/metadata.rb +3 -1
  84. data/lib/foreman_maintain/concerns/reporter.rb +12 -0
  85. data/lib/foreman_maintain/concerns/system_helpers.rb +45 -2
  86. data/lib/foreman_maintain/detector.rb +3 -3
  87. data/lib/foreman_maintain/error.rb +12 -0
  88. data/lib/foreman_maintain/executable.rb +29 -6
  89. data/lib/foreman_maintain/feature.rb +15 -0
  90. data/lib/foreman_maintain/param.rb +4 -3
  91. data/lib/foreman_maintain/reporter.rb +6 -2
  92. data/lib/foreman_maintain/reporter/cli_reporter.rb +26 -10
  93. data/lib/foreman_maintain/runner.rb +26 -15
  94. data/lib/foreman_maintain/runner/execution.rb +5 -1
  95. data/lib/foreman_maintain/scenario.rb +11 -3
  96. data/lib/foreman_maintain/upgrade_runner.rb +0 -2
  97. data/lib/foreman_maintain/utils.rb +2 -2
  98. data/lib/foreman_maintain/utils/command_runner.rb +0 -2
  99. data/lib/foreman_maintain/utils/hash_tools.rb +21 -0
  100. data/lib/foreman_maintain/utils/mongo_core.rb +37 -0
  101. data/lib/foreman_maintain/version.rb +1 -1
  102. metadata +58 -8
  103. data/definitions/features/katello_service.rb +0 -118
  104. data/definitions/procedures/katello_service/restart.rb +0 -24
  105. data/definitions/procedures/katello_service/start.rb +0 -19
  106. data/definitions/procedures/katello_service/stop.rb +0 -17
  107. data/lib/foreman_maintain/utils/facter.rb +0 -21
  108. data/lib/foreman_maintain/utils/hammer.rb +0 -79
@@ -41,7 +41,7 @@ class Features::SyncPlans < ForemanMaintain::Feature
41
41
  def update_records(ids, enabled)
42
42
  updated_record_ids = []
43
43
  ids.each do |sp_id|
44
- result = hammer("sync-plan update --id #{sp_id} --enabled #{enabled}")
44
+ result = feature(:hammer).run("sync-plan update --id #{sp_id} --enabled #{enabled}")
45
45
  if result.include?('Sync plan updated')
46
46
  updated_record_ids << sp_id
47
47
  else
@@ -0,0 +1,69 @@
1
+ class Features::Tar < ForemanMaintain::Feature
2
+ metadata do
3
+ label :tar
4
+ preparation_steps { Procedures::Packages::Install.new(:packages => %w[tar]) }
5
+ end
6
+
7
+ # Run system tar
8
+ # @param [Hash] options tar configuration
9
+ # @option options [String] :archive archive name
10
+ # @option options [String] :command ('create') tar operation command
11
+ # @option options [Array] :exclude dirs or files to exclude
12
+ # @option options [String] :listed_incremental .snar file to do incremental backup
13
+ # @option options [String] :transform sed expression to transform the filenames
14
+ # @option options [String] :volume_size size of tar volume
15
+ # (will try to split the archive when set)
16
+ # @option options [String] :files (*) files to operate on
17
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
18
+ def run(options = {})
19
+ volume_size = options.fetch(:volume_size, nil)
20
+ validate_volume_size(volume_size) unless volume_size.nil?
21
+
22
+ tar_command = ['tar']
23
+ tar_command << '--selinux'
24
+ tar_command << "--#{options.fetch(:command, 'create')}"
25
+ tar_command << "--file=#{options.fetch(:archive)}"
26
+
27
+ if volume_size
28
+ split_tar_script = default_split_tar_script
29
+ tar_command << "--tape-length=#{volume_size}"
30
+ tar_command << "--new-volume-script=#{split_tar_script}"
31
+ end
32
+
33
+ exclude = options.fetch(:exclude, [])
34
+ exclude.each do |ex|
35
+ tar_command << "--exclude=#{ex}"
36
+ end
37
+
38
+ snar_file = options.fetch(:listed_incremental, nil)
39
+ tar_command << "--listed-incremental=#{snar_file}" if snar_file
40
+
41
+ trans = options.fetch(:transform, nil)
42
+ tar_command << "--transform '#{trans}'" if trans
43
+
44
+ tar_command << '-S'
45
+ tar_command << options.fetch(:files, '*')
46
+
47
+ execute!(tar_command.join(' '))
48
+ end
49
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
50
+
51
+ def validate_volume_size(size)
52
+ if size.nil? || size !~ /^\d+[bBcGKkMPTw]?$/
53
+ raise ForemanMaintain::Error::Validation,
54
+ "Please specify size according to 'tar --tape-length' format."
55
+ end
56
+ true
57
+ end
58
+
59
+ private
60
+
61
+ def default_split_tar_script
62
+ utils_path = File.expand_path('../../../bin', __FILE__)
63
+ split_tar_script = File.join(utils_path, 'foreman-maintain-rotate-tar')
64
+ unless File.executable?(split_tar_script)
65
+ raise ForemanMaintain::Error::Fail, "Script #{split_tar_script} is not executable"
66
+ end
67
+ split_tar_script
68
+ end
69
+ end
@@ -0,0 +1,14 @@
1
+ module Procedures::Backup
2
+ class AccessibilityConfirmation < ForemanMaintain::Procedure
3
+ metadata do
4
+ description 'Confirm turning off services is allowed'
5
+ tags :backup
6
+ end
7
+
8
+ def run
9
+ answer = ask_decision("WARNING: This script will stop your services.\n\n" \
10
+ 'Do you want to proceed?', 'y(yes), q(quit)')
11
+ abort! unless answer == :yes
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ module Procedures::Backup
2
+ class Clean < ForemanMaintain::Procedure
3
+ metadata do
4
+ description 'Clean up backup directory'
5
+ tags :backup
6
+ param :backup_dir, 'Directory where to backup to', :required => true
7
+ param :preserve_dir, 'Directory where to backup to'
8
+ end
9
+
10
+ def run
11
+ skip('Backup directory will be preserved') if @preserve_dir
12
+ FileUtils.rm_rf @backup_dir
13
+ logger.info("Backup directory #{@backup_dir} was removed.")
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,26 @@
1
+ module Procedures::Backup
2
+ class CompressData < ForemanMaintain::Procedure
3
+ metadata do
4
+ description 'Compress backup data to save space'
5
+ tags :backup
6
+ param :backup_dir, 'Directory where to backup to', :required => true
7
+ end
8
+
9
+ def run
10
+ compress_file('pgsql_data.tar', 'Postgress DB')
11
+ compress_file('mongo_data.tar', 'Mongo DB')
12
+ end
13
+
14
+ private
15
+
16
+ def compress_file(archive, archive_name)
17
+ data_tar = File.join(@backup_dir, archive)
18
+ if File.exist?(data_tar)
19
+ with_spinner("Compressing backup of #{archive_name}") do
20
+ gzip = spawn('gzip', data_tar, '-f')
21
+ Process.wait(gzip)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,36 @@
1
+ module Procedures::Backup
2
+ class ConfigFiles < ForemanMaintain::Procedure
3
+ metadata do
4
+ description 'Backup config files'
5
+ tags :backup
6
+ preparation_steps do
7
+ if feature(:foreman_proxy) && !feature(:foreman_proxy).internal?
8
+ Checks::Backup::CertsTarExist.new
9
+ end
10
+ end
11
+ param :backup_dir, 'Directory where to backup to', :required => true
12
+ param :proxy_features, 'List of proxy features to backup (default: all)',
13
+ :array => true, :default => ['all']
14
+ end
15
+
16
+ def run
17
+ tarball = File.join(@backup_dir, 'config_files.tar.gz')
18
+ increments = File.join(@backup_dir, '.config.snar')
19
+ with_spinner('Collecting config files to backup') do
20
+ configs = config_files.join(' ')
21
+ execute!("tar --selinux --create --gzip --file=#{tarball} " \
22
+ "--listed-incremental=#{increments} --ignore-failed-read " \
23
+ "#{configs}")
24
+ end
25
+ end
26
+
27
+ def config_files
28
+ configs = []
29
+ # exclude proxy as it has special handling later
30
+ features = ForemanMaintain.available_features - [feature(:foreman_proxy)]
31
+ configs += features.inject([]) { |files, feature| files + feature.config_files }
32
+ configs += feature(:foreman_proxy).config_files(@proxy_features) if feature(:foreman_proxy)
33
+ configs.compact.select { |path| Dir.glob(path).any? }
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,56 @@
1
+ module Procedures::Backup
2
+ class Metadata < ForemanMaintain::Procedure
3
+ metadata do
4
+ description 'Generate metadata'
5
+ tags :backup
6
+ preparation_steps { Checks::Foreman::DBUp.new if feature(:foreman_server) }
7
+ param :backup_dir, 'Directory where to backup to', :required => true
8
+ param :incremental_dir, 'Changes since specified backup only'
9
+ end
10
+
11
+ def run
12
+ with_spinner('Collecting metadata') do |spinner|
13
+ metadata = {}
14
+ metadata['os_version'] = release_info(spinner)
15
+ metadata['plugin_list'] = plugin_list(spinner) || []
16
+ metadata['proxy_features'] = proxy_feature_list(spinner) || []
17
+ metadata['rpms'] = rpms(spinner)
18
+ metadata['incremental'] = @incremental_dir || false
19
+ save_metadata(metadata, spinner)
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def save_metadata(metadata, spinner)
26
+ spinner.update('Saving metadata to metadata.yml')
27
+ File.open(File.join(@backup_dir, 'metadata.yml'), 'w') do |metadata_file|
28
+ metadata_file.puts metadata.to_yaml
29
+ end
30
+ end
31
+
32
+ def release_info(spinner)
33
+ spinner.update('Collecting system release info')
34
+ execute!('cat /etc/redhat-release').chomp
35
+ end
36
+
37
+ def rpms(spinner)
38
+ spinner.update('Collecting installed RPMs')
39
+ execute!('rpm -qa').split("\n")
40
+ end
41
+
42
+ def plugin_list(spinner)
43
+ if feature(:foreman_server)
44
+ spinner.update('Collecting list of plugins')
45
+ feature(:foreman_server).plugins
46
+ end
47
+ end
48
+
49
+ def proxy_feature_list(spinner)
50
+ if feature(:foreman_proxy)
51
+ spinner.update('Collecting list of proxy features')
52
+ feature(:foreman_proxy).features
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,57 @@
1
+ module Procedures::Backup
2
+ module Offline
3
+ class CandlepinDB < ForemanMaintain::Procedure
4
+ metadata do
5
+ description 'Backup Candlepin DB offline'
6
+ tags :backup
7
+ label :backup_offline_candlepin_db
8
+ for_feature :candlepin_database
9
+ preparation_steps { Checks::Candlepin::DBUp.new unless feature(:candlepin_database).local? }
10
+ param :backup_dir, 'Directory where to backup to', :required => true
11
+ param :tar_volume_size, 'Size of tar volume (indicates splitting)'
12
+ param :mount_dir, 'Snapshot mount directory'
13
+ end
14
+
15
+ def run
16
+ if feature(:candlepin_database).local?
17
+ if File.exist?(pg_backup_file)
18
+ puts 'Already done'
19
+ else
20
+ local_backup
21
+ end
22
+ else
23
+ puts "Backup of #{pg_data_dir} is not supported for remote databases." \
24
+ ' Doing postgres dump instead...'
25
+ with_spinner('Getting Candlepin DB dump') do
26
+ feature(:candlepin_database).dump_db(File.join(@backup_dir, 'candlepin.dump'))
27
+ end
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def local_backup
34
+ with_spinner("Collecting data from #{pg_data_dir}") do
35
+ feature(:candlepin_database).backup_local(
36
+ pg_backup_file,
37
+ :listed_incremental => File.join(@backup_dir, '.postgres.snar'),
38
+ :volume_size => @tar_volume_size,
39
+ :data_dir => pg_data_dir
40
+ )
41
+ end
42
+ end
43
+
44
+ def pg_backup_file
45
+ File.join(@backup_dir, 'pgsql_data.tar')
46
+ end
47
+
48
+ def pg_data_dir
49
+ return feature(:candlepin_database).data_dir if @mount_dir.nil?
50
+ mount_point = File.join(@mount_dir, 'pgsql')
51
+ dir = feature(:candlepin_database).find_base_directory(mount_point)
52
+ fail!("Snapshot of Candlepin DB was not found mounted in #{mount_point}") if dir.nil?
53
+ dir
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,57 @@
1
+ module Procedures::Backup
2
+ module Offline
3
+ class ForemanDB < ForemanMaintain::Procedure
4
+ metadata do
5
+ description 'Backup Foreman DB offline'
6
+ tags :backup
7
+ label :backup_offline_foreman_db
8
+ for_feature :foreman_database
9
+ preparation_steps { Checks::Foreman::DBUp.new unless feature(:foreman_database).local? }
10
+ param :backup_dir, 'Directory where to backup to', :required => true
11
+ param :tar_volume_size, 'Size of tar volume (indicates splitting)'
12
+ param :mount_dir, 'Snapshot mount directory'
13
+ end
14
+
15
+ def run
16
+ if feature(:foreman_database).local?
17
+ if File.exist?(pg_backup_file)
18
+ puts 'Already done'
19
+ else
20
+ local_backup
21
+ end
22
+ else
23
+ puts "Backup of #{pg_data_dir} is not supported for remote databases." \
24
+ ' Doing postgres dump instead...'
25
+ with_spinner('Getting Foreman DB dump') do
26
+ feature(:foreman_database).dump_db(File.join(@backup_dir, 'foreman.dump'))
27
+ end
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def local_backup
34
+ with_spinner("Collecting data from #{pg_data_dir}") do
35
+ feature(:foreman_database).backup_local(
36
+ pg_backup_file,
37
+ :listed_incremental => File.join(@backup_dir, '.postgres.snar'),
38
+ :volume_size => @tar_volume_size,
39
+ :data_dir => pg_data_dir
40
+ )
41
+ end
42
+ end
43
+
44
+ def pg_backup_file
45
+ File.join(@backup_dir, 'pgsql_data.tar')
46
+ end
47
+
48
+ def pg_data_dir
49
+ return feature(:foreman_database).data_dir if @mount_dir.nil?
50
+ mount_point = File.join(@mount_dir, 'pgsql')
51
+ dir = feature(:foreman_database).find_base_directory(mount_point)
52
+ fail!("Snapshot of Foreman DB was not found mounted in #{mount_point}") if dir.nil?
53
+ dir
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,56 @@
1
+ module Procedures::Backup
2
+ module Offline
3
+ class Mongo < ForemanMaintain::Procedure
4
+ metadata do
5
+ description 'Backup mongo offline'
6
+ tags :backup
7
+ for_feature :mongo
8
+ preparation_steps do
9
+ unless feature(:mongo).local?
10
+ [Checks::Mongo::DBUp.new, Checks::Mongo::ToolsInstalled.new]
11
+ end
12
+ end
13
+ param :backup_dir, 'Directory where to backup to', :required => true
14
+ param :tar_volume_size, 'Size of tar volume (indicates splitting)'
15
+ param :mount_dir, 'Snapshot mount directory'
16
+ end
17
+
18
+ def run
19
+ if feature(:mongo).local?
20
+ local_backup
21
+ else
22
+ dump_mongo
23
+ end
24
+ end
25
+
26
+ def data_dir
27
+ return nil if @mount_dir.nil?
28
+ mount_point = File.join(@mount_dir, 'mongodb')
29
+ dir = feature(:mongo).find_base_directory(mount_point)
30
+ fail!("Snapshot of Mongo DB was not found mounted in #{mount_point}") if dir.nil?
31
+ dir
32
+ end
33
+
34
+ private
35
+
36
+ def dump_mongo
37
+ puts "Backup of #{feature(:mongo).data_dir} is not supported for remote databases." \
38
+ ' Doing dump instead... '
39
+ with_spinner('Getting dump of Mongo DB') do
40
+ feature(:mongo).dump(File.join(@backup_dir, 'mongo_dump'))
41
+ end
42
+ end
43
+
44
+ def local_backup
45
+ with_spinner('Collecting Mongo data') do
46
+ feature(:mongo).backup_local(
47
+ File.join(@backup_dir, 'mongo_data.tar'),
48
+ :listed_incremental => File.join(@backup_dir, '.mongo.snar'),
49
+ :volume_size => @tar_volume_size,
50
+ :data_dir => data_dir
51
+ )
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,20 @@
1
+ module Procedures::Backup
2
+ module Online
3
+ class CandlepinDB < ForemanMaintain::Procedure
4
+ metadata do
5
+ description 'Backup Candlepin database online'
6
+ tags :backup
7
+ label :backup_online_candlepin_db
8
+ for_feature :candlepin_database
9
+ preparation_steps { Checks::Candlepin::DBUp.new }
10
+ param :backup_dir, 'Directory where to backup to', :required => true
11
+ end
12
+
13
+ def run
14
+ with_spinner('Getting Candlepin DB dump') do
15
+ feature(:candlepin_database).dump_db(File.join(@backup_dir, 'candlepin.dump'))
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Procedures::Backup
2
+ module Online
3
+ class ForemanDB < ForemanMaintain::Procedure
4
+ metadata do
5
+ description 'Backup Foreman database online'
6
+ tags :backup
7
+ label :backup_online_foreman_db
8
+ for_feature :foreman_database
9
+ preparation_steps { Checks::Foreman::DBUp.new }
10
+ param :backup_dir, 'Directory where to backup to', :required => true
11
+ end
12
+
13
+ def run
14
+ with_spinner('Getting Foreman DB dump') do
15
+ feature(:foreman_database).dump_db(File.join(@backup_dir, 'foreman.dump'))
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end