foreman_maintain 0.3.6 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: f0a600b819e8c744cacd365f94a9bdedbbc187686d637d1e9b7ed39d065c3d54
4
- data.tar.gz: eb3b315d318f8b85e3a6f78f79f951f6f70f0acfa11d31726c47df065aab9b3e
2
+ SHA1:
3
+ metadata.gz: 8e56d0ebde52242c236f12a7a5b1f6a5bff833f3
4
+ data.tar.gz: b1edcdce8bef56a30d93e8e87b353c0da2823d0f
5
5
  SHA512:
6
- metadata.gz: fd325f4efac68b36d08857a3860b1d875727cfc7841bd12d6c98ce96196f263526c9398875c4c9e3c3fe904c9f77926f7eb393e84bacac00847f9be247c40002
7
- data.tar.gz: af9c5cedfe89e7e89dfea149c36833364bd1df4717f5a6c3241ce560eeca8772fe45523c3631c4f3d48e702790b26c8b6f3ad66f6f76f119f2e4b92d9a167fd2
6
+ metadata.gz: d30075189e4c304a615af0f9184aec70e6a904e7918d02720a5fddb7241d8abaab5b02221aeeeedd0638a5f3f9b973c2def96e3612d42185d97b0fca9e8f18d8
7
+ data.tar.gz: 9a4793c2de2b9ee693109bd6bb16b5f89f4365b17e972651973b4eb9844535788a1c1c665eef52790e487aa4da794ee1bc04f1ab160e867f666bccb7dd40019b
data/README.md CHANGED
@@ -35,6 +35,19 @@ Subcommands:
35
35
  list List applicable services
36
36
  enable Enable applicable services
37
37
  disable Disable applicable services
38
+
39
+ backup Backup server
40
+ online Keep services online during backup
41
+ offline Shut down services to preserve consistent backup
42
+ snapshot Use snapshots of the databases to create backup
43
+
44
+ restore Restore a backup
45
+
46
+ maintenance-mode Control maintenance-mode for application
47
+ start Start maintenance-mode
48
+ stop Stop maintenance-mode
49
+ status Get maintenance-mode status
50
+ is-enabled Get maintenance-mode status code
38
51
  ```
39
52
 
40
53
  ### Upgrades
@@ -107,12 +120,6 @@ export EXTERNAL_SAT_ORG='Sat6-CI'
107
120
  export EXTERNAL_SAT_ACTIVATION_KEY='Satellite QA RHEL7'
108
121
  ```
109
122
 
110
- To use beta repositories during upgrade, set the following environment variable
111
-
112
- ```
113
- export FOREMAN_MAINTAIN_USE_BETA='1'
114
- ```
115
-
116
123
  ## Implementation
117
124
 
118
125
  `foreman_maintain` maps the CLI commands into definitions. This allows to keep the set
@@ -383,8 +390,6 @@ Execute `rake` to run the tests.
383
390
  ```
384
391
  foreman-maintain health [check|fix]
385
392
  foreman-maintain upgrade [check|run|abort] [foreman_1_14, satellite_6_1, satellite_6_2]
386
- foreman-maintain maintenance-mode [on|off]
387
- foreman-maintain backup [save|restore]
388
393
  foreman-maintain monitor [display|upload]
389
394
  foreman-maintain debug [save|upload|tail]
390
395
  foreman-maintain console
@@ -397,18 +402,18 @@ The completion offers suggestion of possible command-line subcommands and their
397
402
  as usual. It can also suggest values for options and params where file
398
403
  or directory path is expected.
399
404
 
400
- Bash completion is automatically installed by RPM. To use it for development setup
401
- `cp ./config/foreman-maintain.completion /etc/bash_completion.d/foreman-maintain`
405
+ Bash completion is automatically installed by RPM. To use it for development setup
406
+ `cp ./config/foreman-maintain.completion /etc/bash_completion.d/foreman-maintain`
402
407
  and load it to the current shell `source /etc/bash_completion.d/foreman-maintain`.
403
408
  Make sure the `$PWD/bin` is in `PATH` or there is full path to `foreman-maintain-complete`
404
409
  executable specified in `/etc/bash_completion.d/foreman-maintain`.
405
410
 
406
- Bash completion for foreman-maintain needs pre-built cache that holds description of
407
- all subcommands and its parameters. The cache is located by default in
411
+ Bash completion for foreman-maintain needs pre-built cache that holds description of
412
+ all subcommands and its parameters. The cache is located by default in
408
413
  `~/.cache/foreman_maintain_completion.yml`. The location can be changed in foreman-maintain's
409
- config file. The cache can be built manually with
414
+ config file. The cache can be built manually with
410
415
  `foreman-maintain advanced prebuild-bash-completion` or is built automatically when
411
- completion is used and the cache is missing (this may cause slight delay). The cache expires
416
+ completion is used and the cache is missing (this may cause slight delay). The cache expires
412
417
  after installer scenario answer file changed (it indicates that the features on the instance
413
418
  may have changed which has impact on foreman-maintain CLI options and subcommands).
414
419
 
@@ -424,9 +429,18 @@ Possible options for the `:completion` attribute are:
424
429
  - `{ :type => :flag }` option has no value, default for flags
425
430
  - `{ :type => :value }` option has value of unknown type, no suggestions for the value, default
426
431
  - `{ :type => :directory }` value is directory, suggestions follow directory structure
427
- - `{ :type => :file, :filter => '\.txt$' }` value is file, suggestions follow directory structure,
432
+ - `{ :type => :file, :filter => '\.txt$' }` value is file, suggestions follow directory structure,
428
433
  optional `:filter` is regexp to filter the results.
429
-
434
+
435
+ ### Difference between maintenance-mode status and is-enabled:
436
+
437
+ * `maintenance-mode status` gives a brief output with On/Off message. This includes status of each step.
438
+
439
+ * `maintenance-mode is-enabled` returns `0 or 1` output depending upon the maintenance-mode status.
440
+ Here, 1=ON & 0=OFF.
441
+
442
+ If User would like to check whether maintenance-mode is ON/OFF on system in their external script then
443
+ they can use subcommand `foreman-maintain maintenance-mode is-enabled`.
430
444
 
431
445
  ## How to contribute?
432
446
 
@@ -11,9 +11,9 @@ CONFIG = YAML.load_file(CONFIG_FILE) if File.readable?(CONFIG_FILE)
11
11
  exit 0 unless CONFIG[:ENABLED]
12
12
 
13
13
  def running?(pid)
14
- return Process.getpgid(pid) != -1
14
+ Process.getpgid(pid) != -1
15
15
  rescue Errno::ESRCH
16
- return false
16
+ false
17
17
  end
18
18
 
19
19
  def debug(msg)
@@ -25,11 +25,10 @@ def verbose(msg)
25
25
  end
26
26
 
27
27
  def kill(pid)
28
- if running?(pid) && CONFIG[:KILL_BUSY]
29
- verbose "Process #{pid} is still running, sending SIGKILL"
30
- Process.kill 'KILL', pid
31
- sleep 5
32
- end
28
+ return unless running?(pid) && CONFIG[:KILL_BUSY]
29
+ verbose "Process #{pid} is still running, sending SIGKILL"
30
+ Process.kill 'KILL', pid
31
+ sleep 5
33
32
  end
34
33
 
35
34
  def process_status?(pid)
@@ -40,6 +39,10 @@ def process_status?(pid)
40
39
  end
41
40
  end
42
41
 
42
+ def show_passenger_status(status_messages)
43
+ status_messages.each { |msg| verbose msg }
44
+ end
45
+
43
46
  require 'phusion_passenger'
44
47
  PhusionPassenger.locate_directories
45
48
  require 'phusion_passenger/platform_info'
@@ -65,25 +68,22 @@ stats.passenger_processes.each do |p|
65
68
  pid = p.pid.to_i
66
69
  started = get_process_start(pid)
67
70
  get_pid_mem_kb, get_pid_mem_mb = get_rss_info(p)
68
- debug_message = "Checking #{pid} with RSS of #{get_pid_mem_kb}"
69
- verbose_message = "Terminating #{pid} (started #{started}) with private" \
70
- " RSS size of #{get_pid_mem_mb} MB"
71
- debug debug_message
71
+ debug "Checking #{pid} with RSS of #{get_pid_mem_kb}"
72
72
  next unless get_pid_mem_kb > CONFIG[:MAX_PRIV_RSS_MEMORY]
73
73
  status_ps = `ps -p#{pid} -u`
74
74
  status_all = `passenger-status 2> /dev/null`
75
75
  status_backtraces = `passenger-status --show=backtraces 2>/dev/null`
76
- verbose verbose_message
77
- Process.kill 'SIGUSR1', pid
78
- sleep CONFIG[:GRACEFUL_SHUTDOWN_SLEEP]
79
- kill(pid)
80
- process_status?(pid)
81
- if CONFIG[:SEND_STATUS]
82
- verbose status_ps
83
- verbose status_all
84
- verbose status_backtraces
76
+ verbose("Terminating #{pid} (started #{started}) with private RSS size of #{get_pid_mem_mb} MB")
77
+ begin
78
+ Process.kill 'SIGUSR1', pid
79
+ sleep CONFIG[:GRACEFUL_SHUTDOWN_SLEEP]
80
+ kill(pid)
81
+ process_status?(pid)
82
+ show_passenger_status([status_ps, status_all, status_backtraces]) if CONFIG[:SEND_STATUS]
83
+ killed += 1
84
+ exit(1) if killed >= CONFIG[:MAX_TERMINATION]
85
+ rescue Errno::ESRCH
86
+ puts "#{Process.pid}: #{pid} is NOT running"
85
87
  end
86
- killed += 1
87
- exit(1) if killed >= CONFIG[:MAX_TERMINATION]
88
88
  end
89
89
  exit 0
@@ -23,5 +23,12 @@
23
23
  # Mention directory path to store candlepin db backups
24
24
  # :db_backup_dir: '/var/lib/foreman-maintain/db-backups'
25
25
 
26
+ # Disable commands and subcommands. Default: []
27
+ # :disable_commands: [ 'SnapshotBackupCommand' ]
28
+
26
29
  # Location of cache for bash completion
27
30
  :completion_cache_file: '~/.cache/foreman_maintain_completion.yml'
31
+
32
+ # Mention true/false.
33
+ # Value true will to enable cron service stop/restart on maintenance-mode start/stop
34
+ # :manage_crond: false
@@ -25,3 +25,7 @@
25
25
 
26
26
  # Location of cache for bash completion
27
27
  :completion_cache_file: '~/.cache/foreman_maintain_completion.yml'
28
+
29
+ # Mention true/false.
30
+ # Value true will to enable cron service stop/restart on maintenance-mode start/stop
31
+ # :manage_crond: false
@@ -18,7 +18,7 @@ module Checks
18
18
  end
19
19
 
20
20
  def next_steps
21
- if feature(:foreman_database).local?
21
+ if feature(:candlepin_database).local?
22
22
  [Procedures::Service::Start.new(:only => 'postgresql')]
23
23
  else
24
24
  [] # there is nothing we can do for remote db
@@ -0,0 +1,90 @@
1
+ class Checks::CheckHotfixInstalled < ForemanMaintain::Check
2
+ metadata do
3
+ label :check_hotfix_installed
4
+ description 'Check to verify if any hotfix installed on system'
5
+ tags :pre_upgrade
6
+ preparation_steps do
7
+ Procedures::Packages::Install.new(:packages => %w[yum-utils])
8
+ end
9
+
10
+ confine do
11
+ feature(:downstream)
12
+ end
13
+ end
14
+
15
+ def run
16
+ if feature(:downstream).subscribed_using_activation_key?
17
+ skip "Your system is subscribed using custom activation key. Hotfixes can't be detected."
18
+ else
19
+ with_spinner('Checking for presence of hotfix(es). It may take some time to verify.') do
20
+ hotfix_rpmlist = find_hotfix_packages
21
+ installed_pkg_list = installed_packages
22
+ files_modifications = installed_pkg_list.flat_map { |pkg| modified_files(pkg) }
23
+ assert(hotfix_rpmlist.empty? && files_modifications.empty?,
24
+ warning_message(hotfix_rpmlist, files_modifications),
25
+ :warn => true)
26
+ end
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def modified_files(package)
33
+ changed_files = []
34
+ IO.popen(['rpm', '-V', package]) do |pipe|
35
+ pipe.each do |line|
36
+ arr_output = line.chomp.split
37
+ flags = arr_output.first
38
+ filename = arr_output.last
39
+ changed_files << filename if flags.include?('5') && filename =~ /\.(rb|py|erb|js)$/
40
+ end
41
+ end
42
+ changed_files
43
+ end
44
+
45
+ def installed_packages
46
+ packages = []
47
+ repoquery_cmd = execute!('which repoquery')
48
+ IO.popen([repoquery_cmd, '-a', '--installed', '--qf', '%{ui_from_repo} %{nvra}']) do |io|
49
+ io.each do |line|
50
+ repo, pkg = line.chomp.split
51
+ packages << pkg if /satellite|rhscl/ =~ repo[1..-1].downcase
52
+ end
53
+ end
54
+ packages
55
+ end
56
+
57
+ def find_hotfix_packages
58
+ output = execute!('rpm -qa release="*HOTFIX*"').strip
59
+ return [] if output.empty?
60
+
61
+ output.split("\n")
62
+ end
63
+
64
+ def warning_message(hotfix_rpmlist, files_modified)
65
+ message = "\n"
66
+ unless hotfix_rpmlist.empty?
67
+ message += msg_for_hotfix_rpms(hotfix_rpmlist)
68
+ end
69
+ unless files_modified.empty?
70
+ message += msg_for_modified_files(files_modified)
71
+ end
72
+ message += "\n\n*** WARNING: Before update make sure the updated packages contain"\
73
+ " the listed modifications\n"\
74
+ "*** otherwise these fixes will be lost. \n"\
75
+ '*** It is also recommended to backup the modified files prior update.'
76
+ message
77
+ end
78
+
79
+ def msg_for_hotfix_rpms(rpms_list)
80
+ message = "HOTFIX rpm(s) applied on this system:\n"
81
+ message += rpms_list.join(',')
82
+ message
83
+ end
84
+
85
+ def msg_for_modified_files(files_modified)
86
+ message = "\n\nFound #{files_modified.length} file(s) modified on this system.\n"
87
+ message += files_modified.join("\n")
88
+ message
89
+ end
90
+ end
@@ -0,0 +1,20 @@
1
+ class Checks::CheckTmout < ForemanMaintain::Check
2
+ metadata do
3
+ label :check_tmout_variable
4
+ description 'Check if TMOUT environment variable is set'
5
+ tags :pre_upgrade
6
+ end
7
+
8
+ def run
9
+ assert(tmout_unset?, "The TMOUT environment variable is set with value #{tmout_env}."\
10
+ " Run 'unset TMOUT' command to unset this variable.")
11
+ end
12
+
13
+ def tmout_unset?
14
+ tmout_env == '0' || tmout_env == '' || tmout_env.nil?
15
+ end
16
+
17
+ def tmout_env
18
+ ENV['TMOUT']
19
+ end
20
+ end
@@ -26,11 +26,7 @@ module Checks
26
26
  puts "\n"
27
27
  puts stats.stdout
28
28
 
29
- if feature(:downstream) && feature(:downstream).at_least_version?('6.3')
30
- assert(success, io_obj.slow_disk_error_msg + warning_message, :warn => true)
31
- else
32
- assert(success, io_obj.slow_disk_error_msg)
33
- end
29
+ assert(success, io_obj.slow_disk_error_msg)
34
30
  end
35
31
  end
36
32
 
@@ -42,17 +38,11 @@ module Checks
42
38
 
43
39
  def dirs_to_check
44
40
  return DEFAULT_DIRS.first(1) if check_only_single_device?
45
-
46
41
  DEFAULT_DIRS
47
42
  end
48
43
 
49
44
  private
50
45
 
51
- def warning_message
52
- "\nWARNING: Low disk speed might have a negative impact on the system."\
53
- "\nSee https://access.redhat.com/solutions/3397771 before proceeding"
54
- end
55
-
56
46
  def compute_disk_speed(spinner)
57
47
  success = true
58
48
  io_obj = ForemanMaintain::Utils::Disk::NilDevice.new
@@ -0,0 +1,62 @@
1
+ module Checks::MaintenanceMode
2
+ class CheckConsistency < ForemanMaintain::Check
3
+ metadata do
4
+ label :check_maintenance_mode_consistency
5
+ description 'Check of maintenance-mode consistency'
6
+ advanced_run false
7
+ end
8
+
9
+ def run
10
+ procedure_arr = []
11
+ message_to_show = ''
12
+ with_spinner('Running status of maintenance-mode') do |_spinner|
13
+ message_to_show, procedure_arr = verify_with_features
14
+ end
15
+ puts message_to_show
16
+ assert(
17
+ procedure_arr.empty?,
18
+ 'You can follow remediation procedure(s) to fix maintenance-mode state',
19
+ :next_steps => procedure_arr
20
+ )
21
+ end
22
+
23
+ private
24
+
25
+ def verify_with_features
26
+ procedure_arr = []
27
+ feature_status_msgs = []
28
+ is_mode_on = feature(:iptables).maintenance_mode_chain_exist?
29
+ [:iptables, :sync_plans, :cron].each do |feature_name|
30
+ msg, procedures_to_run = send("check_for_#{feature_name}", is_mode_on)
31
+ feature_status_msgs << msg
32
+ procedure_arr.concat(procedures_to_run)
33
+ end
34
+ [construct_message(is_mode_on, feature_status_msgs), procedure_arr]
35
+ end
36
+
37
+ def construct_message(is_mode_on, feature_status_msgs)
38
+ info_string = "\nStatus of maintenance-mode: #{is_mode_on ? 'On' : 'Off'}"
39
+ unless feature_status_msgs.empty?
40
+ info_string += "\n- "
41
+ end
42
+ info_string += feature_status_msgs.join("\n- ")
43
+ info_string
44
+ end
45
+
46
+ def check_for_cron(is_mode_on)
47
+ unless ForemanMaintain.config.manage_crond && feature(:cron)
48
+ return ['cron jobs: not managed', []]
49
+ end
50
+
51
+ feature(:cron).status_for_maintenance_mode(is_mode_on)
52
+ end
53
+
54
+ def check_for_iptables(_is_mode_on)
55
+ feature(:iptables).status_for_maintenance_mode
56
+ end
57
+
58
+ def check_for_sync_plans(is_mode_on)
59
+ feature(:sync_plans).status_for_maintenance_mode(is_mode_on)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,24 @@
1
+ module Checks::Puppet
2
+ class VerifyNoEmptyCacertRequests < ForemanMaintain::Check
3
+ metadata do
4
+ label :puppet_check_no_empty_cert_requests
5
+ for_feature :puppet_server
6
+ tags :default
7
+ description 'Check to verify no empty CA cert requests exist'
8
+ end
9
+
10
+ def run
11
+ cacert_requests_directory = 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
+ assert(
15
+ files.empty?,
16
+ "Found #{files.length} empty file(s) under #{cacert_requests_directory}",
17
+ :next_steps => Procedures::Puppet::DeleteEmptyCaCertRequestFiles.new
18
+ )
19
+ else
20
+ skip "#{cacert_requests_directory} directory not found"
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,22 @@
1
+ class Checks::CheckUpstreamRepository < ForemanMaintain::Check
2
+ metadata do
3
+ label :check_upstream_repository
4
+ description 'Check if any upstream repositories are enabled on system'
5
+ tags :pre_upgrade
6
+ preparation_steps do
7
+ Procedures::Packages::Install.new(:packages => %w[yum-utils])
8
+ end
9
+ confine do
10
+ feature(:downstream)
11
+ end
12
+ end
13
+
14
+ def run
15
+ with_spinner('Checking for presence of upstream repositories') do
16
+ enabled_upstream_repos = feature(:system_repos).upstream_repos_ids
17
+ assert(enabled_upstream_repos.empty?,
18
+ "System has upstream #{enabled_upstream_repos.join(',')} repositories enabled",
19
+ :next_steps => Procedures::Repositories::Disable.new(:repos => enabled_upstream_repos))
20
+ end
21
+ end
22
+ end