foreman_maintain 1.4.0 → 1.4.1
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/README.md +1 -1
- data/definitions/checks/check_hotfix_installed.rb +2 -3
- data/definitions/checks/disk/performance.rb +1 -2
- data/definitions/checks/package_manager/{yum/validate_yum_config.rb → dnf/validate_dnf_config.rb} +13 -11
- data/definitions/checks/repositories/check_upstream_repository.rb +1 -2
- data/definitions/features/installer.rb +8 -66
- data/definitions/features/instance.rb +0 -6
- data/definitions/procedures/backup/metadata.rb +5 -3
- data/definitions/procedures/packages/installer_confirmation.rb +1 -1
- data/definitions/procedures/packages/update.rb +3 -3
- data/definitions/scenarios/backup.rb +1 -6
- data/definitions/scenarios/self_upgrade.rb +4 -6
- data/definitions/scenarios/upgrade_to_capsule_6_15.rb +1 -2
- data/definitions/scenarios/upgrade_to_capsule_6_15_z.rb +1 -2
- data/definitions/scenarios/upgrade_to_katello_nightly.rb +1 -1
- data/definitions/scenarios/upgrade_to_satellite_6_15.rb +1 -2
- data/definitions/scenarios/upgrade_to_satellite_6_15_z.rb +1 -2
- data/extras/foreman_protector/foreman-protector.conf +1 -1
- data/lib/foreman_maintain/concerns/base_database.rb +0 -41
- data/lib/foreman_maintain/concerns/system_helpers.rb +2 -2
- data/lib/foreman_maintain/config.rb +5 -1
- data/lib/foreman_maintain/package_manager/dnf.rb +138 -11
- data/lib/foreman_maintain/package_manager.rb +0 -1
- data/lib/foreman_maintain/repository_manager/el.rb +2 -2
- data/lib/foreman_maintain/version.rb +1 -1
- metadata +3 -12
- data/definitions/checks/backup/directory_ready.rb +0 -23
- data/definitions/checks/foreman/check_checkpoint_segments.rb +0 -59
- data/definitions/checks/foreman/check_duplicate_roles.rb +0 -42
- data/definitions/checks/foreman/puppet_class_duplicates.rb +0 -48
- data/definitions/checks/original_assets.rb +0 -23
- data/definitions/procedures/foreman/apipie_cache.rb +0 -12
- data/definitions/procedures/foreman_docker/remove_foreman_docker.rb +0 -16
- data/extras/foreman_protector/yum/foreman-protector.py +0 -86
- data/lib/foreman_maintain/package_manager/yum.rb +0 -142
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a742f6c45bf5c57c814ba78f83ff3fb72863de35005f0e8f34a6f823de766ba5
|
4
|
+
data.tar.gz: be8eb54fe3eb4d9a05d59f64ad34fc314ae97fc4be47c1aeaf4cde3b0d46b979
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4cb48844ead00af99f66d37ee2a215fe9c397f14b544774580ad5df3dc09598231f5a8a7978fbc2111bb104daa951f1d3c6a1dc2426c2f635e319ded93117e6f
|
7
|
+
data.tar.gz: 7c0cea08c66ea928e2fa6659dd051d55c4ab0e9afabba61c18ad9934b1a21fd1b177d7f765e58a2885927103daf92ba8d05513d2fc0f386ec2900e546afa3cbc
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Foreman Maintain [](https://github.com/theforeman/foreman_maintain/actions/workflows/ruby_tests.yml) <a href="https://codeclimate.com/github/theforeman/foreman_maintain"><img src="https://codeclimate.com/github/theforeman/foreman_maintain/badges/gpa.svg" /></a>
|
2
2
|
|
3
3
|
The `foreman_maintain` aims to provide various features that helps keep the
|
4
4
|
Foreman/Satellite up and running. It supports multiple versions and subparts
|
@@ -4,8 +4,7 @@ class Checks::CheckHotfixInstalled < ForemanMaintain::Check
|
|
4
4
|
description 'Check to verify if any hotfix installed on system'
|
5
5
|
tags :pre_upgrade
|
6
6
|
preparation_steps do
|
7
|
-
[Checks::Repositories::CheckNonRhRepository.new
|
8
|
-
Procedures::Packages::Install.new(:packages => %w[yum-utils])]
|
7
|
+
[Checks::Repositories::CheckNonRhRepository.new]
|
9
8
|
end
|
10
9
|
|
11
10
|
confine do
|
@@ -45,7 +44,7 @@ class Checks::CheckHotfixInstalled < ForemanMaintain::Check
|
|
45
44
|
|
46
45
|
def installed_packages
|
47
46
|
packages = []
|
48
|
-
IO.popen(['repoquery', '-a', '--installed', '--qf', query_format]) do |io|
|
47
|
+
IO.popen(['dnf', 'repoquery', '-a', '--installed', '--qf', query_format]) do |io|
|
49
48
|
io.each do |line|
|
50
49
|
repo, pkg = line.chomp.split
|
51
50
|
next if repo.nil? || pkg.nil?
|
@@ -30,8 +30,7 @@ module Checks
|
|
30
30
|
puts "\n"
|
31
31
|
puts stats.stdout
|
32
32
|
|
33
|
-
|
34
|
-
if current_downstream_feature&.at_least_version?('6.3')
|
33
|
+
if feature(:instance).downstream
|
35
34
|
assert(success, io_obj.slow_disk_error_msg + warning_message, :warn => true)
|
36
35
|
else
|
37
36
|
assert(success, io_obj.slow_disk_error_msg)
|
data/definitions/checks/package_manager/{yum/validate_yum_config.rb → dnf/validate_dnf_config.rb}
RENAMED
@@ -1,9 +1,9 @@
|
|
1
1
|
module Checks::PackageManager
|
2
|
-
module
|
3
|
-
class
|
2
|
+
module Dnf
|
3
|
+
class ValidateDnfConfig < ForemanMaintain::Check
|
4
4
|
metadata do
|
5
|
-
label :
|
6
|
-
description 'Check to validate
|
5
|
+
label :validate_dnf_config
|
6
|
+
description 'Check to validate dnf configuration before upgrade'
|
7
7
|
tags :pre_upgrade
|
8
8
|
end
|
9
9
|
|
@@ -17,30 +17,32 @@ module Checks::PackageManager
|
|
17
17
|
|
18
18
|
private
|
19
19
|
|
20
|
+
# rubocop:disable Metrics/LineLength
|
20
21
|
def failure_message(final_result)
|
21
22
|
verb_string = final_result[:matched_keys].length > 1 ? 'are' : 'is'
|
22
23
|
|
23
|
-
"#{final_result[:matched_keys].join(',')} #{verb_string} set in /etc/
|
24
|
+
"#{final_result[:matched_keys].join(',')} #{verb_string} set in /etc/dnf/dnf.conf as below:"\
|
24
25
|
"\n#{final_result[:grep_output]}"\
|
25
|
-
"\nUnset this configuration as it is risky while
|
26
|
+
"\nUnset this configuration as it is risky while dnf update or upgrade!"
|
26
27
|
end
|
28
|
+
# rubocop:enable Metrics/LineLength
|
27
29
|
|
28
30
|
def verify_config_options
|
29
31
|
result = {}
|
30
|
-
combined_regex =
|
32
|
+
combined_regex = dnf_config_options.values.join('|')
|
31
33
|
result[:grep_output] = execute_grep_cmd(combined_regex)
|
32
|
-
result[:matched_keys] =
|
34
|
+
result[:matched_keys] = dnf_config_options.keys.select do |key|
|
33
35
|
result[:grep_output].include?(key)
|
34
36
|
end
|
35
37
|
result
|
36
38
|
end
|
37
39
|
|
38
40
|
def execute_grep_cmd(regex_string)
|
39
|
-
execute_with_status("grep -iE '#{regex_string}' /etc/
|
41
|
+
execute_with_status("grep -iE '#{regex_string}' /etc/dnf/dnf.conf")[1]
|
40
42
|
end
|
41
43
|
|
42
|
-
def
|
43
|
-
@
|
44
|
+
def dnf_config_options
|
45
|
+
@dnf_config_options ||= {
|
44
46
|
'exclude' => '^exclude\s*=\s*\S+.*$',
|
45
47
|
}
|
46
48
|
end
|
@@ -6,8 +6,7 @@ class Checks::CheckUpstreamRepository < ForemanMaintain::Check
|
|
6
6
|
description 'Check if any upstream repositories are enabled on system'
|
7
7
|
tags :pre_upgrade
|
8
8
|
preparation_steps do
|
9
|
-
[Checks::Repositories::CheckNonRhRepository.new
|
10
|
-
Procedures::Packages::Install.new(:packages => %w[yum-utils])]
|
9
|
+
[Checks::Repositories::CheckNonRhRepository.new]
|
11
10
|
end
|
12
11
|
confine do
|
13
12
|
feature(:instance).downstream
|
@@ -3,22 +3,10 @@ class Features::Installer < ForemanMaintain::Feature
|
|
3
3
|
label :installer
|
4
4
|
|
5
5
|
confine do
|
6
|
-
find_package('foreman-installer')
|
7
|
-
find_package('katello-installer') ||
|
8
|
-
find_package('capsule-installer')
|
6
|
+
find_package('foreman-installer')
|
9
7
|
end
|
10
8
|
end
|
11
9
|
|
12
|
-
def initialize
|
13
|
-
@installer_type = if find_package('foreman-installer')
|
14
|
-
:scenarios
|
15
|
-
elsif find_package('katello-installer')
|
16
|
-
:legacy_katello
|
17
|
-
elsif find_package('capsule-installer')
|
18
|
-
:legacy_capsule
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
10
|
def answers
|
23
11
|
load_answers(configuration)
|
24
12
|
end
|
@@ -28,39 +16,17 @@ class Features::Installer < ForemanMaintain::Feature
|
|
28
16
|
end
|
29
17
|
|
30
18
|
def config_file
|
31
|
-
|
32
|
-
when :scenarios
|
33
|
-
last_scenario_config
|
34
|
-
when :legacy_katello
|
35
|
-
File.join(config_directory, 'katello-installer.yaml')
|
36
|
-
when :legacy_capsule
|
37
|
-
File.join(config_directory, 'capsule-installer.yaml')
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def with_scenarios?
|
42
|
-
@installer_type == :scenarios
|
19
|
+
last_scenario_config
|
43
20
|
end
|
44
21
|
|
45
22
|
def config_directory
|
46
|
-
|
47
|
-
when :scenarios
|
48
|
-
'/etc/foreman-installer'
|
49
|
-
when :legacy_katello
|
50
|
-
'/etc/katello-installer'
|
51
|
-
when :legacy_capsule
|
52
|
-
'/etc/capsule-installer'
|
53
|
-
end
|
23
|
+
'/etc/foreman-installer'
|
54
24
|
end
|
55
25
|
|
56
26
|
def custom_hiera_file
|
57
27
|
@custom_hiera_file ||= File.join(config_directory, 'custom-hiera.yaml')
|
58
28
|
end
|
59
29
|
|
60
|
-
def can_upgrade?
|
61
|
-
@installer_type == :scenarios || @installer_type == :legacy_katello
|
62
|
-
end
|
63
|
-
|
64
30
|
def config_files
|
65
31
|
Dir.glob(File.join(config_directory, '**/*')) +
|
66
32
|
[
|
@@ -71,23 +37,14 @@ class Features::Installer < ForemanMaintain::Feature
|
|
71
37
|
end
|
72
38
|
|
73
39
|
def last_scenario
|
74
|
-
return nil unless with_scenarios?
|
75
|
-
|
76
40
|
File.basename(last_scenario_config).split('.')[0]
|
77
41
|
end
|
78
42
|
|
79
43
|
def installer_command
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
else
|
85
|
-
'foreman-installer'
|
86
|
-
end
|
87
|
-
when :legacy_katello
|
88
|
-
'katello-installer'
|
89
|
-
when :legacy_capsule
|
90
|
-
'capsule-installer'
|
44
|
+
if feature(:satellite)
|
45
|
+
'satellite-installer'
|
46
|
+
else
|
47
|
+
'foreman-installer'
|
91
48
|
end
|
92
49
|
end
|
93
50
|
|
@@ -105,22 +62,7 @@ class Features::Installer < ForemanMaintain::Feature
|
|
105
62
|
end
|
106
63
|
|
107
64
|
def upgrade(exec_options = {})
|
108
|
-
run(
|
109
|
-
end
|
110
|
-
|
111
|
-
def installer_arguments
|
112
|
-
installer_args = ''
|
113
|
-
|
114
|
-
if feature(:foreman_proxy)&.with_content? &&
|
115
|
-
check_max_version('foreman-installer', '3.4')
|
116
|
-
installer_args += ' --disable-system-checks'
|
117
|
-
end
|
118
|
-
|
119
|
-
if !check_min_version('foreman-installer', '2.1') && can_upgrade?
|
120
|
-
installer_args += ' --upgrade'
|
121
|
-
end
|
122
|
-
|
123
|
-
installer_args
|
65
|
+
run('', exec_options)
|
124
66
|
end
|
125
67
|
|
126
68
|
def initial_admin_username
|
@@ -139,12 +139,6 @@ class Features::Instance < ForemanMaintain::Feature
|
|
139
139
|
end
|
140
140
|
|
141
141
|
def pick_failing_components(components)
|
142
|
-
if feature(:katello).current_version < Gem::Version.new('3.2.0')
|
143
|
-
# Note that katello_ping returns an empty result against foreman_auth.
|
144
|
-
# https://github.com/Katello/katello/commit/95d7b9067d38f269a5ec121fb73b5c19d4422baf
|
145
|
-
components.reject! { |n| n.eql?('foreman_auth') }
|
146
|
-
end
|
147
|
-
|
148
142
|
components.each_with_object([]) do |(name, data), failing|
|
149
143
|
failing << name unless data['status'] == 'ok'
|
150
144
|
end
|
@@ -64,9 +64,11 @@ module Procedures::Backup
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def proxy_config(spinner)
|
67
|
-
|
68
|
-
|
69
|
-
|
67
|
+
if feature(:installer)
|
68
|
+
spinner.update('Collecting proxy configuration')
|
69
|
+
feature(:installer).answers['foreman_proxy'].select do |key, _|
|
70
|
+
PROXY_CONFIG_ENTRIES.include?(key)
|
71
|
+
end
|
70
72
|
end
|
71
73
|
end
|
72
74
|
end
|
@@ -6,7 +6,7 @@ module Procedures::Packages
|
|
6
6
|
|
7
7
|
def run
|
8
8
|
question = "\nWARNING: This script runs #{feature(:installer).installer_command} " \
|
9
|
-
"after the
|
9
|
+
"after the dnf execution \n" \
|
10
10
|
"to ensure the #{feature(:instance).product_name} " \
|
11
11
|
"is in a consistent state.\n" \
|
12
12
|
"As a result some of your services may be restarted. \n\n" \
|
@@ -6,13 +6,13 @@ module Procedures::Packages
|
|
6
6
|
param :force, 'Do not skip if package is installed', :flag => true, :default => false
|
7
7
|
param :warn_on_errors, 'Do not interrupt scenario on failure',
|
8
8
|
:flag => true, :default => false
|
9
|
-
param :
|
9
|
+
param :dnf_options, 'Extra dnf options if any', :array => true, :default => []
|
10
10
|
end
|
11
11
|
|
12
12
|
def run
|
13
13
|
assumeyes_val = @assumeyes.nil? ? assumeyes? : @assumeyes
|
14
14
|
package_manager.clean_cache(:assumeyes => assumeyes_val)
|
15
|
-
opts = { :assumeyes => assumeyes_val, :
|
15
|
+
opts = { :assumeyes => assumeyes_val, :dnf_options => @dnf_options }
|
16
16
|
packages_action(:update, @packages, opts)
|
17
17
|
rescue ForemanMaintain::Error::ExecutionError => e
|
18
18
|
if @warn_on_errors
|
@@ -27,7 +27,7 @@ module Procedures::Packages
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def description
|
30
|
-
if @
|
30
|
+
if @dnf_options.include?('--downloadonly')
|
31
31
|
"Download package(s) #{@packages.join(', ')}"
|
32
32
|
else
|
33
33
|
"Update package(s) #{@packages.join(', ')}"
|
@@ -25,7 +25,7 @@ module ForemanMaintain::Scenarios
|
|
25
25
|
accessibility_confirmation
|
26
26
|
prepare_directory
|
27
27
|
logical_volume_confirmation
|
28
|
-
add_step_with_context(Procedures::Backup::Metadata)
|
28
|
+
add_step_with_context(Procedures::Backup::Metadata, :online_backup => online_backup?)
|
29
29
|
|
30
30
|
case strategy
|
31
31
|
when :online
|
@@ -49,7 +49,6 @@ module ForemanMaintain::Scenarios
|
|
49
49
|
# rubocop:disable Metrics/MethodLength
|
50
50
|
def set_context_mapping
|
51
51
|
context.map(:backup_dir,
|
52
|
-
Checks::Backup::DirectoryReady => :backup_dir,
|
53
52
|
Procedures::Backup::PrepareDirectory => :backup_dir,
|
54
53
|
Procedures::Backup::Metadata => :backup_dir,
|
55
54
|
Procedures::Backup::ConfigFiles => :backup_dir,
|
@@ -66,7 +65,6 @@ module ForemanMaintain::Scenarios
|
|
66
65
|
Procedures::Backup::Snapshot::MountForemanDB => :backup_dir,
|
67
66
|
Procedures::Backup::Snapshot::MountPulpcoreDB => :backup_dir)
|
68
67
|
context.map(:preserve_dir,
|
69
|
-
Checks::Backup::DirectoryReady => :preserve_dir,
|
70
68
|
Procedures::Backup::PrepareDirectory => :preserve_dir)
|
71
69
|
context.map(:incremental_dir,
|
72
70
|
Procedures::Backup::PrepareDirectory => :incremental_dir,
|
@@ -104,8 +102,6 @@ module ForemanMaintain::Scenarios
|
|
104
102
|
|
105
103
|
def prepare_directory
|
106
104
|
add_step_with_context(Procedures::Backup::PrepareDirectory)
|
107
|
-
add_step_with_context(Checks::Backup::DirectoryReady,
|
108
|
-
:postgres_access => online_backup? || include_db_dumps?)
|
109
105
|
end
|
110
106
|
|
111
107
|
def logical_volume_confirmation
|
@@ -199,7 +195,6 @@ module ForemanMaintain::Scenarios
|
|
199
195
|
Procedures::Backup::Online::ForemanDB,
|
200
196
|
Procedures::Backup::Online::PulpcoreDB
|
201
197
|
)
|
202
|
-
add_step_with_context(Procedures::Backup::Metadata, :online_backup => true)
|
203
198
|
end
|
204
199
|
|
205
200
|
def strategy
|
@@ -67,13 +67,11 @@ module ForemanMaintain::Scenarios
|
|
67
67
|
def downstream_self_upgrade(pkgs_to_update)
|
68
68
|
ForemanMaintain.enable_maintenance_module
|
69
69
|
|
70
|
-
|
71
|
-
|
72
|
-
"--enablerepo=#{id}"
|
73
|
-
end
|
74
|
-
add_step(Procedures::Packages::Update.new(packages: pkgs_to_update, assumeyes: true,
|
75
|
-
yum_options: yum_options))
|
70
|
+
dnf_options = req_repos_to_update_pkgs.map do |id|
|
71
|
+
"--enablerepo=#{id}"
|
76
72
|
end
|
73
|
+
add_step(Procedures::Packages::Update.new(packages: pkgs_to_update, assumeyes: true,
|
74
|
+
dnf_options: dnf_options))
|
77
75
|
end
|
78
76
|
|
79
77
|
def upstream_self_upgrade(pkgs_to_update)
|
@@ -27,7 +27,6 @@ module Scenarios::Capsule_6_15
|
|
27
27
|
def compose
|
28
28
|
add_steps(find_checks(:default))
|
29
29
|
add_steps(find_checks(:pre_upgrade))
|
30
|
-
add_step(Checks::Foreman::CheckpointSegments)
|
31
30
|
add_step(Checks::Repositories::Validate.new(:version => '6.15'))
|
32
31
|
end
|
33
32
|
end
|
@@ -58,7 +57,7 @@ module Scenarios::Capsule_6_15
|
|
58
57
|
modules_to_enable = ["satellite-capsule:#{el_short_name}"]
|
59
58
|
add_step(Procedures::Packages::EnableModules.new(:module_names => modules_to_enable))
|
60
59
|
add_step(Procedures::Packages::Update.new(:assumeyes => true,
|
61
|
-
:
|
60
|
+
:dnf_options => ['--downloadonly']))
|
62
61
|
add_step(Procedures::Service::Stop.new)
|
63
62
|
add_step(Procedures::Packages::Update.new(:assumeyes => true))
|
64
63
|
add_step_with_context(Procedures::Installer::Upgrade)
|
@@ -27,7 +27,6 @@ module Scenarios::Capsule_6_15_z
|
|
27
27
|
def compose
|
28
28
|
add_steps(find_checks(:default))
|
29
29
|
add_steps(find_checks(:pre_upgrade))
|
30
|
-
add_step(Checks::Foreman::CheckpointSegments)
|
31
30
|
add_step(Checks::Repositories::Validate.new(:version => '6.15'))
|
32
31
|
end
|
33
32
|
end
|
@@ -58,7 +57,7 @@ module Scenarios::Capsule_6_15_z
|
|
58
57
|
modules_to_enable = ["satellite-capsule:#{el_short_name}"]
|
59
58
|
add_step(Procedures::Packages::EnableModules.new(:module_names => modules_to_enable))
|
60
59
|
add_step(Procedures::Packages::Update.new(:assumeyes => true,
|
61
|
-
:
|
60
|
+
:dnf_options => ['--downloadonly']))
|
62
61
|
add_step(Procedures::Service::Stop.new)
|
63
62
|
add_step(Procedures::Packages::Update.new(:assumeyes => true))
|
64
63
|
add_step_with_context(Procedures::Installer::Upgrade)
|
@@ -55,7 +55,7 @@ module Scenarios::Katello_Nightly
|
|
55
55
|
modules_to_enable = ["katello:#{el_short_name}", "pulpcore:#{el_short_name}"]
|
56
56
|
add_step(Procedures::Packages::EnableModules.new(:module_names => modules_to_enable))
|
57
57
|
add_step(Procedures::Packages::Update.new(:assumeyes => true,
|
58
|
-
:
|
58
|
+
:dnf_options => ['--downloadonly']))
|
59
59
|
add_step(Procedures::Service::Stop.new)
|
60
60
|
add_step(Procedures::Packages::Update.new(:assumeyes => true))
|
61
61
|
add_step_with_context(Procedures::Installer::Upgrade)
|
@@ -27,7 +27,6 @@ module Scenarios::Satellite_6_15
|
|
27
27
|
def compose
|
28
28
|
add_steps(find_checks(:default))
|
29
29
|
add_steps(find_checks(:pre_upgrade))
|
30
|
-
add_step(Checks::Foreman::CheckpointSegments)
|
31
30
|
add_step(Checks::Repositories::Validate.new(:version => '6.15'))
|
32
31
|
end
|
33
32
|
end
|
@@ -59,7 +58,7 @@ module Scenarios::Satellite_6_15
|
|
59
58
|
modules_to_enable = ["satellite:#{el_short_name}"]
|
60
59
|
add_step(Procedures::Packages::EnableModules.new(:module_names => modules_to_enable))
|
61
60
|
add_step(Procedures::Packages::Update.new(:assumeyes => true,
|
62
|
-
:
|
61
|
+
:dnf_options => ['--downloadonly']))
|
63
62
|
add_step(Procedures::Service::Stop.new)
|
64
63
|
add_step(Procedures::Packages::Update.new(:assumeyes => true))
|
65
64
|
add_step_with_context(Procedures::Installer::Upgrade)
|
@@ -27,7 +27,6 @@ module Scenarios::Satellite_6_15_z
|
|
27
27
|
def compose
|
28
28
|
add_steps(find_checks(:default))
|
29
29
|
add_steps(find_checks(:pre_upgrade))
|
30
|
-
add_step(Checks::Foreman::CheckpointSegments)
|
31
30
|
add_step(Checks::Repositories::Validate.new(:version => '6.15'))
|
32
31
|
end
|
33
32
|
end
|
@@ -58,7 +57,7 @@ module Scenarios::Satellite_6_15_z
|
|
58
57
|
modules_to_enable = ["satellite:#{el_short_name}"]
|
59
58
|
add_step(Procedures::Packages::EnableModules.new(:module_names => modules_to_enable))
|
60
59
|
add_step(Procedures::Packages::Update.new(:assumeyes => true,
|
61
|
-
:
|
60
|
+
:dnf_options => ['--downloadonly']))
|
62
61
|
add_step(Procedures::Service::Stop.new)
|
63
62
|
add_step(Procedures::Packages::Update.new(:assumeyes => true))
|
64
63
|
add_step_with_context(Procedures::Installer::Upgrade)
|
@@ -75,11 +75,6 @@ module ForemanMaintain
|
|
75
75
|
:hidden_patterns => [config['password']])
|
76
76
|
end
|
77
77
|
|
78
|
-
def backup_file_path(config = configuration)
|
79
|
-
dump_file_name = "#{config['database']}_#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}.dump"
|
80
|
-
"#{backup_dir}/#{dump_file_name}.bz2"
|
81
|
-
end
|
82
|
-
|
83
78
|
def dump_db(file, config = configuration)
|
84
79
|
execute!(dump_command(config) + " > #{file}", :hidden_patterns => [config['password']])
|
85
80
|
end
|
@@ -115,47 +110,11 @@ module ForemanMaintain
|
|
115
110
|
end
|
116
111
|
end
|
117
112
|
|
118
|
-
# TODO: refactor to use dump_db
|
119
|
-
def backup_db_command(file_path, config = configuration)
|
120
|
-
pg_dump_cmd = "pg_dump -Fc #{config['database']}"
|
121
|
-
"runuser - postgres -c '#{pg_dump_cmd}' | bzip2 -9 > #{file_path}"
|
122
|
-
end
|
123
|
-
|
124
113
|
# TODO: remove the backup file path tools from here. Lib Utils::Backup?
|
125
114
|
def backup_dir
|
126
115
|
@backup_dir ||= File.expand_path(ForemanMaintain.config.db_backup_dir)
|
127
116
|
end
|
128
117
|
|
129
|
-
def perform_backup(config = configuration)
|
130
|
-
file_path = backup_file_path(config)
|
131
|
-
backup_cmd = backup_db_command(file_path, config)
|
132
|
-
execute!(backup_cmd, :hidden_patterns => [config['password']])
|
133
|
-
puts "\n Note: Database backup file path - #{file_path}"
|
134
|
-
puts "\n In case of any exception, use above dump file to restore DB."
|
135
|
-
end
|
136
|
-
|
137
|
-
def table_exist?(table_name)
|
138
|
-
sql = <<-SQL
|
139
|
-
SELECT EXISTS ( SELECT *
|
140
|
-
FROM information_schema.tables WHERE table_name = '#{table_name}' )
|
141
|
-
SQL
|
142
|
-
result = query(sql)
|
143
|
-
return false if result.nil? || (result && result.empty?)
|
144
|
-
|
145
|
-
result.first['exists'].eql?('t')
|
146
|
-
end
|
147
|
-
|
148
|
-
def delete_records_by_ids(tbl_name, rec_ids)
|
149
|
-
quotize_rec_ids = rec_ids.map { |el| "'#{el}'" }.join(',')
|
150
|
-
unless quotize_rec_ids.empty?
|
151
|
-
psql(<<-SQL)
|
152
|
-
BEGIN;
|
153
|
-
DELETE FROM #{tbl_name} WHERE id IN (#{quotize_rec_ids});
|
154
|
-
COMMIT;
|
155
|
-
SQL
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
118
|
def find_base_directory(directory)
|
160
119
|
find_dir_containing_file(directory, 'postgresql.conf')
|
161
120
|
end
|
@@ -100,13 +100,13 @@ 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, :dnf_options)
|
104
104
|
case action
|
105
105
|
when :install
|
106
106
|
package_manager.install(packages, :assumeyes => options[:assumeyes])
|
107
107
|
when :update
|
108
108
|
package_manager.update(packages, :assumeyes => options[:assumeyes],
|
109
|
-
:
|
109
|
+
:dnf_options => options[:dnf_options])
|
110
110
|
when :remove
|
111
111
|
package_manager.remove(packages, :assumeyes => options[:assumeyes])
|
112
112
|
else
|
@@ -64,7 +64,11 @@ module ForemanMaintain
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def config_file_path
|
67
|
-
|
67
|
+
if defined?(CONFIG_FILE) && File.exist?(CONFIG_FILE)
|
68
|
+
CONFIG_FILE
|
69
|
+
else
|
70
|
+
File.join(source_path, 'config/foreman_maintain.yml')
|
71
|
+
end
|
68
72
|
end
|
69
73
|
|
70
74
|
def source_path
|
@@ -1,14 +1,100 @@
|
|
1
1
|
module ForemanMaintain::PackageManager
|
2
|
-
class Dnf <
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
class Dnf < Base
|
3
|
+
PROTECTOR_CONFIG_FILE = '/etc/dnf/plugins/foreman-protector.conf'.freeze
|
4
|
+
PROTECTOR_WHITELIST_FILE = '/etc/dnf/plugins/foreman-protector.whitelist'.freeze
|
5
|
+
|
6
|
+
def self.parse_envra(envra)
|
7
|
+
# envra format: 0:foreman-1.20.1.10-1.el7sat.noarch
|
8
|
+
parsed = envra.match(/\d*:?(?<name>.*)-[^-]+-[^-]+\.[^.]+/)
|
9
|
+
parsed ? Hash[parsed.names.map(&:to_sym).zip(parsed.captures)].merge(:envra => envra) : nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def lock_versions
|
13
|
+
enable_protector
|
14
|
+
end
|
15
|
+
|
16
|
+
def unlock_versions
|
17
|
+
disable_protector
|
18
|
+
end
|
19
|
+
|
20
|
+
def versions_locked?
|
21
|
+
!!(protector_config =~ /^\s*enabled\s*=\s*1/) &&
|
22
|
+
protector_whitelist_file_nonzero?
|
23
|
+
end
|
24
|
+
|
25
|
+
def protector_whitelist_file_nonzero?
|
26
|
+
File.exist?(PROTECTOR_WHITELIST_FILE) &&
|
27
|
+
!File.zero?(PROTECTOR_WHITELIST_FILE)
|
6
28
|
end
|
7
29
|
|
8
30
|
def version_locking_supported?
|
9
31
|
true
|
10
32
|
end
|
11
33
|
|
34
|
+
def installed?(packages)
|
35
|
+
packages_list = [packages].flatten(1).map { |pkg| "'#{pkg}'" }.join(' ')
|
36
|
+
sys.execute?(%(rpm -q #{packages_list}))
|
37
|
+
end
|
38
|
+
|
39
|
+
def find_installed_package(name, queryformat = '')
|
40
|
+
rpm_cmd = "rpm -q '#{name}'"
|
41
|
+
unless queryformat.empty?
|
42
|
+
rpm_cmd += " --qf '#{queryformat}'"
|
43
|
+
end
|
44
|
+
status, result = sys.execute_with_status(rpm_cmd, interactive: false)
|
45
|
+
if status == 0
|
46
|
+
result
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def install(packages, assumeyes: false)
|
51
|
+
dnf_action('install', packages, assumeyes: assumeyes)
|
52
|
+
end
|
53
|
+
|
54
|
+
def reinstall(packages, assumeyes: false)
|
55
|
+
dnf_action('reinstall', packages, assumeyes: assumeyes)
|
56
|
+
end
|
57
|
+
|
58
|
+
def remove(packages, assumeyes: false)
|
59
|
+
dnf_action('remove', packages, assumeyes: assumeyes)
|
60
|
+
end
|
61
|
+
|
62
|
+
def update(packages = [], assumeyes: false, dnf_options: [])
|
63
|
+
dnf_action('update', packages, assumeyes: assumeyes, dnf_options: dnf_options)
|
64
|
+
end
|
65
|
+
|
66
|
+
def check_update(packages: nil, with_status: false)
|
67
|
+
dnf_action(
|
68
|
+
'check-update',
|
69
|
+
packages,
|
70
|
+
assumeyes: true,
|
71
|
+
valid_exit_statuses: [0, 100],
|
72
|
+
with_status: with_status
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
76
|
+
def update_available?(package)
|
77
|
+
cmd_output = dnf_action('check-update -q', package, with_status: true, assumeyes: false)
|
78
|
+
cmd_output[0] == 100
|
79
|
+
end
|
80
|
+
|
81
|
+
def files_not_owned_by_package(directory)
|
82
|
+
find_cmd = "find #{directory} -exec /bin/sh -c 'rpm -qf {} &> /dev/null || echo {}' \\;"
|
83
|
+
sys.execute(find_cmd).split("\n")
|
84
|
+
end
|
85
|
+
|
86
|
+
def list_installed_packages(queryformat = '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n')
|
87
|
+
# The queryformat should only include valid tag(s) as per `rpm --querytags` list.
|
88
|
+
# If any special formatting is required with querytag then it should be provided with tag i.e,
|
89
|
+
# "--%{VENDOR}"
|
90
|
+
# The queryformat string must end with '\n'
|
91
|
+
sys.execute!("rpm -qa --qf '#{queryformat}'").split("\n")
|
92
|
+
end
|
93
|
+
|
94
|
+
def clean_cache(assumeyes: false)
|
95
|
+
dnf_action('clean', 'all', :assumeyes => assumeyes)
|
96
|
+
end
|
97
|
+
|
12
98
|
def module_enabled?(name)
|
13
99
|
_status, result = info(name)
|
14
100
|
result.match?(/Stream.+\[e\].+/)
|
@@ -29,18 +115,59 @@ module ForemanMaintain::PackageManager
|
|
29
115
|
|
30
116
|
private
|
31
117
|
|
32
|
-
|
118
|
+
# rubocop:disable Metrics/LineLength, Metrics/ParameterLists
|
119
|
+
def dnf_action(action, packages, with_status: false, assumeyes: false, dnf_options: [], valid_exit_statuses: [0])
|
33
120
|
packages = [packages].flatten(1)
|
34
|
-
|
35
|
-
|
121
|
+
|
122
|
+
dnf_options << '-y' if assumeyes
|
123
|
+
dnf_options << '--disableplugin=foreman-protector'
|
124
|
+
|
125
|
+
command = ['dnf', dnf_options.join(' '), action]
|
126
|
+
|
127
|
+
command.push(packages.join(' ')) unless packages.empty?
|
128
|
+
command = command.join(' ')
|
129
|
+
|
36
130
|
if with_status
|
37
|
-
sys.execute_with_status(
|
38
|
-
|
131
|
+
sys.execute_with_status(
|
132
|
+
command,
|
133
|
+
:interactive => !assumeyes
|
134
|
+
)
|
39
135
|
else
|
40
|
-
sys.execute!(
|
41
|
-
|
136
|
+
sys.execute!(
|
137
|
+
command,
|
138
|
+
:interactive => !assumeyes,
|
139
|
+
:valid_exit_statuses => valid_exit_statuses
|
140
|
+
)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
# rubocop:enable Metrics/LineLength, Metrics/ParameterLists
|
42
144
|
|
145
|
+
def protector_config
|
146
|
+
File.exist?(protector_config_file) ? File.read(protector_config_file) : ''
|
147
|
+
end
|
148
|
+
|
149
|
+
def protector_config_file
|
150
|
+
PROTECTOR_CONFIG_FILE
|
151
|
+
end
|
152
|
+
|
153
|
+
def enable_protector
|
154
|
+
setup_protector(true)
|
155
|
+
end
|
156
|
+
|
157
|
+
def disable_protector
|
158
|
+
setup_protector(false)
|
159
|
+
end
|
160
|
+
|
161
|
+
def setup_protector(enabled)
|
162
|
+
config = protector_config
|
163
|
+
config += "\n" unless config[-1] == "\n"
|
164
|
+
enabled_re = /^\s*enabled\s*=.*$/
|
165
|
+
if enabled_re.match(config)
|
166
|
+
config = config.gsub(enabled_re, "enabled = #{enabled ? '1' : '0'}")
|
167
|
+
else
|
168
|
+
config += "enabled = #{enabled ? '1' : '0'}\n"
|
43
169
|
end
|
170
|
+
File.open(protector_config_file, 'w') { |file| file.puts config }
|
44
171
|
end
|
45
172
|
end
|
46
173
|
end
|
@@ -72,8 +72,8 @@ module ForemanMaintain::RepositoryManager
|
|
72
72
|
entry.split(':', 2).last.strip
|
73
73
|
end]
|
74
74
|
|
75
|
-
#
|
76
|
-
#
|
75
|
+
# repolist output includes extra info in the output
|
76
|
+
#
|
77
77
|
# rhel-7-server-rpms/7Server/x86_64
|
78
78
|
# rhel-server-rhscl-7-rpms/7Server/x86_64
|
79
79
|
# This trims anything after first '/' to get correct repo label
|
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.4.
|
4
|
+
version: 1.4.1
|
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: 2023-
|
11
|
+
date: 2023-10-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: clamp
|
@@ -158,7 +158,6 @@ files:
|
|
158
158
|
- config/foreman_maintain.yml.packaging
|
159
159
|
- config/hammer.yml.example
|
160
160
|
- definitions/checks/backup/certs_tar_exist.rb
|
161
|
-
- definitions/checks/backup/directory_ready.rb
|
162
161
|
- definitions/checks/candlepin/db_up.rb
|
163
162
|
- definitions/checks/check_for_newer_packages.rb
|
164
163
|
- definitions/checks/check_hotfix_installed.rb
|
@@ -168,15 +167,12 @@ files:
|
|
168
167
|
- definitions/checks/disk/available_space_postgresql12.rb
|
169
168
|
- definitions/checks/disk/performance.rb
|
170
169
|
- definitions/checks/env_proxy.rb
|
171
|
-
- definitions/checks/foreman/check_checkpoint_segments.rb
|
172
170
|
- definitions/checks/foreman/check_corrupted_roles.rb
|
173
171
|
- definitions/checks/foreman/check_duplicate_permission.rb
|
174
|
-
- definitions/checks/foreman/check_duplicate_roles.rb
|
175
172
|
- definitions/checks/foreman/check_puppet_capsules.rb
|
176
173
|
- definitions/checks/foreman/check_tuning_requirements.rb
|
177
174
|
- definitions/checks/foreman/db_up.rb
|
178
175
|
- definitions/checks/foreman/facts_names.rb
|
179
|
-
- definitions/checks/foreman/puppet_class_duplicates.rb
|
180
176
|
- definitions/checks/foreman/validate_external_db_version.rb
|
181
177
|
- definitions/checks/foreman_openscap/invalid_report_associations.rb
|
182
178
|
- definitions/checks/foreman_proxy/check_tftp_storage.rb
|
@@ -188,8 +184,7 @@ files:
|
|
188
184
|
- definitions/checks/foreman_tasks/not_running.rb
|
189
185
|
- definitions/checks/maintenance_mode/check_consistency.rb
|
190
186
|
- definitions/checks/non_rh_packages.rb
|
191
|
-
- definitions/checks/
|
192
|
-
- definitions/checks/package_manager/yum/validate_yum_config.rb
|
187
|
+
- definitions/checks/package_manager/dnf/validate_dnf_config.rb
|
193
188
|
- definitions/checks/pulpcore/db_up.rb
|
194
189
|
- definitions/checks/puppet/verify_no_empty_cacert_requests.rb
|
195
190
|
- definitions/checks/repositories/check_non_rh_repository.rb
|
@@ -259,11 +254,9 @@ files:
|
|
259
254
|
- definitions/procedures/crond/start.rb
|
260
255
|
- definitions/procedures/crond/stop.rb
|
261
256
|
- definitions/procedures/files/remove.rb
|
262
|
-
- definitions/procedures/foreman/apipie_cache.rb
|
263
257
|
- definitions/procedures/foreman/fix_corrupted_roles.rb
|
264
258
|
- definitions/procedures/foreman/remove_duplicate_obsolete_roles.rb
|
265
259
|
- definitions/procedures/foreman/remove_duplicate_permissions.rb
|
266
|
-
- definitions/procedures/foreman_docker/remove_foreman_docker.rb
|
267
260
|
- definitions/procedures/foreman_maintain_features.rb
|
268
261
|
- definitions/procedures/foreman_openscap/invalid_report_associations.rb
|
269
262
|
- definitions/procedures/foreman_proxy/features.rb
|
@@ -342,7 +335,6 @@ files:
|
|
342
335
|
- extras/foreman_protector/dnf/foreman-protector.py
|
343
336
|
- extras/foreman_protector/foreman-protector.conf
|
344
337
|
- extras/foreman_protector/foreman-protector.whitelist
|
345
|
-
- extras/foreman_protector/yum/foreman-protector.py
|
346
338
|
- lib/foreman_maintain.rb
|
347
339
|
- lib/foreman_maintain/check.rb
|
348
340
|
- lib/foreman_maintain/cli.rb
|
@@ -397,7 +389,6 @@ files:
|
|
397
389
|
- lib/foreman_maintain/package_manager/apt.rb
|
398
390
|
- lib/foreman_maintain/package_manager/base.rb
|
399
391
|
- lib/foreman_maintain/package_manager/dnf.rb
|
400
|
-
- lib/foreman_maintain/package_manager/yum.rb
|
401
392
|
- lib/foreman_maintain/param.rb
|
402
393
|
- lib/foreman_maintain/procedure.rb
|
403
394
|
- lib/foreman_maintain/reporter.rb
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module Checks::Backup
|
2
|
-
class DirectoryReady < ForemanMaintain::Check
|
3
|
-
metadata do
|
4
|
-
description 'Check if the directory exists and is writable'
|
5
|
-
tags :backup
|
6
|
-
manual_detection
|
7
|
-
param :backup_dir, 'Directory where to backup to', :required => true
|
8
|
-
param :preserve_dir, 'Directory where to backup to', :flag => true, :default => false
|
9
|
-
param :postgres_access, 'Whether the postgres user needs access', :flag => true,
|
10
|
-
:default => false
|
11
|
-
end
|
12
|
-
|
13
|
-
def run
|
14
|
-
assert(File.directory?(@backup_dir), "Backup directory (#{@backup_dir}) does not exist.")
|
15
|
-
if feature(:instance).postgresql_local? && @postgres_access
|
16
|
-
result = system("runuser - postgres -c 'test -w #{@backup_dir}'")
|
17
|
-
assert(result, "Postgres user needs write access to the backup directory \n" \
|
18
|
-
"Please allow the postgres user write access to #{@backup_dir}" \
|
19
|
-
' or choose another directory.')
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
module Checks
|
2
|
-
module Foreman
|
3
|
-
class CheckpointSegments < ForemanMaintain::Check
|
4
|
-
metadata do
|
5
|
-
label :check_postgresql_checkpoint_segments
|
6
|
-
description 'Check if checkpoint_segments configuration exists on the system'
|
7
|
-
confine do
|
8
|
-
feature(:foreman) && feature(:installer) &&
|
9
|
-
File.exist?(feature(:installer).custom_hiera_file)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def run
|
14
|
-
failure_message = check_custom_hiera
|
15
|
-
fail! failure_message if failure_message
|
16
|
-
end
|
17
|
-
|
18
|
-
# rubocop:disable Metrics/MethodLength
|
19
|
-
def check_custom_hiera
|
20
|
-
hiera_file = feature(:installer).custom_hiera_file
|
21
|
-
begin
|
22
|
-
config = YAML.load_file(hiera_file)
|
23
|
-
if config.is_a?(Hash) && config.key?('postgresql::server::config_entries')
|
24
|
-
if config['postgresql::server::config_entries'].nil?
|
25
|
-
return <<-MESSAGE.strip_heredoc
|
26
|
-
ERROR: 'postgresql::server::config_entries' cannot be null.
|
27
|
-
Please remove it from following file and re-run the command.
|
28
|
-
- #{hiera_file}
|
29
|
-
MESSAGE
|
30
|
-
elsif config['postgresql::server::config_entries'].key?('checkpoint_segments')
|
31
|
-
message = <<-MESSAGE.strip_heredoc
|
32
|
-
ERROR: Tuning option 'checkpoint_segments' found.
|
33
|
-
This option is no longer valid for PostgreSQL 9.5 or newer.
|
34
|
-
Please remove it from following file and re-run the command.
|
35
|
-
- #{hiera_file}
|
36
|
-
MESSAGE
|
37
|
-
if feature(:katello)
|
38
|
-
message += <<-MESSAGE.strip_heredoc
|
39
|
-
The presence of checkpoint_segments in #{hiera_file} indicates manual tuning.
|
40
|
-
Manual tuning can override values provided by the --tuning parameter.
|
41
|
-
Review #{hiera_file} for values that are already provided by the built in tuning profiles.
|
42
|
-
Built in tuning profiles also provide a supported upgrade path.
|
43
|
-
MESSAGE
|
44
|
-
end
|
45
|
-
return message
|
46
|
-
end
|
47
|
-
elsif config.is_a?(String)
|
48
|
-
fail! "Error: File #{hiera_file} is not a yaml file."
|
49
|
-
exit 1
|
50
|
-
end
|
51
|
-
rescue Psych::SyntaxError
|
52
|
-
fail! "Found syntax error in file: #{hiera_file}"
|
53
|
-
exit 1
|
54
|
-
end
|
55
|
-
end
|
56
|
-
# rubocop:enable Metrics/MethodLength
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
module Checks
|
2
|
-
module Foreman
|
3
|
-
class CheckDuplicateRoles < ForemanMaintain::Check
|
4
|
-
metadata do
|
5
|
-
label :duplicate_roles
|
6
|
-
for_feature :foreman_database
|
7
|
-
description 'Check for duplicate roles from DB'
|
8
|
-
tags :pre_upgrade
|
9
|
-
confine do
|
10
|
-
check_max_version('foreman', '1.20')
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def run
|
15
|
-
duplicate_roles = find_duplicate_roles
|
16
|
-
roles_names = duplicate_roles.map { |r| r['name'] }.uniq
|
17
|
-
assert(
|
18
|
-
duplicate_roles.empty?,
|
19
|
-
"Duplicate entries found for role(s) - #{roles_names.join(', ')} in your DB",
|
20
|
-
:next_steps => [
|
21
|
-
Procedures::Foreman::RemoveDuplicateObsoleteRoles.new,
|
22
|
-
Procedures::KnowledgeBaseArticle.new(
|
23
|
-
:doc => 'fix_db_migrate_failure_on_duplicate_roles'
|
24
|
-
),
|
25
|
-
]
|
26
|
-
)
|
27
|
-
end
|
28
|
-
|
29
|
-
def find_duplicate_roles
|
30
|
-
feature(:foreman_database).query(self.class.query_to_get_duplicate_roles)
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.query_to_get_duplicate_roles
|
34
|
-
<<-SQL
|
35
|
-
SELECT r.id, r.name FROM roles r JOIN (
|
36
|
-
SELECT name, COUNT(*) FROM roles GROUP BY name HAVING count(*) > 1
|
37
|
-
) dr ON r.name = dr.name ORDER BY r.name
|
38
|
-
SQL
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
module Checks
|
2
|
-
module Foreman
|
3
|
-
class PuppetClassDuplicates < ForemanMaintain::Check
|
4
|
-
metadata do
|
5
|
-
label :puppet_class_duplicates
|
6
|
-
for_feature :foreman_database
|
7
|
-
description 'Check for duplicate Puppet class records'
|
8
|
-
tags :pre_upgrade
|
9
|
-
confine do
|
10
|
-
check_max_version('foreman', '1.20')
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def run
|
15
|
-
duplicate_names = find_duplicate_names
|
16
|
-
assert(duplicate_names.empty?, duplicate_msg(duplicate_names))
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def duplicate_msg(duplicate_names)
|
22
|
-
msg = "There are #{duplicate_names.count} Puppet classes with duplicities:\n"
|
23
|
-
classes_list = duplicate_names.reduce('') do |memo, hash|
|
24
|
-
memo.tap { |acc| acc << "#{hash['name']} - #{hash['name_count']}\n" }
|
25
|
-
end
|
26
|
-
help_msg = 'Please head over to Configure -> Classes'
|
27
|
-
help_msg << " and make sure there is only 1 Puppet class record for each name.\n"
|
28
|
-
[msg, classes_list, help_msg].join('')
|
29
|
-
end
|
30
|
-
|
31
|
-
def find_duplicate_names
|
32
|
-
feature(:foreman_database).query(duplicate_names_query)
|
33
|
-
end
|
34
|
-
|
35
|
-
def duplicate_names_query
|
36
|
-
<<-SQL
|
37
|
-
SELECT name, name_count
|
38
|
-
FROM (
|
39
|
-
SELECT name, count(name) AS name_count
|
40
|
-
FROM puppetclasses
|
41
|
-
GROUP BY name
|
42
|
-
) AS puppetclass_counts
|
43
|
-
WHERE name_count > 1
|
44
|
-
SQL
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
class Checks::OriginalAssets < ForemanMaintain::Check
|
2
|
-
metadata do
|
3
|
-
description 'Check if only installed assets are present on the system'
|
4
|
-
tags :post_upgrade
|
5
|
-
for_feature :foreman_server
|
6
|
-
end
|
7
|
-
|
8
|
-
ASSETS_DIR = '/var/lib/foreman/public/assets'.freeze
|
9
|
-
|
10
|
-
def run
|
11
|
-
custom_assets = []
|
12
|
-
product_name = feature(:instance).product_name
|
13
|
-
with_spinner('Checking for presence of non-original assets...') do
|
14
|
-
custom_assets = package_manager.files_not_owned_by_package(ASSETS_DIR)
|
15
|
-
logger.info("Non-original assets detected:\n" + custom_assets.join("\n"))
|
16
|
-
end
|
17
|
-
remove_files = Procedures::Files::Remove.new(:files => custom_assets, :assumeyes => true)
|
18
|
-
assert(custom_assets.empty?,
|
19
|
-
"Some assets not owned by #{product_name} were detected on the system.\n" \
|
20
|
-
'Possible conflicting versions can affect operation of the Web UI.',
|
21
|
-
:next_steps => remove_files)
|
22
|
-
end
|
23
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module Procedures::ForemanDocker
|
2
|
-
class RemoveForemanDocker < ForemanMaintain::Procedure
|
3
|
-
metadata do
|
4
|
-
advanced_run false
|
5
|
-
description 'Drop foreman_docker plugin'
|
6
|
-
confine do
|
7
|
-
find_package(foreman_plugin_name('foreman_docker'))
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def run
|
12
|
-
execute!('foreman-rake foreman_docker:cleanup')
|
13
|
-
packages_action(:remove, foreman_plugin_name('foreman_docker'), :assumeyes => true)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,86 +0,0 @@
|
|
1
|
-
from yum.plugins import PluginYumExit
|
2
|
-
from yum.plugins import TYPE_CORE
|
3
|
-
from rpmUtils.miscutils import splitFilename
|
4
|
-
from yum.packageSack import packagesNewestByName
|
5
|
-
|
6
|
-
import urlgrabber
|
7
|
-
import urlgrabber.grabber
|
8
|
-
|
9
|
-
import os
|
10
|
-
import fnmatch
|
11
|
-
import tempfile
|
12
|
-
import time
|
13
|
-
|
14
|
-
requires_api_version = '2.1'
|
15
|
-
plugin_type = (TYPE_CORE,)
|
16
|
-
|
17
|
-
_package_whitelist = set()
|
18
|
-
fileurl = None
|
19
|
-
|
20
|
-
def _load_whitelist():
|
21
|
-
try:
|
22
|
-
if fileurl:
|
23
|
-
llfile = urlgrabber.urlopen(fileurl)
|
24
|
-
for line in llfile.readlines():
|
25
|
-
if line.startswith('#') or line.strip() == '':
|
26
|
-
continue
|
27
|
-
_package_whitelist.add(line.rstrip().lower())
|
28
|
-
llfile.close()
|
29
|
-
except urlgrabber.grabber.URLGrabError as e:
|
30
|
-
raise PluginYumExit('Unable to read Foreman protector"s configuration: %s' % e)
|
31
|
-
|
32
|
-
def _add_obsoletes(conduit):
|
33
|
-
if _package_whitelist:
|
34
|
-
# If anything obsoletes something that we have whitelisted ... then
|
35
|
-
# whitelist that too.
|
36
|
-
for (pkgtup, instTup) in conduit._base.up.getObsoletesTuples():
|
37
|
-
if instTup[0] not in _package_whitelist:
|
38
|
-
continue
|
39
|
-
_package_whitelist.add(pkgtup[0].lower())
|
40
|
-
|
41
|
-
def _get_updates(base):
|
42
|
-
updates = {}
|
43
|
-
|
44
|
-
for p in base.pkgSack.returnNewestByName():
|
45
|
-
if p.name in _package_whitelist:
|
46
|
-
# This one is whitelisted, skip
|
47
|
-
continue
|
48
|
-
updates[p.name] = p
|
49
|
-
|
50
|
-
return updates
|
51
|
-
|
52
|
-
def config_hook(conduit):
|
53
|
-
global fileurl
|
54
|
-
|
55
|
-
fileurl = conduit.confString('main', 'whitelist')
|
56
|
-
|
57
|
-
def _add_package_whitelist_excluders(conduit):
|
58
|
-
if hasattr(conduit, 'registerPackageName'):
|
59
|
-
conduit.registerPackageName("yum-plugin-foreman-protector")
|
60
|
-
ape = conduit._base.pkgSack.addPackageExcluder
|
61
|
-
exid = 'foreman-protector.W.'
|
62
|
-
ape(None, exid + str(1), 'mark.washed')
|
63
|
-
ape(None, exid + str(2), 'wash.name.in', _package_whitelist)
|
64
|
-
ape(None, exid + str(3), 'exclude.marked')
|
65
|
-
|
66
|
-
def exclude_hook(conduit):
|
67
|
-
conduit.info(3, 'Reading Foreman protector configuration')
|
68
|
-
|
69
|
-
_load_whitelist()
|
70
|
-
_add_obsoletes(conduit)
|
71
|
-
|
72
|
-
total = len(_get_updates(conduit._base))
|
73
|
-
conduit.info(3, '*** Excluded total: %s' % total)
|
74
|
-
if total:
|
75
|
-
if total > 1:
|
76
|
-
suffix = 's'
|
77
|
-
else:
|
78
|
-
suffix = ''
|
79
|
-
conduit.info(1, '\n'
|
80
|
-
'WARNING: Excluding %d package%s due to foreman-protector. \n'
|
81
|
-
'Use foreman-maintain packages install/update <package> \n'
|
82
|
-
'to safely install packages without restrictions.\n'
|
83
|
-
'Use foreman-maintain upgrade run for full upgrade.\n'
|
84
|
-
% (total, suffix))
|
85
|
-
|
86
|
-
_add_package_whitelist_excluders(conduit)
|
@@ -1,142 +0,0 @@
|
|
1
|
-
module ForemanMaintain::PackageManager
|
2
|
-
class Yum < Base
|
3
|
-
PROTECTOR_CONFIG_FILE = '/etc/yum/pluginconf.d/foreman-protector.conf'.freeze
|
4
|
-
PROTECTOR_WHITELIST_FILE = '/etc/yum/pluginconf.d/foreman-protector.whitelist'.freeze
|
5
|
-
|
6
|
-
def self.parse_envra(envra)
|
7
|
-
# envra format: 0:foreman-1.20.1.10-1.el7sat.noarch
|
8
|
-
parsed = envra.match(/\d*:?(?<name>.*)-[^-]+-[^-]+\.[^.]+/)
|
9
|
-
parsed ? Hash[parsed.names.map(&:to_sym).zip(parsed.captures)].merge(:envra => envra) : nil
|
10
|
-
end
|
11
|
-
|
12
|
-
def lock_versions
|
13
|
-
enable_protector
|
14
|
-
end
|
15
|
-
|
16
|
-
def unlock_versions
|
17
|
-
disable_protector
|
18
|
-
end
|
19
|
-
|
20
|
-
def versions_locked?
|
21
|
-
!!(protector_config =~ /^\s*enabled\s*=\s*1/) &&
|
22
|
-
protector_whitelist_file_nonzero?
|
23
|
-
end
|
24
|
-
|
25
|
-
def protector_whitelist_file_nonzero?
|
26
|
-
File.exist?(PROTECTOR_WHITELIST_FILE) &&
|
27
|
-
!File.zero?(PROTECTOR_WHITELIST_FILE)
|
28
|
-
end
|
29
|
-
|
30
|
-
def version_locking_supported?
|
31
|
-
true
|
32
|
-
end
|
33
|
-
|
34
|
-
def installed?(packages)
|
35
|
-
packages_list = [packages].flatten(1).map { |pkg| "'#{pkg}'" }.join(' ')
|
36
|
-
sys.execute?(%(rpm -q #{packages_list}))
|
37
|
-
end
|
38
|
-
|
39
|
-
def find_installed_package(name, queryformat = '')
|
40
|
-
rpm_cmd = "rpm -q '#{name}'"
|
41
|
-
unless queryformat.empty?
|
42
|
-
rpm_cmd += " --qf '#{queryformat}'"
|
43
|
-
end
|
44
|
-
status, result = sys.execute_with_status(rpm_cmd)
|
45
|
-
if status == 0
|
46
|
-
result
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def install(packages, assumeyes: false)
|
51
|
-
yum_action('install', packages, :assumeyes => assumeyes)
|
52
|
-
end
|
53
|
-
|
54
|
-
def reinstall(packages, assumeyes: false)
|
55
|
-
yum_action('reinstall', packages, :assumeyes => assumeyes)
|
56
|
-
end
|
57
|
-
|
58
|
-
def remove(packages, assumeyes: false)
|
59
|
-
yum_action('remove', packages, :assumeyes => assumeyes)
|
60
|
-
end
|
61
|
-
|
62
|
-
def update(packages = [], assumeyes: false, yum_options: [])
|
63
|
-
yum_action('update', packages, :assumeyes => assumeyes, :yum_options => yum_options)
|
64
|
-
end
|
65
|
-
|
66
|
-
def clean_cache(assumeyes: false)
|
67
|
-
yum_action('clean', 'all', :assumeyes => assumeyes)
|
68
|
-
end
|
69
|
-
|
70
|
-
def check_update(packages: nil, with_status: false)
|
71
|
-
yum_action('check-update', packages, :assumeyes => true, :valid_exit_statuses => [0, 100],
|
72
|
-
:with_status => with_status)
|
73
|
-
end
|
74
|
-
|
75
|
-
def update_available?(package)
|
76
|
-
cmd_output = yum_action('check-update -q', package, :with_status => true, :assumeyes => false)
|
77
|
-
cmd_output[0] == 100
|
78
|
-
end
|
79
|
-
|
80
|
-
def files_not_owned_by_package(directory)
|
81
|
-
find_cmd = "find #{directory} -exec /bin/sh -c 'rpm -qf {} &> /dev/null || echo {}' \\;"
|
82
|
-
sys.execute(find_cmd).split("\n")
|
83
|
-
end
|
84
|
-
|
85
|
-
def list_installed_packages(queryformat = '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n')
|
86
|
-
# The queryformat should only include valid tag(s) as per `rpm --querytags` list.
|
87
|
-
# If any special formatting is required with querytag then it should be provided with tag i.e,
|
88
|
-
# "--%{VENDOR}"
|
89
|
-
# The queryformat string must end with '\n'
|
90
|
-
sys.execute!("rpm -qa --qf '#{queryformat}'").split("\n")
|
91
|
-
end
|
92
|
-
|
93
|
-
private
|
94
|
-
|
95
|
-
def protector_config
|
96
|
-
File.exist?(protector_config_file) ? File.read(protector_config_file) : ''
|
97
|
-
end
|
98
|
-
|
99
|
-
def protector_config_file
|
100
|
-
PROTECTOR_CONFIG_FILE
|
101
|
-
end
|
102
|
-
|
103
|
-
def enable_protector
|
104
|
-
setup_protector(true)
|
105
|
-
end
|
106
|
-
|
107
|
-
def disable_protector
|
108
|
-
setup_protector(false)
|
109
|
-
end
|
110
|
-
|
111
|
-
def setup_protector(enabled)
|
112
|
-
config = protector_config
|
113
|
-
config += "\n" unless config[-1] == "\n"
|
114
|
-
enabled_re = /^\s*enabled\s*=.*$/
|
115
|
-
if enabled_re.match(config)
|
116
|
-
config = config.gsub(enabled_re, "enabled = #{enabled ? '1' : '0'}")
|
117
|
-
else
|
118
|
-
config += "enabled = #{enabled ? '1' : '0'}\n"
|
119
|
-
end
|
120
|
-
File.open(protector_config_file, 'w') { |file| file.puts config }
|
121
|
-
end
|
122
|
-
|
123
|
-
def yum_action(action, packages, options)
|
124
|
-
with_status = options.fetch(:with_status, false)
|
125
|
-
assumeyes = options.fetch(:assumeyes, false)
|
126
|
-
valid_exit_statuses = options.fetch(:valid_exit_statuses, [0])
|
127
|
-
yum_options = options.fetch(:yum_options, [])
|
128
|
-
packages = [packages].flatten(1)
|
129
|
-
yum_options << '-y' if assumeyes
|
130
|
-
yum_options << '--disableplugin=foreman-protector'
|
131
|
-
yum_options_s = yum_options.empty? ? '' : ' ' + yum_options.join(' ')
|
132
|
-
packages_s = packages.empty? ? '' : ' ' + packages.join(' ')
|
133
|
-
if with_status
|
134
|
-
sys.execute_with_status("yum#{yum_options_s} #{action}#{packages_s}",
|
135
|
-
:interactive => !assumeyes)
|
136
|
-
else
|
137
|
-
sys.execute!("yum#{yum_options_s} #{action}#{packages_s}",
|
138
|
-
:interactive => !assumeyes, :valid_exit_statuses => valid_exit_statuses)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|