foreman_maintain 1.6.4 → 1.6.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc4310d22dcb14b51945e3642cba4c7050e6660893dc09639064b013a2881380
4
- data.tar.gz: d305fc1da3bd0a013d4455ec1ae578f22529fe5302261f82be251be5a0ee9a84
3
+ metadata.gz: 9832b114fa0e778b687140d47774ffa583742e69c0883f7e0738fad23e6d0f87
4
+ data.tar.gz: dfd33002a93b7171aab581342c169d0eef6cee318302bad7d24108581e05b514
5
5
  SHA512:
6
- metadata.gz: d10f290659e20460fffcebf72291e7260a6caf3c8d0964bdb3bd40d9f86ec9b8a5f70781c2f9de2d01778f09bdcda1421defb679a7f541d7ff4b21406368ca3c
7
- data.tar.gz: c63898eece400b9d3813e06e070a3188c27ad5a06aaf57652c68e6f0887bf5b9173b6dd6eb9192acf37dff6b8d2b4c89285f65cf427de72a7a1aa69cc4b9f703
6
+ metadata.gz: 30c727eed2a0f6fb4402caedfcbca2b5e8466b322f94f938523e16726b9439d3b00737950d88c41993fdd61f8cedea7c67752d1917e91ff6a6dde57dfbca1544
7
+ data.tar.gz: fd20b2f2ea602071e1371266b62e7640b945a942208469019f0ee173ab90afd51de78e91c9790c525d1d6e689f5d47779e57ce22c032a1a1d3c53f61eb566135
@@ -12,7 +12,7 @@ module Checks::Repositories
12
12
 
13
13
  param :version,
14
14
  'Version for which repositories needs to be validated',
15
- :required => true
15
+ :required => false
16
16
 
17
17
  manual_detection
18
18
  end
@@ -21,6 +21,8 @@ module Checks::Repositories
21
21
  if feature(:instance).downstream.subscribed_using_activation_key?
22
22
  skip 'Your system is subscribed using custom activation key'
23
23
  else
24
+ @version ||= package_version(feature(:instance).downstream.package_name)
25
+
24
26
  with_spinner("Validating availability of repositories for #{@version}") do |spinner|
25
27
  find_absent_repos(spinner)
26
28
  end
@@ -5,7 +5,7 @@ module Procedures::Packages
5
5
  end
6
6
 
7
7
  def run
8
- status, output = execute_with_status('dnf needs-restarting --reboothint')
8
+ status, output = package_manager.reboot_required?
9
9
  if status == 1
10
10
  set_info_warn(output)
11
11
  else
@@ -7,13 +7,18 @@ module Procedures::Packages
7
7
  param :warn_on_errors, 'Do not interrupt scenario on failure',
8
8
  :flag => true, :default => false
9
9
  param :dnf_options, 'Extra dnf options if any', :array => true, :default => []
10
+ param :download_only, 'Download and cache packages only', :flag => true, :default => false
10
11
  param :clean_cache, 'If true will cause a DNF cache clean', :flag => true, :default => true
11
12
  end
12
13
 
13
14
  def run
14
15
  assumeyes_val = @assumeyes.nil? ? assumeyes? : @assumeyes
15
16
  package_manager.clean_cache(:assumeyes => assumeyes_val) if @clean_cache
16
- opts = { :assumeyes => assumeyes_val, :dnf_options => @dnf_options }
17
+ opts = {
18
+ :assumeyes => assumeyes_val,
19
+ :options => @dnf_options,
20
+ :download_only => @download_only,
21
+ }
17
22
  packages_action(:update, @packages, opts)
18
23
  rescue ForemanMaintain::Error::ExecutionError => e
19
24
  if @warn_on_errors
@@ -28,15 +33,11 @@ module Procedures::Packages
28
33
  end
29
34
 
30
35
  def description
31
- if download_only?
36
+ if @download_only
32
37
  "Download package(s) #{@packages.join(', ')}"
33
38
  else
34
39
  "Update package(s) #{@packages.join(', ')}"
35
40
  end
36
41
  end
37
-
38
- def download_only?
39
- @dnf_options.include?('--downloadonly')
40
- end
41
42
  end
42
43
  end
@@ -10,8 +10,6 @@ module Procedures::Packages
10
10
  if @packages.nil? || @packages.empty?
11
11
  question = "\nWARNING: No specific packages to update were provided\n" \
12
12
  "so we are going to update all available packages.\n" \
13
- "It is recommended to update everything only as part of upgrade\n" \
14
- "of the #{feature(:instance).product_name} to the next version. \n" \
15
13
  "To Upgrade to next version use 'foreman-maintain upgrade'.\n\n" \
16
14
  "Do you want to proceed with update of everything regardless\n" \
17
15
  'of the recommendations?'
@@ -115,22 +115,16 @@ module ForemanMaintain::Scenarios
115
115
  end
116
116
 
117
117
  add_step_with_context(Procedures::Packages::UnlockVersions)
118
+ add_step_with_context(
119
+ Procedures::Packages::Update,
120
+ :force => true,
121
+ :warn_on_errors => true,
122
+ :download_only => context.get(:downloadonly)
123
+ )
118
124
 
119
125
  if context.get(:downloadonly)
120
- add_step_with_context(
121
- Procedures::Packages::Update,
122
- :force => true,
123
- :warn_on_errors => true,
124
- :dnf_options => ['--downloadonly']
125
- )
126
126
  add_step_with_context(Procedures::Packages::LockVersions)
127
127
  else
128
- add_step_with_context(
129
- Procedures::Packages::Update,
130
- :force => true,
131
- :warn_on_errors => true
132
- )
133
-
134
128
  add_step_with_context(Procedures::Installer::Run)
135
129
  end
136
130
 
@@ -0,0 +1,126 @@
1
+ module Scenarios::Update
2
+ class Abstract < ForemanMaintain::Scenario
3
+ def self.update_metadata(&block)
4
+ metadata do
5
+ tags :update_scenario
6
+ instance_eval(&block)
7
+ end
8
+ end
9
+ end
10
+
11
+ class PreUpdateCheck < Abstract
12
+ update_metadata do
13
+ description 'Checks before updating'
14
+ tags :pre_update_checks
15
+ run_strategy :fail_slow
16
+ end
17
+
18
+ # rubocop:disable Metrics/MethodLength
19
+ def compose
20
+ add_steps(
21
+ Checks::Foreman::FactsNames, # if Foreman database present
22
+ Checks::ForemanProxy::CheckTftpStorage, # if Satellite with foreman-proxy+tftp
23
+ Checks::ForemanProxy::VerifyDhcpConfigSyntax, # if foreman-proxy+dhcp-isc
24
+ Checks::ForemanTasks::NotPaused, # if foreman-tasks present
25
+ Checks::Puppet::VerifyNoEmptyCacertRequests, # if puppetserver
26
+ Checks::ServerPing,
27
+ Checks::ServicesUp,
28
+ Checks::SystemRegistration,
29
+ Checks::CheckHotfixInstalled,
30
+ Checks::CheckTmout,
31
+ Checks::CheckUpstreamRepository,
32
+ Checks::Disk::AvailableSpace,
33
+ Checks::Disk::AvailableSpaceCandlepin, # if candlepin
34
+ Checks::Foreman::ValidateExternalDbVersion, # if external database
35
+ Checks::Foreman::CheckCorruptedRoles,
36
+ Checks::Foreman::CheckDuplicatePermissions,
37
+ Checks::Foreman::TuningRequirements, # if katello present
38
+ Checks::ForemanOpenscap::InvalidReportAssociations, # if foreman-openscap
39
+ Checks::ForemanTasks::Invalid::CheckOld, # if foreman-tasks
40
+ Checks::ForemanTasks::Invalid::CheckPendingState, # if foreman-tasks
41
+ Checks::ForemanTasks::Invalid::CheckPlanningState, # if foreman-tasks
42
+ Checks::ForemanTasks::NotRunning, # if foreman-tasks
43
+ Checks::NonRhPackages,
44
+ Checks::PackageManager::Dnf::ValidateDnfConfig,
45
+ Checks::Repositories::CheckNonRhRepository,
46
+ Checks::Repositories::Validate
47
+ )
48
+ end
49
+ # rubocop:enable Metrics/MethodLength
50
+ end
51
+
52
+ class PreMigrations < Abstract
53
+ update_metadata do
54
+ description 'Procedures before migrating'
55
+ tags :pre_migrations
56
+ end
57
+
58
+ def compose
59
+ add_steps(
60
+ Procedures::Packages::Update.new(
61
+ :assumeyes => true,
62
+ :dnf_options => ['--downloadonly']
63
+ ),
64
+ Procedures::MaintenanceMode::EnableMaintenanceMode,
65
+ Procedures::Crond::Stop,
66
+ Procedures::SyncPlans::Disable
67
+ )
68
+ end
69
+ end
70
+
71
+ class Migrations < Abstract
72
+ update_metadata do
73
+ description 'Migration scripts'
74
+ tags :migrations
75
+ run_strategy :fail_fast
76
+ end
77
+
78
+ def compose
79
+ add_steps(
80
+ Procedures::Service::Stop,
81
+ Procedures::Packages::Update.new(:assumeyes => true, :clean_cache => false),
82
+ Procedures::Installer::Run.new(:assumeyes => true),
83
+ Procedures::Installer::UpgradeRakeTask
84
+ )
85
+ end
86
+ end
87
+
88
+ class PostMigrations < Abstract
89
+ update_metadata do
90
+ description 'Procedures after migrating'
91
+ tags :post_migrations
92
+ end
93
+
94
+ def compose
95
+ add_steps(
96
+ Procedures::RefreshFeatures,
97
+ Procedures::Service::Start,
98
+ Procedures::Crond::Start,
99
+ Procedures::SyncPlans::Enable,
100
+ Procedures::MaintenanceMode::DisableMaintenanceMode
101
+ )
102
+ end
103
+ end
104
+
105
+ class PostUpdateChecks < Abstract
106
+ update_metadata do
107
+ description 'Checks after update'
108
+ tags :post_update_checks
109
+ run_strategy :fail_slow
110
+ end
111
+
112
+ def compose
113
+ add_steps(
114
+ Checks::Foreman::FactsNames, # if Foreman database present
115
+ Checks::ForemanProxy::CheckTftpStorage, # if Satellite with foreman-proxy+tftp
116
+ Checks::ForemanProxy::VerifyDhcpConfigSyntax, # if foreman-proxy+dhcp-isc
117
+ Checks::ForemanTasks::NotPaused, # if foreman-tasks present
118
+ Checks::Puppet::VerifyNoEmptyCacertRequests, # if puppetserver
119
+ Checks::ServerPing,
120
+ Checks::ServicesUp,
121
+ Checks::SystemRegistration,
122
+ Procedures::Packages::CheckForReboot
123
+ )
124
+ end
125
+ end
126
+ end
@@ -63,7 +63,7 @@ module Scenarios::Capsule_6_16
63
63
  end
64
64
  add_step(Procedures::Packages::Update.new(
65
65
  :assumeyes => true,
66
- :dnf_options => ['--downloadonly']
66
+ :download_only => true
67
67
  ))
68
68
  add_step(Procedures::Service::Stop.new)
69
69
  add_step(Procedures::Packages::Update.new(:assumeyes => true, :clean_cache => false))
@@ -45,7 +45,7 @@ module Scenarios::Capsule_6_16_z
45
45
  end
46
46
  add_step(Procedures::Packages::Update.new(
47
47
  :assumeyes => true,
48
- :dnf_options => ['--downloadonly']
48
+ :download_only => true
49
49
  ))
50
50
  add_steps(find_procedures(:pre_migrations))
51
51
  end
@@ -60,7 +60,7 @@ module Scenarios::Katello_Nightly
60
60
  end
61
61
  add_step(Procedures::Packages::Update.new(
62
62
  :assumeyes => true,
63
- :dnf_options => ['--downloadonly']
63
+ :download_only => true
64
64
  ))
65
65
  add_step(Procedures::Service::Stop.new)
66
66
  add_step(Procedures::Packages::Update.new(:assumeyes => true, :clean_cache => false))
@@ -65,7 +65,7 @@ module Scenarios::Satellite_6_16
65
65
  end
66
66
  add_step(Procedures::Packages::Update.new(
67
67
  :assumeyes => true,
68
- :dnf_options => ['--downloadonly']
68
+ :download_only => true
69
69
  ))
70
70
  add_step(Procedures::Service::Stop.new)
71
71
  add_step(Procedures::Packages::Update.new(:assumeyes => true, :clean_cache => false))
@@ -45,7 +45,7 @@ module Scenarios::Satellite_6_16_z
45
45
  end
46
46
  add_step(Procedures::Packages::Update.new(
47
47
  :assumeyes => true,
48
- :dnf_options => ['--downloadonly']
48
+ :download_only => true
49
49
  ))
50
50
  add_steps(find_procedures(:pre_migrations))
51
51
  end
@@ -0,0 +1,48 @@
1
+ require 'foreman_maintain/update_runner'
2
+
3
+ module ForemanMaintain
4
+ module Cli
5
+ class UpdateCommand < Base
6
+ def self.disable_self_update_option
7
+ option '--disable-self-update', :flag, 'Disable automatic self update',
8
+ :default => false
9
+ end
10
+
11
+ def update_runner
12
+ update_runner = ForemanMaintain::UpdateRunner.new(
13
+ reporter,
14
+ :assumeyes => assumeyes?,
15
+ :whitelist => whitelist || [],
16
+ :force => force?
17
+ )
18
+ update_runner.load
19
+ update_runner
20
+ end
21
+
22
+ subcommand 'check', 'Run pre-update checks before updating' do
23
+ interactive_option
24
+ disable_self_update_option
25
+
26
+ def execute
27
+ ForemanMaintain.validate_downstream_packages
28
+ ForemanMaintain.perform_self_upgrade unless disable_self_update?
29
+ update_runner.run_phase(:pre_update_checks)
30
+ exit update_runner.exit_code
31
+ end
32
+ end
33
+
34
+ subcommand 'run', 'Run an update' do
35
+ interactive_option
36
+ disable_self_update_option
37
+
38
+ def execute
39
+ ForemanMaintain.validate_downstream_packages
40
+ ForemanMaintain.perform_self_upgrade unless disable_self_update?
41
+ update_runner.run
42
+ update_runner.save
43
+ exit update_runner.exit_code
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -12,6 +12,7 @@ require 'foreman_maintain/cli/maintenance_mode_command'
12
12
  require 'foreman_maintain/cli/packages_command'
13
13
  require 'foreman_maintain/cli/plugin_command'
14
14
  require 'foreman_maintain/cli/self_upgrade_command'
15
+ require 'foreman_maintain/cli/update_command'
15
16
 
16
17
  Clamp.allow_options_after_parameters = true
17
18
 
@@ -22,6 +23,7 @@ module ForemanMaintain
22
23
 
23
24
  subcommand 'health', 'Health related commands', HealthCommand
24
25
  subcommand 'upgrade', 'Upgrade related commands', UpgradeCommand
26
+ subcommand 'update', 'Update related commands', UpdateCommand
25
27
  subcommand 'service', 'Control applicable services', ServiceCommand
26
28
  subcommand 'backup', 'Backup server', BackupCommand
27
29
  subcommand 'restore', 'Restore a backup', RestoreCommand
@@ -100,13 +100,17 @@ module ForemanMaintain
100
100
  end
101
101
 
102
102
  def packages_action(action, packages, options = {})
103
- options.validate_options!(:assumeyes, :dnf_options)
103
+ options.validate_options!(:assumeyes, :options, :download_only)
104
104
  case action
105
105
  when :install
106
106
  package_manager.install(packages, :assumeyes => options[:assumeyes])
107
107
  when :update
108
- package_manager.update(packages, :assumeyes => options[:assumeyes],
109
- :dnf_options => options[:dnf_options])
108
+ package_manager.update(
109
+ packages,
110
+ :assumeyes => options[:assumeyes],
111
+ :options => options[:options],
112
+ :download_only => options[:download_only]
113
+ )
110
114
  when :remove
111
115
  package_manager.remove(packages, :assumeyes => options[:assumeyes])
112
116
  else
@@ -138,7 +138,11 @@ module ForemanMaintain
138
138
  def __run__(execution)
139
139
  setup_execution_state(execution)
140
140
  unless skipped?
141
- run
141
+ if defined?(self.class.present?)
142
+ run if self.class.present?
143
+ else
144
+ run
145
+ end
142
146
  end
143
147
  rescue Error::Skip => e
144
148
  set_skip(e.message)
@@ -19,10 +19,12 @@ module ForemanMaintain::PackageManager
19
19
  apt_action('remove', packages, :assumeyes => assumeyes)
20
20
  end
21
21
 
22
- def update(packages = [], assumeyes: false)
22
+ # rubocop:disable Lint/UnusedMethodArgument
23
+ def update(packages = [], assumeyes: false, options: [], download_only: false)
23
24
  action = packages.any? ? '--only-upgrade install' : 'upgrade'
24
- apt_action(action, packages, :assumeyes => assumeyes)
25
+ apt_action(action, packages, :assumeyes => assumeyes, :download_only => download_only)
25
26
  end
27
+ # rubocop:enable Lint/UnusedMethodArgument
26
28
 
27
29
  def clean_cache(assumeyes: false)
28
30
  apt_action('clean', :assumeyes => assumeyes)
@@ -60,10 +62,18 @@ module ForemanMaintain::PackageManager
60
62
  false
61
63
  end
62
64
 
63
- def apt_action(action, packages, with_status: false, assumeyes: false, valid_exit_statuses: [0])
65
+ def reboot_required?
66
+ status = File.exist?('/var/run/reboot-required') ? 1 : 0
67
+ output = ''
68
+ [status, output]
69
+ end
70
+
71
+ # rubocop:disable Layout/LineLength
72
+ def apt_action(action, packages, with_status: false, assumeyes: false, valid_exit_statuses: [0], download_only: false)
64
73
  apt_options = []
65
74
  packages = [packages].flatten(1)
66
75
  apt_options << '-y' if assumeyes
76
+ apt_options << '--download-only' if download_only
67
77
  apt_options_s = apt_options.empty? ? '' : ' ' + apt_options.join(' ')
68
78
  packages_s = packages.empty? ? '' : ' ' + packages.join(' ')
69
79
  if with_status
@@ -74,5 +84,6 @@ module ForemanMaintain::PackageManager
74
84
  :interactive => !assumeyes, :valid_exit_statuses => valid_exit_statuses)
75
85
  end
76
86
  end
87
+ # rubocop:enable Layout/LineLength
77
88
  end
78
89
  end
@@ -59,8 +59,14 @@ module ForemanMaintain::PackageManager
59
59
  dnf_action('remove', packages, assumeyes: assumeyes)
60
60
  end
61
61
 
62
- def update(packages = [], assumeyes: false, dnf_options: [])
63
- dnf_action('update', packages, assumeyes: assumeyes, dnf_options: dnf_options)
62
+ def update(packages = [], assumeyes: false, options: [], download_only: false)
63
+ dnf_action(
64
+ 'update',
65
+ packages,
66
+ assumeyes: assumeyes,
67
+ dnf_options: options,
68
+ download_only: download_only
69
+ )
64
70
  end
65
71
 
66
72
  def check_update(packages: nil, with_status: false)
@@ -121,13 +127,18 @@ module ForemanMaintain::PackageManager
121
127
  dnf_action('module info', name, with_status: true, assumeyes: true)
122
128
  end
123
129
 
130
+ def reboot_required?
131
+ sys.execute_with_status('dnf needs-restarting --reboothint', :interactive => false)
132
+ end
133
+
124
134
  private
125
135
 
126
- # rubocop:disable Metrics/LineLength, Metrics/ParameterLists
127
- def dnf_action(action, packages, with_status: false, assumeyes: false, dnf_options: [], valid_exit_statuses: [0])
136
+ # rubocop:disable Layout/LineLength, Metrics/ParameterLists
137
+ def dnf_action(action, packages, with_status: false, assumeyes: false, dnf_options: [], valid_exit_statuses: [0], download_only: false)
128
138
  packages = [packages].flatten(1)
129
139
 
130
140
  dnf_options << '-y' if assumeyes
141
+ dnf_topions << '--downloadonly' if download_only
131
142
  dnf_options << '--disableplugin=foreman-protector'
132
143
 
133
144
  command = ['dnf', dnf_options.join(' '), action]
@@ -148,7 +159,7 @@ module ForemanMaintain::PackageManager
148
159
  )
149
160
  end
150
161
  end
151
- # rubocop:enable Metrics/LineLength, Metrics/ParameterLists
162
+ # rubocop:enable Layout/LineLength, Metrics/ParameterLists
152
163
 
153
164
  def protector_config
154
165
  File.exist?(protector_config_file) ? File.read(protector_config_file) : ''
@@ -163,14 +163,14 @@ module ForemanMaintain
163
163
  scenarios
164
164
  end
165
165
 
166
- def add_steps(steps)
167
- steps.each do |step|
166
+ def add_steps(*steps)
167
+ steps.flatten.each do |step|
168
168
  self.steps << step.ensure_instance
169
169
  end
170
170
  end
171
171
 
172
172
  def add_step(step)
173
- add_steps([step]) unless step.nil?
173
+ add_steps(step) unless step.nil?
174
174
  end
175
175
 
176
176
  def add_step_with_context(definition, extra_params = {})
@@ -0,0 +1,156 @@
1
+ module ForemanMaintain
2
+ class UpdateRunner < Runner
3
+ include Concerns::Finders
4
+
5
+ PHASES = [
6
+ :pre_update_checks,
7
+ :pre_migrations,
8
+ :migrations,
9
+ :post_migrations,
10
+ :post_update_checks,
11
+ ].freeze
12
+
13
+ attr_reader :phase
14
+
15
+ def initialize(reporter, options = {})
16
+ super(reporter, [], options)
17
+ @scenario_cache = {}
18
+ self.phase = :pre_update_checks
19
+ end
20
+
21
+ def find_scenario(phase)
22
+ return @scenario_cache[phase] if @scenario_cache.key?(phase)
23
+
24
+ condition = { :tags => [:update_scenario, phase] }
25
+ matching_scenarios = find_scenarios(condition)
26
+ @scenario_cache[phase] = matching_scenarios.first
27
+ end
28
+
29
+ def run
30
+ PHASES.each do |phase|
31
+ return run_rollback if quit?
32
+
33
+ run_phase(phase)
34
+ end
35
+
36
+ finish_update unless quit?
37
+ end
38
+
39
+ def run_rollback
40
+ # we only are able to rollback from pre_migrations phase
41
+ if phase == :pre_migrations
42
+ rollback_pre_migrations
43
+ end
44
+ end
45
+
46
+ def finish_update
47
+ @finished = true
48
+ @reporter.hline
49
+ @reporter.puts("Update finished.")
50
+ end
51
+
52
+ def storage
53
+ ForemanMaintain.storage("update")
54
+ end
55
+
56
+ # serializes the state of the run to storage
57
+ def save
58
+ if @finished
59
+ storage.delete(:serialized)
60
+ else
61
+ storage[:serialized] = to_hash
62
+ end
63
+ storage.save
64
+ end
65
+
66
+ # deserializes the state of the run from the storage
67
+ def load
68
+ return unless storage[:serialized]
69
+
70
+ load_from_hash(storage[:serialized])
71
+ end
72
+
73
+ def run_phase(phase)
74
+ scenario = find_scenario(phase)
75
+ return if scenario.nil? || scenario.steps.empty?
76
+
77
+ confirm_scenario(scenario)
78
+ return if quit?
79
+
80
+ self.phase = phase
81
+ run_scenario(scenario)
82
+ # if we started from the :pre_update_checks, ensure to ask before
83
+ # continuing with the rest of the update
84
+ @ask_to_confirm_update = phase == :pre_update_checks
85
+ end
86
+
87
+ private
88
+
89
+ def rollback_pre_migrations
90
+ raise "Unexpected phase #{phase}, expecting pre_migrations" unless phase == :pre_migrations
91
+
92
+ rollback_needed = scenario(:pre_migrations).steps.any? { |s| s.executed? && s.success? }
93
+ if rollback_needed
94
+ @quit = false
95
+ # prevent the unnecessary confirmation questions
96
+ @last_scenario = nil
97
+ @last_scenario_continuation_confirmed = true
98
+ [:post_migrations, :post_update_checks].each do |phase|
99
+ run_phase(phase)
100
+ end
101
+ end
102
+ self.phase = :pre_update_checks # rollback finished
103
+ @reporter.puts("The update failed and system was restored to pre-update state.")
104
+ end
105
+
106
+ def with_non_empty_scenario(phase)
107
+ next_scenario = scenario(phase)
108
+ unless next_scenario.nil? || next_scenario.steps.empty?
109
+ yield next_scenario
110
+ end
111
+ end
112
+
113
+ def to_hash
114
+ ret = { :phase => phase, :scenarios => {} }
115
+ @scenario_cache.each do |key, scenario|
116
+ ret[:scenarios][key] = scenario.to_hash
117
+ end
118
+ ret
119
+ end
120
+
121
+ def load_from_hash(hash)
122
+ unless @scenario_cache.empty?
123
+ raise "Some scenarios are already initialized: #{@scenario_cache.keys}"
124
+ end
125
+
126
+ self.phase = hash[:phase]
127
+ hash[:scenarios].each do |key, scenario_hash|
128
+ @scenario_cache[key] = Scenario.new_from_hash(scenario_hash)
129
+ end
130
+ end
131
+
132
+ def confirm_scenario(scenario)
133
+ decision = super(scenario)
134
+ # we have not asked the user already about next steps
135
+ if decision.nil? && @ask_to_confirm_update
136
+ response = reporter.ask_decision(<<-MESSAGE.strip_heredoc.strip)
137
+ The pre-update checks indicate that the system is ready for update.
138
+ It's recommended to perform a backup at this stage.
139
+ Confirm to continue with the modification part of the update
140
+ MESSAGE
141
+ if [:no, :quit].include?(response)
142
+ ask_to_quit
143
+ end
144
+ end
145
+ response
146
+ ensure
147
+ @ask_to_confirm_update = false
148
+ end
149
+
150
+ def phase=(phase)
151
+ raise "Unknown phase #{phase}" unless PHASES.include?(phase)
152
+
153
+ @phase = phase
154
+ end
155
+ end
156
+ end
@@ -63,6 +63,14 @@ module ForemanMaintain::Utils
63
63
  end
64
64
  end
65
65
 
66
+ def matches?(service)
67
+ if service.is_a? String
68
+ service == @name || File.fnmatch(service, @name)
69
+ else
70
+ super
71
+ end
72
+ end
73
+
66
74
  private
67
75
 
68
76
  def execute(action)
@@ -1,3 +1,3 @@
1
1
  module ForemanMaintain
2
- VERSION = '1.6.4'.freeze
2
+ VERSION = '1.6.5'.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: 1.6.4
4
+ version: 1.6.5
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: 2024-04-17 00:00:00.000000000 Z
11
+ date: 2024-04-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clamp
@@ -316,6 +316,7 @@ files:
316
316
  - definitions/scenarios/restore.rb
317
317
  - definitions/scenarios/self_upgrade.rb
318
318
  - definitions/scenarios/services.rb
319
+ - definitions/scenarios/update.rb
319
320
  - definitions/scenarios/upgrade_to_capsule_6_16.rb
320
321
  - definitions/scenarios/upgrade_to_capsule_6_16_z.rb
321
322
  - definitions/scenarios/upgrade_to_foreman_nightly.rb
@@ -346,6 +347,7 @@ files:
346
347
  - lib/foreman_maintain/cli/self_upgrade_command.rb
347
348
  - lib/foreman_maintain/cli/service_command.rb
348
349
  - lib/foreman_maintain/cli/transform_clamp_options.rb
350
+ - lib/foreman_maintain/cli/update_command.rb
349
351
  - lib/foreman_maintain/cli/upgrade_command.rb
350
352
  - lib/foreman_maintain/concerns/base_database.rb
351
353
  - lib/foreman_maintain/concerns/directory_marker.rb
@@ -391,6 +393,7 @@ files:
391
393
  - lib/foreman_maintain/runner/stored_execution.rb
392
394
  - lib/foreman_maintain/scenario.rb
393
395
  - lib/foreman_maintain/top_level_modules.rb
396
+ - lib/foreman_maintain/update_runner.rb
394
397
  - lib/foreman_maintain/upgrade_runner.rb
395
398
  - lib/foreman_maintain/utils.rb
396
399
  - lib/foreman_maintain/utils/backup.rb
@@ -433,7 +436,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
433
436
  - !ruby/object:Gem::Version
434
437
  version: '0'
435
438
  requirements: []
436
- rubygems_version: 3.3.26
439
+ rubygems_version: 3.3.27
437
440
  signing_key:
438
441
  specification_version: 4
439
442
  summary: Foreman maintenance tool belt