foreman_leapp 4.3.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/helpers/foreman_leapp/template_helper.rb +2 -5
- data/app/lib/actions/foreman_leapp/preupgrade_job.rb +13 -2
- data/app/lib/foreman_leapp/remediation_plan.rb +49 -0
- data/app/models/preupgrade_report.rb +4 -3
- data/app/models/preupgrade_report_entry.rb +3 -1
- data/app/views/api/v2/preupgrade_report_entries/base.json.rabl +2 -1
- data/app/views/foreman_leapp/job_templates/leapp_preupgrade.erb +2 -0
- data/db/migrate/20260825120000_add_leapp_version_to_report_entries.rb +7 -0
- data/lib/foreman_leapp/engine.rb +1 -1
- data/lib/foreman_leapp/version.rb +1 -1
- data/package.json +1 -14
- data/test/helpers/template_helper_test.rb +45 -0
- data/test/models/preupgrade_report_entry_test.rb +3 -2
- data/test/models/preupgrade_report_test.rb +16 -0
- data/test/unit/actions/preupgrade_job_test.rb +27 -0
- data/test/unit/remediation_plan_test.rb +97 -0
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0b1d949c6e610cc2063defc9a50b0cf522f37fdf6ca8c839a4fb506cffd7460f
|
|
4
|
+
data.tar.gz: 927658988954a6db9379f26497f27c6bb68253e1f8ccb11dc1061a21169a2ee1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d93ffcc5320a5339bc97d9a3130bdf3ee0d3b96028d8d883c0895bdeb8abb8ec15dd4593aecbfeedd578027eb85606684f194b5fc19771d2c5c9947d82be87fe
|
|
7
|
+
data.tar.gz: 9b2e14599a9949e7c5040c71b3eb7d193a1cd88dc29ad388e05a49c8b71cf93a7253484481f7e54584b8002bd2fcb86675018afd9f096b3ac8ffa26adcd3fb5f
|
|
@@ -4,11 +4,8 @@ module ForemanLeapp
|
|
|
4
4
|
module TemplateHelper
|
|
5
5
|
def build_remediation_plan(remediation_ids, host)
|
|
6
6
|
PreupgradeReportEntry.remediation_details(remediation_ids, host)
|
|
7
|
-
.
|
|
8
|
-
.
|
|
9
|
-
.compact
|
|
10
|
-
.select { |r| r['type'] == 'command' }
|
|
11
|
-
.map { |r| "#{r['context'].join(' ')}\n" }
|
|
7
|
+
.group_by { |_detail, leapp_version| leapp_version }
|
|
8
|
+
.map { |leapp_version, pairs| RemediationPlan.build(pairs.map(&:first), leapp_version) }
|
|
12
9
|
.join
|
|
13
10
|
end
|
|
14
11
|
end
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
module Actions
|
|
4
4
|
module ForemanLeapp
|
|
5
5
|
class PreupgradeJob < Actions::EntryAction
|
|
6
|
+
# The `rpm -q leapp` line of the job output, e.g. leapp-0.21.0-1.el8.noarch
|
|
7
|
+
LEAPP_NVR = /^leapp-(\d[\d.]*)/.freeze
|
|
8
|
+
|
|
6
9
|
def self.subscribe
|
|
7
10
|
Actions::RemoteExecution::RunHostJob
|
|
8
11
|
end
|
|
@@ -15,9 +18,11 @@ module Actions
|
|
|
15
18
|
|
|
16
19
|
def finalize(*_args)
|
|
17
20
|
host = Host.find(input[:host_id])
|
|
18
|
-
|
|
21
|
+
job_output = task.main_action.continuous_output.humanize
|
|
22
|
+
leapp_report = format_output(job_output)
|
|
19
23
|
|
|
20
|
-
PreupgradeReport.create_report(host, leapp_report, input[:job_invocation_id]
|
|
24
|
+
PreupgradeReport.create_report(host, leapp_report, input[:job_invocation_id],
|
|
25
|
+
leapp_version(job_output))
|
|
21
26
|
end
|
|
22
27
|
|
|
23
28
|
private
|
|
@@ -30,6 +35,12 @@ module Actions
|
|
|
30
35
|
.join('')
|
|
31
36
|
JSON.parse(output)
|
|
32
37
|
end
|
|
38
|
+
|
|
39
|
+
# The version of the leapp package the report was generated with. It drives
|
|
40
|
+
# how the remediation commands from the report have to be quoted.
|
|
41
|
+
def leapp_version(job_output)
|
|
42
|
+
job_output[LEAPP_NVR, 1]
|
|
43
|
+
end
|
|
33
44
|
end
|
|
34
45
|
end
|
|
35
46
|
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'shellwords'
|
|
4
|
+
|
|
5
|
+
module ForemanLeapp
|
|
6
|
+
# Assembles the shell script out of the command remediations found in a leapp report.
|
|
7
|
+
#
|
|
8
|
+
# Leapp changed the way remediation commands are quoted. Up to leapp 0.21 the
|
|
9
|
+
# arguments in the "context" list were already quoted by leapp itself, so they
|
|
10
|
+
# were meant to be joined verbatim. Starting with leapp 0.22 the arguments are
|
|
11
|
+
# reported as they are and have to be escaped by the consumer of the report.
|
|
12
|
+
# See https://github.com/oamg/leapp-repository/pull/1520
|
|
13
|
+
#
|
|
14
|
+
# The new quoting is shipped by leapp-upgrade-el<X>toel<Y> 0.25, which is released
|
|
15
|
+
# together with leapp 0.22, so the version of the leapp package tells the two
|
|
16
|
+
# formats apart.
|
|
17
|
+
module RemediationPlan
|
|
18
|
+
# The first leapp version that reports remediation command arguments unquoted.
|
|
19
|
+
UNQUOTED_ARGUMENTS_SINCE = Gem::Version.new('0.22')
|
|
20
|
+
|
|
21
|
+
class << self
|
|
22
|
+
def build(detail, leapp_version)
|
|
23
|
+
quoted = quoted_by_leapp?(leapp_version)
|
|
24
|
+
Array.wrap(detail)
|
|
25
|
+
.flat_map { |d| d['remediations'] }
|
|
26
|
+
.compact
|
|
27
|
+
.select { |remediation| remediation['type'] == 'command' }
|
|
28
|
+
.map { |remediation| "#{command_line(remediation['context'], quoted)}\n" }
|
|
29
|
+
.join
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def command_line(context, quoted)
|
|
33
|
+
arguments = Array.wrap(context)
|
|
34
|
+
return arguments.join(' ') if quoted
|
|
35
|
+
|
|
36
|
+
arguments.map { |argument| Shellwords.escape(argument) }.join(' ')
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Unknown versions are treated as old leapp, so that reports collected
|
|
40
|
+
# before the version was recorded keep rendering the way they used to.
|
|
41
|
+
def quoted_by_leapp?(leapp_version)
|
|
42
|
+
version = Gem::Version.new(leapp_version.to_s[/\A[0-9][0-9.]*/].to_s.chomp('.'))
|
|
43
|
+
version < UNQUOTED_ARGUMENTS_SINCE
|
|
44
|
+
rescue ArgumentError
|
|
45
|
+
true
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -6,7 +6,7 @@ class PreupgradeReport < ::Report
|
|
|
6
6
|
|
|
7
7
|
scoped_search on: :job_invocation_id, only_explicit: true
|
|
8
8
|
|
|
9
|
-
def self.create_report(host, data, job_invocation_id)
|
|
9
|
+
def self.create_report(host, data, job_invocation_id, leapp_version = nil)
|
|
10
10
|
# We don't have specific permissions for the Preupgrade leapp reports,
|
|
11
11
|
# so we need to skip the permission check for non-admin users.
|
|
12
12
|
# The user is still required to have permission to run the job and view the hosts.
|
|
@@ -16,12 +16,12 @@ class PreupgradeReport < ::Report
|
|
|
16
16
|
reported_at: DateTime.now.utc
|
|
17
17
|
|
|
18
18
|
data['entries']&.each do |entry|
|
|
19
|
-
PreupgradeReportEntry.create! entry_params(report, entry, host, data)
|
|
19
|
+
PreupgradeReportEntry.create! entry_params(report, entry, host, data, leapp_version)
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
def self.entry_params(report, entry, host, data)
|
|
24
|
+
def self.entry_params(report, entry, host, data, leapp_version = nil)
|
|
25
25
|
{ preupgrade_report: report,
|
|
26
26
|
host_id: host.id,
|
|
27
27
|
hostname: host.name,
|
|
@@ -30,6 +30,7 @@ class PreupgradeReport < ::Report
|
|
|
30
30
|
audience: entry['audience'],
|
|
31
31
|
severity: entry['severity'],
|
|
32
32
|
leapp_run_id: data['leapp_run_id'],
|
|
33
|
+
leapp_version: leapp_version,
|
|
33
34
|
summary: entry['summary'],
|
|
34
35
|
tags: entry['tags'],
|
|
35
36
|
flags: entry['flags'],
|
|
@@ -50,8 +50,10 @@ class PreupgradeReportEntry < ApplicationRecord
|
|
|
50
50
|
))
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
# Returns [detail, leapp_version] pairs. The leapp version is needed because
|
|
54
|
+
# the quoting of the remediation commands differs between leapp versions.
|
|
53
55
|
def self.remediation_details(remediation_ids, host)
|
|
54
|
-
where(id: remediation_ids, host: host).where.not(detail: nil).pluck(:detail)
|
|
56
|
+
where(id: remediation_ids, host: host).where.not(detail: nil).pluck(:detail, :leapp_version)
|
|
55
57
|
end
|
|
56
58
|
|
|
57
59
|
def self.search_yes_no_fields(key, operator, value)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
object @preupgrade_report_entry
|
|
2
2
|
|
|
3
3
|
attributes :id, :detail, :preupgrade_report_id, :host_id, :hostname, :title, :actor, :audience,
|
|
4
|
-
:severity, :leapp_run_id, :summary, :tags, :flags, :created_at,
|
|
4
|
+
:severity, :leapp_run_id, :leapp_version, :summary, :tags, :flags, :created_at,
|
|
5
|
+
:updated_at
|
data/lib/foreman_leapp/engine.rb
CHANGED
|
@@ -17,7 +17,7 @@ module ForemanLeapp
|
|
|
17
17
|
initializer 'foreman_leapp.register_plugin', before: :finisher_hook do |app|
|
|
18
18
|
app.reloader.to_prepare do
|
|
19
19
|
Foreman::Plugin.register :foreman_leapp do
|
|
20
|
-
requires_foreman '>= 5.
|
|
20
|
+
requires_foreman '>= 5.1'
|
|
21
21
|
register_gettext
|
|
22
22
|
|
|
23
23
|
apipie_documented_controllers ["#{ForemanLeapp::Engine.root}/app/controllers/api/v2/*.rb"]
|
data/package.json
CHANGED
|
@@ -4,12 +4,7 @@
|
|
|
4
4
|
"description": "Plugin for RHEL upgrades using Foreman.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"
|
|
8
|
-
"link-leapp-js": "./script/link_leapp_js.sh",
|
|
9
|
-
"test": "tfm-test --plugin --config jest.config.js",
|
|
10
|
-
"test:watch": "tfm-test --plugin --watchAll",
|
|
11
|
-
"test:current": "tfm-test --plugin --watch",
|
|
12
|
-
"publish-coverage": "tfm-publish-coverage"
|
|
7
|
+
"link-leapp-js": "./script/link_leapp_js.sh"
|
|
13
8
|
},
|
|
14
9
|
"repository": {
|
|
15
10
|
"type": "git",
|
|
@@ -21,16 +16,8 @@
|
|
|
21
16
|
"url": "http://projects.theforeman.org/projects/foreman_leapp/issues"
|
|
22
17
|
},
|
|
23
18
|
"homepage": "https://github.com/oamg/foreman_leapp",
|
|
24
|
-
"peerDependencies": {
|
|
25
|
-
"@theforeman/vendor": ">= 12.0.1"
|
|
26
|
-
},
|
|
27
19
|
"devDependencies": {
|
|
28
20
|
"@babel/core": "^7.7.0",
|
|
29
|
-
"@theforeman/builder": ">= 12.0.1",
|
|
30
|
-
"@theforeman/eslint-plugin-foreman": ">= 12.0.1",
|
|
31
|
-
"@theforeman/eslint-plugin-rules": ">= 12.0.1",
|
|
32
|
-
"@theforeman/test": ">= 12.0.1",
|
|
33
|
-
"@theforeman/vendor-dev": ">= 12.0.1",
|
|
34
21
|
"babel-eslint": "^10.0.0",
|
|
35
22
|
"eslint": "^6.8.0",
|
|
36
23
|
"prettier": "^1.19.1"
|
|
@@ -8,6 +8,17 @@ module ForemanLeapp
|
|
|
8
8
|
let(:report) { FactoryBot.create(:preupgrade_report, host: host) }
|
|
9
9
|
let(:entry) { FactoryBot.create(:preupgrade_report_entry, host: host, preupgrade_report: report) }
|
|
10
10
|
|
|
11
|
+
let(:quoting_context) do
|
|
12
|
+
{
|
|
13
|
+
remediations: [
|
|
14
|
+
{
|
|
15
|
+
type: 'command',
|
|
16
|
+
context: ['bash', '-c', 'ln -snf "var/log/leapp" "/space space"'],
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
|
|
11
22
|
describe 'build_remediation_plan' do
|
|
12
23
|
test 'with remediation commands' do
|
|
13
24
|
template = build_remediation_plan([entry.id], host)
|
|
@@ -26,6 +37,40 @@ module ForemanLeapp
|
|
|
26
37
|
template = build_remediation_plan([entry.id], FactoryBot.create(:host))
|
|
27
38
|
assert_equal template, ''
|
|
28
39
|
end
|
|
40
|
+
|
|
41
|
+
test 'joins the arguments verbatim for reports from leapp older than 0.22' do
|
|
42
|
+
old_entry = FactoryBot.create(:preupgrade_report_entry, host: host, preupgrade_report: report,
|
|
43
|
+
leapp_version: '0.21.0', detail: quoting_context)
|
|
44
|
+
|
|
45
|
+
template = build_remediation_plan([old_entry.id], host)
|
|
46
|
+
|
|
47
|
+
assert_equal "bash -c ln -snf \"var/log/leapp\" \"/space space\"\n", template
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
test 'escapes the arguments for reports from leapp 0.22 and newer' do
|
|
51
|
+
new_entry = FactoryBot.create(:preupgrade_report_entry, host: host, preupgrade_report: report,
|
|
52
|
+
leapp_version: '0.22.0', detail: quoting_context)
|
|
53
|
+
|
|
54
|
+
template = build_remediation_plan([new_entry.id], host)
|
|
55
|
+
|
|
56
|
+
assert_equal ['bash', '-c', 'ln -snf "var/log/leapp" "/space space"'],
|
|
57
|
+
Shellwords.split(template)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
test 'quotes every entry according to the leapp version it was reported by' do
|
|
61
|
+
old_entry = FactoryBot.create(:preupgrade_report_entry, host: host, preupgrade_report: report,
|
|
62
|
+
leapp_version: '0.21.0', detail: quoting_context)
|
|
63
|
+
new_entry = FactoryBot.create(:preupgrade_report_entry, host: host, preupgrade_report: report,
|
|
64
|
+
leapp_version: '0.22.0', detail: quoting_context)
|
|
65
|
+
|
|
66
|
+
lines = build_remediation_plan([old_entry.id, new_entry.id], host).lines
|
|
67
|
+
verbatim_line = "bash -c ln -snf \"var/log/leapp\" \"/space space\"\n"
|
|
68
|
+
|
|
69
|
+
assert_equal 2, lines.size
|
|
70
|
+
assert_includes lines, verbatim_line
|
|
71
|
+
assert_equal ['bash', '-c', 'ln -snf "var/log/leapp" "/space space"'],
|
|
72
|
+
Shellwords.split(lines.find { |line| line != verbatim_line })
|
|
73
|
+
end
|
|
29
74
|
end
|
|
30
75
|
end
|
|
31
76
|
end
|
|
@@ -20,14 +20,15 @@ class PreupgradeReportEntryTest < ActiveSupport::TestCase
|
|
|
20
20
|
@host = FactoryBot.create(:host)
|
|
21
21
|
|
|
22
22
|
report = FactoryBot.create(:preupgrade_report)
|
|
23
|
-
@entry1 = FactoryBot.create(:preupgrade_report_entry, preupgrade_report: report, host: @host
|
|
23
|
+
@entry1 = FactoryBot.create(:preupgrade_report_entry, preupgrade_report: report, host: @host,
|
|
24
|
+
leapp_version: '0.22.0')
|
|
24
25
|
@entry2 = FactoryBot.create(:preupgrade_report_entry, preupgrade_report: report, host: @host, detail: nil)
|
|
25
26
|
end
|
|
26
27
|
|
|
27
28
|
it do
|
|
28
29
|
details = PreupgradeReportEntry.remediation_details([@entry1.id, @entry2.id], @host.id)
|
|
29
30
|
assert_equal details.size, 1
|
|
30
|
-
assert_equal details[0], @entry1.detail
|
|
31
|
+
assert_equal details[0], [@entry1.detail, '0.22.0']
|
|
31
32
|
|
|
32
33
|
details = PreupgradeReportEntry.remediation_details([@entry1.id, @entry2.id], FactoryBot.create(:host))
|
|
33
34
|
assert_equal details.size, 0
|
|
@@ -19,6 +19,22 @@ class PreupgradeReportTest < ActiveSupport::TestCase
|
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
it 'stores the leapp version the report was generated with' do
|
|
23
|
+
data = { 'leapp_run_id' => 'leapp_c13e471c', 'entries' => [sample_entry_1] }
|
|
24
|
+
|
|
25
|
+
PreupgradeReport.create_report(host, data, job_invocation, '0.22.0')
|
|
26
|
+
|
|
27
|
+
assert_equal ['0.22.0'], PreupgradeReportEntry.where(host: host).pluck(:leapp_version)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'leaves the leapp version empty when it is not known' do
|
|
31
|
+
data = { 'leapp_run_id' => 'leapp_c13e471c', 'entries' => [sample_entry_1] }
|
|
32
|
+
|
|
33
|
+
PreupgradeReport.create_report(host, data, job_invocation)
|
|
34
|
+
|
|
35
|
+
assert_nil PreupgradeReportEntry.where(host: host).first.leapp_version
|
|
36
|
+
end
|
|
37
|
+
|
|
22
38
|
it 'no entries' do
|
|
23
39
|
data = { 'leapp_run_id' => 'leapp_c13e471c' }
|
|
24
40
|
|
|
@@ -40,4 +40,31 @@ module ForemanLeapp
|
|
|
40
40
|
it { assert_finalize_phase planned_action }
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
|
+
|
|
44
|
+
# Parsing the job output does not need any of the remote execution setup.
|
|
45
|
+
class PreupgradeJobOutputTest < ActiveSupport::TestCase
|
|
46
|
+
include Dynflow::Testing
|
|
47
|
+
|
|
48
|
+
let(:action) { create_action(Actions::ForemanLeapp::PreupgradeJob) }
|
|
49
|
+
|
|
50
|
+
describe '#leapp_version' do
|
|
51
|
+
test 'picks the leapp version up from the rpm output' do
|
|
52
|
+
output = "leapp-0.22.0-1.el9.noarch\n===leap_upgrade_report_start===\n{}\nExit status: 0\n"
|
|
53
|
+
|
|
54
|
+
assert_equal '0.22.0', action.send(:leapp_version, output)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
test 'ignores other leapp packages' do
|
|
58
|
+
output = "leapp-upgrade-el8toel9-0.25.0-1.el8.noarch\nleapp-0.22.0-1.el8.noarch\n"
|
|
59
|
+
|
|
60
|
+
assert_equal '0.22.0', action.send(:leapp_version, output)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
test 'returns nil when the leapp package is not reported' do
|
|
64
|
+
output = "package leapp is not installed\n===leap_upgrade_report_start===\n{}\n"
|
|
65
|
+
|
|
66
|
+
assert_nil action.send(:leapp_version, output)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
43
70
|
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'test_plugin_helper'
|
|
4
|
+
|
|
5
|
+
module ForemanLeapp
|
|
6
|
+
class RemediationPlanTest < ActiveSupport::TestCase
|
|
7
|
+
# Taken from a leapp <= 0.21 report - leapp quoted the arguments itself.
|
|
8
|
+
OLD_SYMLINK_CONTEXT = [
|
|
9
|
+
'sh',
|
|
10
|
+
'-c',
|
|
11
|
+
'"ln -snf usr/lib /lib && ln -snf var/log/leapp /space space && ' \
|
|
12
|
+
'ln -snf var/log/leapp /quote\'quote"',
|
|
13
|
+
].freeze
|
|
14
|
+
|
|
15
|
+
# The very same remediation as reported by leapp >= 0.22 - the arguments
|
|
16
|
+
# are reported verbatim. https://github.com/oamg/leapp-repository/pull/1520
|
|
17
|
+
NEW_SYMLINK_CONTEXT = [
|
|
18
|
+
'bash',
|
|
19
|
+
'-c',
|
|
20
|
+
'ln -snf "usr/lib" "/lib" && ln -snf "var/log/leapp" "/space space" && ' \
|
|
21
|
+
'ln -snf "var/log/leapp" "/quote\'quote"',
|
|
22
|
+
].freeze
|
|
23
|
+
|
|
24
|
+
describe '#command_line' do
|
|
25
|
+
test 'joins the arguments verbatim when leapp did the quoting' do
|
|
26
|
+
assert_equal OLD_SYMLINK_CONTEXT.join(' '),
|
|
27
|
+
RemediationPlan.command_line(OLD_SYMLINK_CONTEXT, true)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
test 'escapes the arguments when leapp reports them verbatim' do
|
|
31
|
+
line = RemediationPlan.command_line(NEW_SYMLINK_CONTEXT, false)
|
|
32
|
+
|
|
33
|
+
assert_equal NEW_SYMLINK_CONTEXT, Shellwords.split(line)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
test 'escapes shell metacharacters when leapp reports them verbatim' do
|
|
37
|
+
context = ['sed', '-i', 's/^AllowZoneDrifting=.*/AllowZoneDrifting=no/',
|
|
38
|
+
'/etc/firewalld/firewalld.conf']
|
|
39
|
+
|
|
40
|
+
line = RemediationPlan.command_line(context, false)
|
|
41
|
+
|
|
42
|
+
assert_equal context, Shellwords.split(line)
|
|
43
|
+
assert_not_includes line, '.*'
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe '#quoted_by_leapp?' do
|
|
48
|
+
test 'true for leapp older than 0.22' do
|
|
49
|
+
assert RemediationPlan.quoted_by_leapp?('0.21.0')
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
test 'false for leapp 0.22 and newer' do
|
|
53
|
+
assert_not RemediationPlan.quoted_by_leapp?('0.22.0')
|
|
54
|
+
assert_not RemediationPlan.quoted_by_leapp?('0.22')
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
test 'keeps the old quoting when the leapp version is unknown' do
|
|
58
|
+
[nil, ''].each do |leapp_version|
|
|
59
|
+
assert RemediationPlan.quoted_by_leapp?(leapp_version)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
test 'keeps the old quoting when the leapp version cannot be parsed' do
|
|
64
|
+
assert RemediationPlan.quoted_by_leapp?('not-a-version')
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
test 'handles a leapp version with a release suffix' do
|
|
68
|
+
assert_not RemediationPlan.quoted_by_leapp?('0.22.0-1.el9')
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
describe '#build' do
|
|
73
|
+
let(:detail) do
|
|
74
|
+
{ 'remediations' => [
|
|
75
|
+
{ 'type' => 'hint', 'context' => 'Set AllowZoneDrifting=no' },
|
|
76
|
+
{ 'type' => 'command', 'context' => %w[vgimportdevices] },
|
|
77
|
+
{ 'type' => 'command', 'context' => NEW_SYMLINK_CONTEXT },
|
|
78
|
+
] }
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
test 'renders one line per command remediation and skips the hints' do
|
|
82
|
+
lines = RemediationPlan.build(detail, '0.22.0').lines
|
|
83
|
+
|
|
84
|
+
assert_equal 2, lines.size
|
|
85
|
+
assert_equal ['vgimportdevices'], Shellwords.split(lines.first)
|
|
86
|
+
assert_equal NEW_SYMLINK_CONTEXT, Shellwords.split(lines.second)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
test 'returns an empty plan when there is nothing to run' do
|
|
90
|
+
assert_equal '', RemediationPlan.build(nil, '0.22.0')
|
|
91
|
+
assert_equal '',
|
|
92
|
+
RemediationPlan.build({ 'remediations' => [{ 'type' => 'hint', 'context' => 'meh.' }] },
|
|
93
|
+
'0.22.0')
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: foreman_leapp
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 5.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Foreman Leapp team
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-10-
|
|
10
|
+
date: 2026-10-26 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: foreman_remote_execution
|
|
@@ -61,6 +61,7 @@ files:
|
|
|
61
61
|
- app/helpers/foreman_leapp/hosts_helper.rb
|
|
62
62
|
- app/helpers/foreman_leapp/template_helper.rb
|
|
63
63
|
- app/lib/actions/foreman_leapp/preupgrade_job.rb
|
|
64
|
+
- app/lib/foreman_leapp/remediation_plan.rb
|
|
64
65
|
- app/lib/helpers/job_helper.rb
|
|
65
66
|
- app/models/concerns/foreman_leapp/job_invocation_extensions.rb
|
|
66
67
|
- app/models/preupgrade_report.rb
|
|
@@ -82,6 +83,7 @@ files:
|
|
|
82
83
|
- db/migrate/20200326142259_add_job_id_to_report.rb
|
|
83
84
|
- db/migrate/20200327091009_add_host_to_report.rb
|
|
84
85
|
- db/migrate/20200429080939_report_entries_flags.rb
|
|
86
|
+
- db/migrate/20260825120000_add_leapp_version_to_report_entries.rb
|
|
85
87
|
- db/seeds.d/10_leapp_preupgrade.rb
|
|
86
88
|
- lib/foreman_leapp.rb
|
|
87
89
|
- lib/foreman_leapp/engine.rb
|
|
@@ -115,6 +117,7 @@ files:
|
|
|
115
117
|
- test/test_plugin_helper.rb
|
|
116
118
|
- test/unit/actions/preupgrade_job_test.rb
|
|
117
119
|
- test/unit/helpers/job_helper_test.rb
|
|
120
|
+
- test/unit/remediation_plan_test.rb
|
|
118
121
|
- webpack/__mocks__/foremanReact/Root/Context/ForemanContext.js
|
|
119
122
|
- webpack/components/PreupgradeReportsTable/PreupgradeReportsTable.scss
|
|
120
123
|
- webpack/components/PreupgradeReportsTable/PreupgradeReportsTableHelpers.js
|
|
@@ -157,3 +160,4 @@ test_files:
|
|
|
157
160
|
- test/test_plugin_helper.rb
|
|
158
161
|
- test/unit/actions/preupgrade_job_test.rb
|
|
159
162
|
- test/unit/helpers/job_helper_test.rb
|
|
163
|
+
- test/unit/remediation_plan_test.rb
|