foreman_maintain 0.1.6 → 0.2.0

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 (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