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 +4 -4
- data/definitions/checks/repositories/validate.rb +3 -1
- data/definitions/procedures/packages/check_for_reboot.rb +1 -1
- data/definitions/procedures/packages/update.rb +7 -6
- data/definitions/procedures/packages/update_all_confirmation.rb +0 -2
- data/definitions/scenarios/packages.rb +6 -12
- data/definitions/scenarios/update.rb +126 -0
- data/definitions/scenarios/upgrade_to_capsule_6_16.rb +1 -1
- data/definitions/scenarios/upgrade_to_capsule_6_16_z.rb +1 -1
- data/definitions/scenarios/upgrade_to_katello_nightly.rb +1 -1
- data/definitions/scenarios/upgrade_to_satellite_6_16.rb +1 -1
- data/definitions/scenarios/upgrade_to_satellite_6_16_z.rb +1 -1
- data/lib/foreman_maintain/cli/update_command.rb +48 -0
- data/lib/foreman_maintain/cli.rb +2 -0
- data/lib/foreman_maintain/concerns/system_helpers.rb +7 -3
- data/lib/foreman_maintain/executable.rb +5 -1
- data/lib/foreman_maintain/package_manager/apt.rb +14 -3
- data/lib/foreman_maintain/package_manager/dnf.rb +16 -5
- data/lib/foreman_maintain/scenario.rb +3 -3
- data/lib/foreman_maintain/update_runner.rb +156 -0
- data/lib/foreman_maintain/utils/service/systemd.rb +8 -0
- data/lib/foreman_maintain/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9832b114fa0e778b687140d47774ffa583742e69c0883f7e0738fad23e6d0f87
|
4
|
+
data.tar.gz: dfd33002a93b7171aab581342c169d0eef6cee318302bad7d24108581e05b514
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 =>
|
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
|
@@ -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 = {
|
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
|
-
:
|
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))
|
@@ -60,7 +60,7 @@ module Scenarios::Katello_Nightly
|
|
60
60
|
end
|
61
61
|
add_step(Procedures::Packages::Update.new(
|
62
62
|
:assumeyes => true,
|
63
|
-
:
|
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
|
-
:
|
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))
|
@@ -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
|
data/lib/foreman_maintain/cli.rb
CHANGED
@@ -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, :
|
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(
|
109
|
-
|
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
|
-
|
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
|
-
|
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
|
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,
|
63
|
-
dnf_action(
|
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
|
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
|
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(
|
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
|
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
|
+
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-
|
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.
|
439
|
+
rubygems_version: 3.3.27
|
437
440
|
signing_key:
|
438
441
|
specification_version: 4
|
439
442
|
summary: Foreman maintenance tool belt
|