Build for the summer release (8.8.z) & CTC1
- Add back gating tests dropped by automatic migration to c8s - Include leap data files in the package - Introduce in-place upgrades for systems with enabled FIPS mode - Enable the upgrade path 8.8 -> 9.2 for RHEL with SAP HANA - Fix the upgrade of ruby-irb package - Resolves: rhbz#2030627, rhbz#2097003, rhbz#2203800, rhbz#2203803 Signed-off-by: Petr Stodulka <pstodulk@redhat.com>
This commit is contained in:
parent
9e18e82e4d
commit
443be74fe3
509321
0001-Introduce-leapp-data-in-the-RPM-repository.patch
Normal file
509321
0001-Introduce-leapp-data-in-the-RPM-repository.patch
Normal file
File diff suppressed because it is too large
Load Diff
98
0002-Add-el8toel9-actor-to-handle-directory-symlink.patch
Normal file
98
0002-Add-el8toel9-actor-to-handle-directory-symlink.patch
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
From 619982896c07aa453a1b48b2bf399e4fe4f723b2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jarek Prokop <jprokop@redhat.com>
|
||||||
|
Date: Fri, 21 Apr 2023 17:25:15 +0200
|
||||||
|
Subject: [PATCH 2/5] Add el8toel9 actor to handle directory -> symlink with
|
||||||
|
ruby IRB.
|
||||||
|
|
||||||
|
The `/usr/share/ruby/irb/` directory is a symlink in RHEL 9.
|
||||||
|
|
||||||
|
Simply remove the directory to then let the RPM mechanism create the
|
||||||
|
correct symlink on update.
|
||||||
|
|
||||||
|
Users should not expect to ever retain anything in this directory.
|
||||||
|
---
|
||||||
|
.../actors/registerrubyirbadjustment/actor.py | 22 ++++++++++++++++++
|
||||||
|
.../test_register_ruby_irb_adjustments.py | 11 +++++++++
|
||||||
|
.../el8toel9/tools/handlerubyirbsymlink | 23 +++++++++++++++++++
|
||||||
|
3 files changed, 56 insertions(+)
|
||||||
|
create mode 100644 repos/system_upgrade/el8toel9/actors/registerrubyirbadjustment/actor.py
|
||||||
|
create mode 100644 repos/system_upgrade/el8toel9/actors/registerrubyirbadjustment/tests/test_register_ruby_irb_adjustments.py
|
||||||
|
create mode 100755 repos/system_upgrade/el8toel9/tools/handlerubyirbsymlink
|
||||||
|
|
||||||
|
diff --git a/repos/system_upgrade/el8toel9/actors/registerrubyirbadjustment/actor.py b/repos/system_upgrade/el8toel9/actors/registerrubyirbadjustment/actor.py
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..ac4d1e6f
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/repos/system_upgrade/el8toel9/actors/registerrubyirbadjustment/actor.py
|
||||||
|
@@ -0,0 +1,22 @@
|
||||||
|
+from leapp.actors import Actor
|
||||||
|
+from leapp.models import DNFWorkaround
|
||||||
|
+from leapp.tags import FactsPhaseTag, IPUWorkflowTag
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class RegisterRubyIRBAdjustment(Actor):
|
||||||
|
+ """
|
||||||
|
+ Registers a workaround which will adjust the Ruby IRB directories during the upgrade.
|
||||||
|
+ """
|
||||||
|
+
|
||||||
|
+ name = 'register_ruby_irb_adjustment'
|
||||||
|
+ consumes = ()
|
||||||
|
+ produces = (DNFWorkaround,)
|
||||||
|
+ tags = (IPUWorkflowTag, FactsPhaseTag)
|
||||||
|
+
|
||||||
|
+ def process(self):
|
||||||
|
+ self.produce(
|
||||||
|
+ DNFWorkaround(
|
||||||
|
+ display_name='IRB directory fix',
|
||||||
|
+ script_path=self.get_tool_path('handlerubyirbsymlink'),
|
||||||
|
+ )
|
||||||
|
+ )
|
||||||
|
diff --git a/repos/system_upgrade/el8toel9/actors/registerrubyirbadjustment/tests/test_register_ruby_irb_adjustments.py b/repos/system_upgrade/el8toel9/actors/registerrubyirbadjustment/tests/test_register_ruby_irb_adjustments.py
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..fc341646
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/repos/system_upgrade/el8toel9/actors/registerrubyirbadjustment/tests/test_register_ruby_irb_adjustments.py
|
||||||
|
@@ -0,0 +1,11 @@
|
||||||
|
+import os.path
|
||||||
|
+
|
||||||
|
+from leapp.models import DNFWorkaround
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+def test_register_ruby_irb_adjustments(current_actor_context):
|
||||||
|
+ current_actor_context.run()
|
||||||
|
+ assert len(current_actor_context.consume(DNFWorkaround)) == 1
|
||||||
|
+ assert current_actor_context.consume(DNFWorkaround)[0].display_name == 'IRB directory fix'
|
||||||
|
+ assert os.path.basename(current_actor_context.consume(DNFWorkaround)[0].script_path) == 'handlerubyirbsymlink'
|
||||||
|
+ assert os.path.exists(current_actor_context.consume(DNFWorkaround)[0].script_path)
|
||||||
|
diff --git a/repos/system_upgrade/el8toel9/tools/handlerubyirbsymlink b/repos/system_upgrade/el8toel9/tools/handlerubyirbsymlink
|
||||||
|
new file mode 100755
|
||||||
|
index 00000000..9558dd48
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/repos/system_upgrade/el8toel9/tools/handlerubyirbsymlink
|
||||||
|
@@ -0,0 +1,23 @@
|
||||||
|
+#!/usr/bin/bash -e
|
||||||
|
+
|
||||||
|
+# just in case of hidden files.. not sure why would someone do that, it's more
|
||||||
|
+# like forgotten cache file possibility, but rather do that..
|
||||||
|
+shopt -s dotglob
|
||||||
|
+
|
||||||
|
+handle_dir() {
|
||||||
|
+ # Check that $1 is not already a symlink
|
||||||
|
+ # then remove the directory so that RPM can freely create the
|
||||||
|
+ # symlink.
|
||||||
|
+ if [ "$(readlink "$1")" == "/usr/share/gems/gems/irb-1.3.5" ]; then
|
||||||
|
+ return
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ # There is no configuration or anything that the user should ever customize
|
||||||
|
+ # and expect to retain.
|
||||||
|
+ rm -rf "$1"
|
||||||
|
+
|
||||||
|
+ return 0
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+handle_dir /usr/share/ruby/irb
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
558
0003-Enable-8-9-upgrades-with-FIPS-enabled-1053.patch
Normal file
558
0003-Enable-8-9-upgrades-with-FIPS-enabled-1053.patch
Normal file
@ -0,0 +1,558 @@
|
|||||||
|
From 0c03180b274e9245611a7379a997ac81c726a9e9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Michal=20He=C4=8Dko?= <michal.sk.com@gmail.com>
|
||||||
|
Date: Wed, 10 May 2023 16:51:49 +0200
|
||||||
|
Subject: [PATCH 3/5] Enable 8>9 upgrades with FIPS enabled (#1053)
|
||||||
|
|
||||||
|
Short story long:
|
||||||
|
==============
|
||||||
|
|
||||||
|
FIPS refers to a set of security standards governing many aspects of how information should be handled by computers and by people. FIPS in context of RHEL typically means FIPS 140, a single document defining rules for the use of encryption and cryptographic services. In essence, it defines requirements for cryptographic modules (e.g. what algorithms can be used, thus preventing the use of insecure ones) manipulating sensitive information.
|
||||||
|
|
||||||
|
From the point of view of upgrades there are 5 components that are certified under FIPS: kernel, OpenSSL, GnuTLS, NSS, and libgcrypt. As for the kernel, fips=1 needs to be present on the cmdline in order to enable FIPS in the kernel. Kernel offers a /proc/sys/crypto/fips_enabled virtual file containing the information about whether the kernel has booted with FIPS enabled.
|
||||||
|
|
||||||
|
According to FIPS, the userspace components need to verify that they were not tampered with, and thus they have to have some sort of checksum either in a special section of a binary, or in a separate file. The components read /proc/sys/crypto/fips_enabled to know when to switch into the FIPS enabled mode. OpenSSL does things a bit differently, by not including support for FIPS directly but via a special fips.so module. Furthermore, for OpenSSL to check whether FIPS is enabled a configuration file must be present at /etc/pki/tls/openssl.cnf, because the code checking for FIPS is a part of configuration parsing.
|
||||||
|
|
||||||
|
As every userspace component has different implementation of FIPS-mode, and a different way for the user to check whether the component believes that the system it is running on has FIPS enabled, there is no straightforward way for us to make really sure that all of the components run in FIPS enabled inside the target userspace container.
|
||||||
|
|
||||||
|
Brief summary of changes in the code:
|
||||||
|
* scanfips: split scanning for fips into a separate actor
|
||||||
|
* checkfips: inhibit the IPU only on 7>8
|
||||||
|
* in case of FIPS for IPU 8 -> 9, copy related files into the target container to be able to generate FIPS compliant initramfs
|
||||||
|
* checkfipsenabled: check for fips in upgrade initramfs (LastTestsPhase); interrupt the upgrade if FIPS is not enabled in the upgrade environment
|
||||||
|
* upgradeinitramfsgenerator: refactor library and tests due to FIPS
|
||||||
|
* create upgrade kernel hmac unconditionallly
|
||||||
|
---------
|
||||||
|
|
||||||
|
Co-authored-by: Michal Hecko <mhecko@redhat.com>
|
||||||
|
---
|
||||||
|
.../libraries/addupgradebootentry.py | 1 +
|
||||||
|
.../tests/unit_test_addupgradebootentry.py | 2 +-
|
||||||
|
.../common/actors/checkfips/actor.py | 50 +++++++++++++------
|
||||||
|
.../actors/checkfips/tests/test_checkfips.py | 23 +++++++++
|
||||||
|
.../initramfs/checkfipsenabled/actor.py | 21 ++++++++
|
||||||
|
.../checkfipsenabled/libraries/check_fips.py | 23 +++++++++
|
||||||
|
.../tests/test_checkfipsenabled.py | 31 ++++++++++++
|
||||||
|
.../upgradeinitramfsgenerator/actor.py | 2 +
|
||||||
|
.../files/generate-initram.sh | 3 ++
|
||||||
|
.../libraries/upgradeinitramfsgenerator.py | 28 ++++++++++-
|
||||||
|
.../unit_test_upgradeinitramfsgenerator.py | 16 +++++-
|
||||||
|
.../libraries/removebootfiles.py | 2 +-
|
||||||
|
.../tests/unit_test_removebootfiles.py | 4 +-
|
||||||
|
.../tests/unit_test_removeupgradebootentry.py | 2 +-
|
||||||
|
.../common/actors/scanfips/actor.py | 28 +++++++++++
|
||||||
|
.../tests/test_scanfips.py} | 13 +++--
|
||||||
|
.../common/models/bootcontent.py | 1 +
|
||||||
|
repos/system_upgrade/common/models/fips.py | 12 +++++
|
||||||
|
18 files changed, 233 insertions(+), 29 deletions(-)
|
||||||
|
create mode 100644 repos/system_upgrade/common/actors/checkfips/tests/test_checkfips.py
|
||||||
|
create mode 100644 repos/system_upgrade/common/actors/initramfs/checkfipsenabled/actor.py
|
||||||
|
create mode 100644 repos/system_upgrade/common/actors/initramfs/checkfipsenabled/libraries/check_fips.py
|
||||||
|
create mode 100644 repos/system_upgrade/common/actors/initramfs/checkfipsenabled/tests/test_checkfipsenabled.py
|
||||||
|
create mode 100644 repos/system_upgrade/common/actors/scanfips/actor.py
|
||||||
|
rename repos/system_upgrade/common/actors/{checkfips/tests/unit_test_checkfips.py => scanfips/tests/test_scanfips.py} (74%)
|
||||||
|
create mode 100644 repos/system_upgrade/common/models/fips.py
|
||||||
|
|
||||||
|
diff --git a/repos/system_upgrade/common/actors/addupgradebootentry/libraries/addupgradebootentry.py b/repos/system_upgrade/common/actors/addupgradebootentry/libraries/addupgradebootentry.py
|
||||||
|
index beddafec..4e1c4204 100644
|
||||||
|
--- a/repos/system_upgrade/common/actors/addupgradebootentry/libraries/addupgradebootentry.py
|
||||||
|
+++ b/repos/system_upgrade/common/actors/addupgradebootentry/libraries/addupgradebootentry.py
|
||||||
|
@@ -88,6 +88,7 @@ def get_boot_file_paths():
|
||||||
|
raise StopActorExecutionError('Could not create a GRUB boot entry for the upgrade initramfs',
|
||||||
|
details={'details': 'Did not receive a message about the leapp-provided'
|
||||||
|
'kernel and initramfs'})
|
||||||
|
+ # Returning information about kernel hmac file path is needless as it is not used when adding boot entry
|
||||||
|
return boot_content.kernel_path, boot_content.initram_path
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/repos/system_upgrade/common/actors/addupgradebootentry/tests/unit_test_addupgradebootentry.py b/repos/system_upgrade/common/actors/addupgradebootentry/tests/unit_test_addupgradebootentry.py
|
||||||
|
index cc442f8d..ddc37e52 100644
|
||||||
|
--- a/repos/system_upgrade/common/actors/addupgradebootentry/tests/unit_test_addupgradebootentry.py
|
||||||
|
+++ b/repos/system_upgrade/common/actors/addupgradebootentry/tests/unit_test_addupgradebootentry.py
|
||||||
|
@@ -135,7 +135,7 @@ def test_add_boot_entry_configs(monkeypatch):
|
||||||
|
def test_get_boot_file_paths(monkeypatch):
|
||||||
|
# BootContent message available
|
||||||
|
def consume_message_mocked(*models):
|
||||||
|
- yield BootContent(kernel_path='/ghi', initram_path='/jkl')
|
||||||
|
+ yield BootContent(kernel_path='/ghi', initram_path='/jkl', kernel_hmac_path='/path')
|
||||||
|
|
||||||
|
monkeypatch.setattr('leapp.libraries.stdlib.api.consume', consume_message_mocked)
|
||||||
|
|
||||||
|
diff --git a/repos/system_upgrade/common/actors/checkfips/actor.py b/repos/system_upgrade/common/actors/checkfips/actor.py
|
||||||
|
index e76af950..bd09b1b9 100644
|
||||||
|
--- a/repos/system_upgrade/common/actors/checkfips/actor.py
|
||||||
|
+++ b/repos/system_upgrade/common/actors/checkfips/actor.py
|
||||||
|
@@ -1,7 +1,8 @@
|
||||||
|
from leapp import reporting
|
||||||
|
from leapp.actors import Actor
|
||||||
|
from leapp.exceptions import StopActorExecutionError
|
||||||
|
-from leapp.models import KernelCmdline, Report
|
||||||
|
+from leapp.libraries.common.config import version
|
||||||
|
+from leapp.models import DracutModule, FIPSInfo, Report, UpgradeInitramfsTasks
|
||||||
|
from leapp.tags import ChecksPhaseTag, IPUWorkflowTag
|
||||||
|
|
||||||
|
|
||||||
|
@@ -11,25 +12,44 @@ class CheckFips(Actor):
|
||||||
|
"""
|
||||||
|
|
||||||
|
name = 'check_fips'
|
||||||
|
- consumes = (KernelCmdline,)
|
||||||
|
- produces = (Report,)
|
||||||
|
+ consumes = (FIPSInfo,)
|
||||||
|
+ produces = (Report, UpgradeInitramfsTasks)
|
||||||
|
tags = (IPUWorkflowTag, ChecksPhaseTag)
|
||||||
|
|
||||||
|
def process(self):
|
||||||
|
- cmdline = next(self.consume(KernelCmdline), None)
|
||||||
|
- if not cmdline:
|
||||||
|
- raise StopActorExecutionError('Cannot check FIPS state due to missing command line parameters',
|
||||||
|
- details={'Problem': 'Did not receive a message with kernel command '
|
||||||
|
- 'line parameters (KernelCmdline)'})
|
||||||
|
- for parameter in cmdline.parameters:
|
||||||
|
- if parameter.key == 'fips' and parameter.value == '1':
|
||||||
|
- title = 'Cannot upgrade a system with FIPS mode enabled'
|
||||||
|
- summary = 'Leapp has detected that FIPS is enabled on this system. ' \
|
||||||
|
- 'In-place upgrade of systems in FIPS mode is currently unsupported.'
|
||||||
|
+ fips_info = next(self.consume(FIPSInfo), None)
|
||||||
|
+
|
||||||
|
+ if not fips_info:
|
||||||
|
+ raise StopActorExecutionError('Cannot check FIPS state due to not receiving necessary FIPSInfo message',
|
||||||
|
+ details={'Problem': 'Did not receive a message with information about FIPS '
|
||||||
|
+ 'usage'})
|
||||||
|
+
|
||||||
|
+ if version.get_target_major_version() == '8':
|
||||||
|
+ if fips_info.is_enabled:
|
||||||
|
+ title = 'Automated upgrades from RHEL 7 to RHEL 8 in FIPS mode are not supported'
|
||||||
|
+ summary = ('Leapp has detected that FIPS is enabled on this system. '
|
||||||
|
+ 'Automated in-place upgrade of RHEL 7 systems in FIPS mode is currently unsupported '
|
||||||
|
+ 'and manual intervention is required.')
|
||||||
|
+
|
||||||
|
+ fips_7to8_steps_docs_url = 'https://red.ht/planning-upgrade-to-rhel8'
|
||||||
|
+
|
||||||
|
reporting.create_report([
|
||||||
|
reporting.Title(title),
|
||||||
|
reporting.Summary(summary),
|
||||||
|
reporting.Severity(reporting.Severity.HIGH),
|
||||||
|
- reporting.Groups([reporting.Groups.SECURITY]),
|
||||||
|
- reporting.Groups([reporting.Groups.INHIBITOR])
|
||||||
|
+ reporting.Groups([reporting.Groups.SECURITY, reporting.Groups.INHIBITOR]),
|
||||||
|
+ reporting.ExternalLink(url=fips_7to8_steps_docs_url,
|
||||||
|
+ title='Planning an upgrade from RHEL 7 to RHEL 8')
|
||||||
|
])
|
||||||
|
+ else:
|
||||||
|
+ # FIXME(mhecko): We include these files manually as they are not included automatically when the fips
|
||||||
|
+ # module is used due to a bug in dracut. This code should be removed, once the dracut bug is resolved.
|
||||||
|
+ # See https://bugzilla.redhat.com/show_bug.cgi?id=2176560
|
||||||
|
+ if fips_info.is_enabled:
|
||||||
|
+ fips_required_initramfs_files = [
|
||||||
|
+ '/etc/crypto-policies/back-ends/opensslcnf.config',
|
||||||
|
+ '/etc/pki/tls/openssl.cnf',
|
||||||
|
+ '/usr/lib64/ossl-modules/fips.so',
|
||||||
|
+ ]
|
||||||
|
+ self.produce(UpgradeInitramfsTasks(include_files=fips_required_initramfs_files,
|
||||||
|
+ include_dracut_modules=[DracutModule(name='fips')]))
|
||||||
|
diff --git a/repos/system_upgrade/common/actors/checkfips/tests/test_checkfips.py b/repos/system_upgrade/common/actors/checkfips/tests/test_checkfips.py
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..5498bf23
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/repos/system_upgrade/common/actors/checkfips/tests/test_checkfips.py
|
||||||
|
@@ -0,0 +1,23 @@
|
||||||
|
+import pytest
|
||||||
|
+
|
||||||
|
+from leapp.libraries.common.config import version
|
||||||
|
+from leapp.models import FIPSInfo, Report
|
||||||
|
+from leapp.utils.report import is_inhibitor
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+@pytest.mark.parametrize(('fips_info', 'target_major_version', 'should_inhibit'), [
|
||||||
|
+ (FIPSInfo(is_enabled=True), '8', True),
|
||||||
|
+ (FIPSInfo(is_enabled=True), '9', False),
|
||||||
|
+ (FIPSInfo(is_enabled=False), '8', False),
|
||||||
|
+ (FIPSInfo(is_enabled=False), '9', False),
|
||||||
|
+])
|
||||||
|
+def test_check_fips(monkeypatch, current_actor_context, fips_info, target_major_version, should_inhibit):
|
||||||
|
+ monkeypatch.setattr(version, 'get_target_major_version', lambda: target_major_version)
|
||||||
|
+ current_actor_context.feed(fips_info)
|
||||||
|
+ current_actor_context.run()
|
||||||
|
+ if should_inhibit:
|
||||||
|
+ output = current_actor_context.consume(Report)
|
||||||
|
+ assert len(output) == 1
|
||||||
|
+ assert is_inhibitor(output[0].report)
|
||||||
|
+ else:
|
||||||
|
+ assert not any(is_inhibitor(msg.report) for msg in current_actor_context.consume(Report))
|
||||||
|
diff --git a/repos/system_upgrade/common/actors/initramfs/checkfipsenabled/actor.py b/repos/system_upgrade/common/actors/initramfs/checkfipsenabled/actor.py
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..ef1930da
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/repos/system_upgrade/common/actors/initramfs/checkfipsenabled/actor.py
|
||||||
|
@@ -0,0 +1,21 @@
|
||||||
|
+from leapp.actors import Actor
|
||||||
|
+from leapp.libraries.actor import check_fips as check_fips_lib
|
||||||
|
+from leapp.models import FIPSInfo
|
||||||
|
+from leapp.tags import IPUWorkflowTag, LateTestsPhaseTag
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class CheckFIPSCorrectlyEnabled(Actor):
|
||||||
|
+ """
|
||||||
|
+ Sanity check to stop the IPU if the system did not boot into the upgrade initramfs with FIPS settings preserved.
|
||||||
|
+
|
||||||
|
+ The performed check should be unlikely to fail, as it would mean that the upgrade boot entry was created without
|
||||||
|
+ fips=1 on the kernel cmdline.
|
||||||
|
+ """
|
||||||
|
+
|
||||||
|
+ name = 'check_fips_correctly_enabled'
|
||||||
|
+ consumes = (FIPSInfo,)
|
||||||
|
+ produces = ()
|
||||||
|
+ tags = (LateTestsPhaseTag, IPUWorkflowTag)
|
||||||
|
+
|
||||||
|
+ def process(self):
|
||||||
|
+ check_fips_lib.check_fips_state_perserved()
|
||||||
|
diff --git a/repos/system_upgrade/common/actors/initramfs/checkfipsenabled/libraries/check_fips.py b/repos/system_upgrade/common/actors/initramfs/checkfipsenabled/libraries/check_fips.py
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..ba236619
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/repos/system_upgrade/common/actors/initramfs/checkfipsenabled/libraries/check_fips.py
|
||||||
|
@@ -0,0 +1,23 @@
|
||||||
|
+from leapp.exceptions import StopActorExecutionError
|
||||||
|
+from leapp.libraries.stdlib import api
|
||||||
|
+from leapp.models import FIPSInfo
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+def read_sys_fips_state():
|
||||||
|
+ with open('/proc/sys/crypto/fips_enabled') as fips_status_handle:
|
||||||
|
+ return fips_status_handle.read().strip()
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+def check_fips_state_perserved():
|
||||||
|
+ fips_info = next(api.consume(FIPSInfo), None)
|
||||||
|
+ if not fips_info:
|
||||||
|
+ # Unexpected, FIPSInfo is produced unconditionally
|
||||||
|
+ raise StopActorExecutionError('Cannot check for the correct FIPS state in the upgrade initramfs',
|
||||||
|
+ details={'Problem': 'Did not receive any FIPSInfo message'})
|
||||||
|
+
|
||||||
|
+ if fips_info.is_enabled:
|
||||||
|
+ fips_status = read_sys_fips_state()
|
||||||
|
+ if fips_status != '1':
|
||||||
|
+ details = {'details': ('The system is reporting FIPS as disabled, although it should be enabled'
|
||||||
|
+ ' since it was enabled on the source system.')}
|
||||||
|
+ raise StopActorExecutionError('Failed to enable FIPS in the upgrade initramfs', details=details)
|
||||||
|
diff --git a/repos/system_upgrade/common/actors/initramfs/checkfipsenabled/tests/test_checkfipsenabled.py b/repos/system_upgrade/common/actors/initramfs/checkfipsenabled/tests/test_checkfipsenabled.py
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..9a396e8a
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/repos/system_upgrade/common/actors/initramfs/checkfipsenabled/tests/test_checkfipsenabled.py
|
||||||
|
@@ -0,0 +1,31 @@
|
||||||
|
+import pytest
|
||||||
|
+
|
||||||
|
+from leapp.exceptions import StopActorExecutionError
|
||||||
|
+from leapp.libraries.actor import check_fips
|
||||||
|
+from leapp.libraries.common.testutils import CurrentActorMocked
|
||||||
|
+from leapp.libraries.stdlib import api
|
||||||
|
+from leapp.models import FIPSInfo
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+@pytest.mark.parametrize(
|
||||||
|
+ ('fips_info', 'sys_fips_enabled_contents', 'should_prevent_ipu'),
|
||||||
|
+ (
|
||||||
|
+ (FIPSInfo(is_enabled=False), '0', False),
|
||||||
|
+ (FIPSInfo(is_enabled=True), '0', True),
|
||||||
|
+ (FIPSInfo(is_enabled=True), '1', False),
|
||||||
|
+ )
|
||||||
|
+)
|
||||||
|
+def test_ipu_prevention_if_fips_not_perserved(monkeypatch,
|
||||||
|
+ fips_info,
|
||||||
|
+ sys_fips_enabled_contents,
|
||||||
|
+ should_prevent_ipu):
|
||||||
|
+
|
||||||
|
+ mocked_actor = CurrentActorMocked(msgs=[fips_info])
|
||||||
|
+ monkeypatch.setattr(check_fips, 'read_sys_fips_state', lambda: sys_fips_enabled_contents)
|
||||||
|
+ monkeypatch.setattr(api, 'current_actor', mocked_actor)
|
||||||
|
+
|
||||||
|
+ if should_prevent_ipu:
|
||||||
|
+ with pytest.raises(StopActorExecutionError):
|
||||||
|
+ check_fips.check_fips_state_perserved()
|
||||||
|
+ else:
|
||||||
|
+ check_fips.check_fips_state_perserved() # unhandled exception with crash the test
|
||||||
|
diff --git a/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/actor.py b/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/actor.py
|
||||||
|
index dc97172a..2c52e817 100644
|
||||||
|
--- a/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/actor.py
|
||||||
|
+++ b/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/actor.py
|
||||||
|
@@ -4,6 +4,7 @@ from leapp.models import RequiredUpgradeInitramPackages # deprecated
|
||||||
|
from leapp.models import UpgradeDracutModule # deprecated
|
||||||
|
from leapp.models import (
|
||||||
|
BootContent,
|
||||||
|
+ FIPSInfo,
|
||||||
|
TargetOSInstallationImage,
|
||||||
|
TargetUserSpaceInfo,
|
||||||
|
TargetUserSpaceUpgradeTasks,
|
||||||
|
@@ -27,6 +28,7 @@ class UpgradeInitramfsGenerator(Actor):
|
||||||
|
|
||||||
|
name = 'upgrade_initramfs_generator'
|
||||||
|
consumes = (
|
||||||
|
+ FIPSInfo,
|
||||||
|
RequiredUpgradeInitramPackages, # deprecated
|
||||||
|
TargetOSInstallationImage,
|
||||||
|
TargetUserSpaceInfo,
|
||||||
|
diff --git a/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/files/generate-initram.sh b/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/files/generate-initram.sh
|
||||||
|
index 104af586..d6934147 100755
|
||||||
|
--- a/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/files/generate-initram.sh
|
||||||
|
+++ b/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/files/generate-initram.sh
|
||||||
|
@@ -78,6 +78,9 @@ build() {
|
||||||
|
}
|
||||||
|
\cp "/lib/modules/${KERNEL_VERSION}/vmlinuz" "vmlinuz-upgrade.$KERNEL_ARCH"
|
||||||
|
|
||||||
|
+ # Copy out kernel HMAC so that integrity checks can be performed (performed only in FIPS mode)
|
||||||
|
+ \cp "/lib/modules/${KERNEL_VERSION}/.vmlinuz.hmac" ".vmlinuz-upgrade.$KERNEL_ARCH.hmac"
|
||||||
|
+
|
||||||
|
stage "Building initram disk for kernel: $KERNEL_VERSION"
|
||||||
|
\dracut \
|
||||||
|
-vvvv \
|
||||||
|
diff --git a/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/libraries/upgradeinitramfsgenerator.py b/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/libraries/upgradeinitramfsgenerator.py
|
||||||
|
index f6539b25..2f145217 100644
|
||||||
|
--- a/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/libraries/upgradeinitramfsgenerator.py
|
||||||
|
+++ b/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/libraries/upgradeinitramfsgenerator.py
|
||||||
|
@@ -180,6 +180,24 @@ def generate_initram_disk(context):
|
||||||
|
copy_boot_files(context)
|
||||||
|
|
||||||
|
|
||||||
|
+def create_upgrade_hmac_from_target_hmac(original_hmac_path, upgrade_hmac_path, upgrade_kernel):
|
||||||
|
+ # Rename the kernel name stored in the HMAC file as the upgrade kernel is named differently and the HMAC file
|
||||||
|
+ # refers to the real target kernel
|
||||||
|
+ with open(original_hmac_path) as original_hmac_file:
|
||||||
|
+ hmac_file_lines = [line for line in original_hmac_file.read().split('\n') if line]
|
||||||
|
+ if len(hmac_file_lines) > 1:
|
||||||
|
+ details = ('Expected the target kernel HMAC file to containing only one HMAC line, '
|
||||||
|
+ 'found {0}'.format(len(hmac_file_lines)))
|
||||||
|
+ raise StopActorExecutionError('Failed to prepare HMAC file for upgrade kernel.',
|
||||||
|
+ details={'details': details})
|
||||||
|
+
|
||||||
|
+ # Keep only non-empty strings after splitting on space
|
||||||
|
+ hmac, dummy_target_kernel_name = [fragment for fragment in hmac_file_lines[0].split(' ') if fragment]
|
||||||
|
+
|
||||||
|
+ with open(upgrade_hmac_path, 'w') as upgrade_kernel_hmac_file:
|
||||||
|
+ upgrade_kernel_hmac_file.write('{hmac} {kernel}\n'.format(hmac=hmac, kernel=upgrade_kernel))
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def copy_boot_files(context):
|
||||||
|
"""
|
||||||
|
Function to copy the generated initram and corresponding kernel to /boot - Additionally produces a BootContent
|
||||||
|
@@ -188,14 +206,22 @@ def copy_boot_files(context):
|
||||||
|
curr_arch = api.current_actor().configuration.architecture
|
||||||
|
kernel = 'vmlinuz-upgrade.{}'.format(curr_arch)
|
||||||
|
initram = 'initramfs-upgrade.{}.img'.format(curr_arch)
|
||||||
|
+
|
||||||
|
+ kernel_hmac = '.{0}.hmac'.format(kernel)
|
||||||
|
+ kernel_hmac_path = os.path.join('/boot', kernel_hmac)
|
||||||
|
+
|
||||||
|
content = BootContent(
|
||||||
|
kernel_path=os.path.join('/boot', kernel),
|
||||||
|
- initram_path=os.path.join('/boot', initram)
|
||||||
|
+ initram_path=os.path.join('/boot', initram),
|
||||||
|
+ kernel_hmac_path=kernel_hmac_path
|
||||||
|
)
|
||||||
|
|
||||||
|
context.copy_from(os.path.join('/artifacts', kernel), content.kernel_path)
|
||||||
|
context.copy_from(os.path.join('/artifacts', initram), content.initram_path)
|
||||||
|
|
||||||
|
+ kernel_hmac_path = context.full_path(os.path.join('/artifacts', kernel_hmac))
|
||||||
|
+ create_upgrade_hmac_from_target_hmac(kernel_hmac_path, content.kernel_hmac_path, kernel)
|
||||||
|
+
|
||||||
|
api.produce(content)
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/tests/unit_test_upgradeinitramfsgenerator.py b/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/tests/unit_test_upgradeinitramfsgenerator.py
|
||||||
|
index 13939df1..cd9d0546 100644
|
||||||
|
--- a/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/tests/unit_test_upgradeinitramfsgenerator.py
|
||||||
|
+++ b/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/tests/unit_test_upgradeinitramfsgenerator.py
|
||||||
|
@@ -10,6 +10,7 @@ from leapp.libraries.common.testutils import CurrentActorMocked, logger_mocked,
|
||||||
|
from leapp.utils.deprecation import suppress_deprecation
|
||||||
|
|
||||||
|
from leapp.models import ( # isort:skip
|
||||||
|
+ FIPSInfo,
|
||||||
|
RequiredUpgradeInitramPackages, # deprecated
|
||||||
|
UpgradeDracutModule, # deprecated
|
||||||
|
BootContent,
|
||||||
|
@@ -133,19 +134,32 @@ class MockedLogger(logger_mocked):
|
||||||
|
@pytest.mark.parametrize('arch', architecture.ARCH_SUPPORTED)
|
||||||
|
def test_copy_boot_files(monkeypatch, arch):
|
||||||
|
kernel = 'vmlinuz-upgrade.{}'.format(arch)
|
||||||
|
+ kernel_hmac = '.vmlinuz-upgrade.{}.hmac'.format(arch)
|
||||||
|
initram = 'initramfs-upgrade.{}.img'.format(arch)
|
||||||
|
bootc = BootContent(
|
||||||
|
kernel_path=os.path.join('/boot', kernel),
|
||||||
|
+ kernel_hmac_path=os.path.join('/boot', kernel_hmac),
|
||||||
|
initram_path=os.path.join('/boot', initram)
|
||||||
|
)
|
||||||
|
|
||||||
|
+ context = MockedContext()
|
||||||
|
monkeypatch.setattr(upgradeinitramfsgenerator.api, 'current_actor', CurrentActorMocked(arch=arch))
|
||||||
|
monkeypatch.setattr(upgradeinitramfsgenerator.api, 'produce', produce_mocked())
|
||||||
|
- context = MockedContext()
|
||||||
|
+
|
||||||
|
+ def create_upgrade_hmac_from_target_hmac_mock(original_hmac_path, upgrade_hmac_path, upgrade_kernel):
|
||||||
|
+ hmac_file = '.{}.hmac'.format(upgrade_kernel)
|
||||||
|
+ assert original_hmac_path == os.path.join(context.full_path('/artifacts'), hmac_file)
|
||||||
|
+ assert upgrade_hmac_path == bootc.kernel_hmac_path
|
||||||
|
+
|
||||||
|
+ monkeypatch.setattr(upgradeinitramfsgenerator,
|
||||||
|
+ 'create_upgrade_hmac_from_target_hmac',
|
||||||
|
+ create_upgrade_hmac_from_target_hmac_mock)
|
||||||
|
+
|
||||||
|
upgradeinitramfsgenerator.copy_boot_files(context)
|
||||||
|
assert len(context.called_copy_from) == 2
|
||||||
|
assert (os.path.join('/artifacts', kernel), bootc.kernel_path) in context.called_copy_from
|
||||||
|
assert (os.path.join('/artifacts', initram), bootc.initram_path) in context.called_copy_from
|
||||||
|
+
|
||||||
|
assert upgradeinitramfsgenerator.api.produce.called == 1
|
||||||
|
assert upgradeinitramfsgenerator.api.produce.model_instances[0] == bootc
|
||||||
|
|
||||||
|
diff --git a/repos/system_upgrade/common/actors/removebootfiles/libraries/removebootfiles.py b/repos/system_upgrade/common/actors/removebootfiles/libraries/removebootfiles.py
|
||||||
|
index a0eccbb8..d31af906 100644
|
||||||
|
--- a/repos/system_upgrade/common/actors/removebootfiles/libraries/removebootfiles.py
|
||||||
|
+++ b/repos/system_upgrade/common/actors/removebootfiles/libraries/removebootfiles.py
|
||||||
|
@@ -14,7 +14,7 @@ def remove_boot_files():
|
||||||
|
api.current_logger().warning('Did not receive a message about the leapp-provided kernel and initramfs ->'
|
||||||
|
' Skipping removal of these files.')
|
||||||
|
raise StopActorExecution
|
||||||
|
- for filepath in boot_content.kernel_path, boot_content.initram_path:
|
||||||
|
+ for filepath in boot_content.kernel_path, boot_content.initram_path, boot_content.kernel_hmac_path:
|
||||||
|
remove_file(filepath)
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/repos/system_upgrade/common/actors/removebootfiles/tests/unit_test_removebootfiles.py b/repos/system_upgrade/common/actors/removebootfiles/tests/unit_test_removebootfiles.py
|
||||||
|
index dab94e89..7e5fbbf0 100644
|
||||||
|
--- a/repos/system_upgrade/common/actors/removebootfiles/tests/unit_test_removebootfiles.py
|
||||||
|
+++ b/repos/system_upgrade/common/actors/removebootfiles/tests/unit_test_removebootfiles.py
|
||||||
|
@@ -20,14 +20,14 @@ class remove_file_mocked(object):
|
||||||
|
def test_remove_boot_files(monkeypatch):
|
||||||
|
# BootContent message available
|
||||||
|
def consume_message_mocked(*models):
|
||||||
|
- yield BootContent(kernel_path='/abc', initram_path='/def')
|
||||||
|
+ yield BootContent(kernel_path='/abc', initram_path='/def', kernel_hmac_path='/ghi')
|
||||||
|
|
||||||
|
monkeypatch.setattr('leapp.libraries.stdlib.api.consume', consume_message_mocked)
|
||||||
|
monkeypatch.setattr(removebootfiles, 'remove_file', remove_file_mocked())
|
||||||
|
|
||||||
|
removebootfiles.remove_boot_files()
|
||||||
|
|
||||||
|
- assert removebootfiles.remove_file.files_to_remove == ['/abc', '/def']
|
||||||
|
+ assert removebootfiles.remove_file.files_to_remove == ['/abc', '/def', '/ghi']
|
||||||
|
|
||||||
|
# No BootContent message available
|
||||||
|
def consume_no_message_mocked(*models):
|
||||||
|
diff --git a/repos/system_upgrade/common/actors/removeupgradebootentry/tests/unit_test_removeupgradebootentry.py b/repos/system_upgrade/common/actors/removeupgradebootentry/tests/unit_test_removeupgradebootentry.py
|
||||||
|
index 1bf48c15..54eec552 100644
|
||||||
|
--- a/repos/system_upgrade/common/actors/removeupgradebootentry/tests/unit_test_removeupgradebootentry.py
|
||||||
|
+++ b/repos/system_upgrade/common/actors/removeupgradebootentry/tests/unit_test_removeupgradebootentry.py
|
||||||
|
@@ -50,7 +50,7 @@ def test_remove_boot_entry(firmware, arch, monkeypatch):
|
||||||
|
def test_get_upgrade_kernel_filepath(monkeypatch):
|
||||||
|
# BootContent message available
|
||||||
|
def consume_message_mocked(*models):
|
||||||
|
- yield BootContent(kernel_path='/abc', initram_path='/def')
|
||||||
|
+ yield BootContent(kernel_path='/abc', initram_path='/def', kernel_hmac_path='/ghi')
|
||||||
|
|
||||||
|
monkeypatch.setattr(api, 'consume', consume_message_mocked)
|
||||||
|
|
||||||
|
diff --git a/repos/system_upgrade/common/actors/scanfips/actor.py b/repos/system_upgrade/common/actors/scanfips/actor.py
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..f369b796
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/repos/system_upgrade/common/actors/scanfips/actor.py
|
||||||
|
@@ -0,0 +1,28 @@
|
||||||
|
+from leapp.actors import Actor
|
||||||
|
+from leapp.exceptions import StopActorExecutionError
|
||||||
|
+from leapp.models import FIPSInfo, KernelCmdline
|
||||||
|
+from leapp.tags import FactsPhaseTag, IPUWorkflowTag
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class ScanFIPS(Actor):
|
||||||
|
+ """
|
||||||
|
+ Determine whether the source system has FIPS enabled.
|
||||||
|
+ """
|
||||||
|
+
|
||||||
|
+ name = 'scan_fips'
|
||||||
|
+ consumes = (KernelCmdline,)
|
||||||
|
+ produces = (FIPSInfo,)
|
||||||
|
+ tags = (IPUWorkflowTag, FactsPhaseTag)
|
||||||
|
+
|
||||||
|
+ def process(self):
|
||||||
|
+ cmdline = next(self.consume(KernelCmdline), None)
|
||||||
|
+ if not cmdline:
|
||||||
|
+ raise StopActorExecutionError('Cannot check FIPS state due to missing command line parameters',
|
||||||
|
+ details={'Problem': 'Did not receive a message with kernel command '
|
||||||
|
+ 'line parameters (KernelCmdline)'})
|
||||||
|
+
|
||||||
|
+ for parameter in cmdline.parameters:
|
||||||
|
+ if parameter.key == 'fips' and parameter.value == '1':
|
||||||
|
+ self.produce(FIPSInfo(is_enabled=True))
|
||||||
|
+ return
|
||||||
|
+ self.produce(FIPSInfo(is_enabled=False))
|
||||||
|
diff --git a/repos/system_upgrade/common/actors/checkfips/tests/unit_test_checkfips.py b/repos/system_upgrade/common/actors/scanfips/tests/test_scanfips.py
|
||||||
|
similarity index 74%
|
||||||
|
rename from repos/system_upgrade/common/actors/checkfips/tests/unit_test_checkfips.py
|
||||||
|
rename to repos/system_upgrade/common/actors/scanfips/tests/test_scanfips.py
|
||||||
|
index 7774352e..c5f6ac66 100644
|
||||||
|
--- a/repos/system_upgrade/common/actors/checkfips/tests/unit_test_checkfips.py
|
||||||
|
+++ b/repos/system_upgrade/common/actors/scanfips/tests/test_scanfips.py
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
-from leapp.models import KernelCmdline, KernelCmdlineArg, Report
|
||||||
|
+from leapp.models import FIPSInfo, KernelCmdline, KernelCmdlineArg
|
||||||
|
from leapp.snactor.fixture import current_actor_context
|
||||||
|
|
||||||
|
ballast1 = [KernelCmdlineArg(key=k, value=v) for k, v in [
|
||||||
|
@@ -19,7 +19,7 @@ ballast2 = [KernelCmdlineArg(key=k, value=v) for k, v in [
|
||||||
|
('LANG', 'en_US.UTF-8')]]
|
||||||
|
|
||||||
|
|
||||||
|
-@pytest.mark.parametrize('parameters,expected_report', [
|
||||||
|
+@pytest.mark.parametrize(('parameters', 'should_detect_enabled_fips'), [
|
||||||
|
([], False),
|
||||||
|
([KernelCmdlineArg(key='fips', value='')], False),
|
||||||
|
([KernelCmdlineArg(key='fips', value='0')], False),
|
||||||
|
@@ -27,11 +27,10 @@ ballast2 = [KernelCmdlineArg(key=k, value=v) for k, v in [
|
||||||
|
([KernelCmdlineArg(key='fips', value='11')], False),
|
||||||
|
([KernelCmdlineArg(key='fips', value='yes')], False)
|
||||||
|
])
|
||||||
|
-def test_check_fips(current_actor_context, parameters, expected_report):
|
||||||
|
+def test_check_fips(current_actor_context, parameters, should_detect_enabled_fips):
|
||||||
|
cmdline = KernelCmdline(parameters=ballast1+parameters+ballast2)
|
||||||
|
current_actor_context.feed(cmdline)
|
||||||
|
current_actor_context.run()
|
||||||
|
- if expected_report:
|
||||||
|
- assert current_actor_context.consume(Report)
|
||||||
|
- else:
|
||||||
|
- assert not current_actor_context.consume(Report)
|
||||||
|
+ produced_msgs = current_actor_context.consume(FIPSInfo)
|
||||||
|
+
|
||||||
|
+ assert (FIPSInfo(is_enabled=should_detect_enabled_fips),) == produced_msgs
|
||||||
|
diff --git a/repos/system_upgrade/common/models/bootcontent.py b/repos/system_upgrade/common/models/bootcontent.py
|
||||||
|
index 03efa8f6..edada01e 100644
|
||||||
|
--- a/repos/system_upgrade/common/models/bootcontent.py
|
||||||
|
+++ b/repos/system_upgrade/common/models/bootcontent.py
|
||||||
|
@@ -11,3 +11,4 @@ class BootContent(Model):
|
||||||
|
|
||||||
|
kernel_path = fields.String(help='Filepath of the kernel copied to /boot/ by Leapp.')
|
||||||
|
initram_path = fields.String(help='Filepath of the initramfs copied to /boot/ by Leapp.')
|
||||||
|
+ kernel_hmac_path = fields.String(help='Filepath of the kernel hmac copied to /boot/ by Leapp.')
|
||||||
|
diff --git a/repos/system_upgrade/common/models/fips.py b/repos/system_upgrade/common/models/fips.py
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..aa9930db
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/repos/system_upgrade/common/models/fips.py
|
||||||
|
@@ -0,0 +1,12 @@
|
||||||
|
+from leapp.models import fields, Model
|
||||||
|
+from leapp.topics import SystemInfoTopic
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class FIPSInfo(Model):
|
||||||
|
+ """
|
||||||
|
+ Information about whether the source system has FIPS enabled.
|
||||||
|
+ """
|
||||||
|
+ topic = SystemInfoTopic
|
||||||
|
+
|
||||||
|
+ is_enabled = fields.Boolean(default=False)
|
||||||
|
+ """ Is fips enabled on the source system """
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
259
0004-Change-the-upgrade-paths-for-SAP-HANA.patch
Normal file
259
0004-Change-the-upgrade-paths-for-SAP-HANA.patch
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
From 24bfcccc59047c43237ce1b0202245314eca7158 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Irina Gulina <igulina@redhat.com>
|
||||||
|
Date: Fri, 5 May 2023 08:43:19 +0200
|
||||||
|
Subject: [PATCH 4/5] Change the upgrade paths for SAP HANA
|
||||||
|
|
||||||
|
- Drop 7.9 to 8.2
|
||||||
|
- Add 7.9 to 8.8, but keep 7.9 to 8.6 as default
|
||||||
|
- Add 8.8 to 9.2
|
||||||
|
- Drop SAP HANA version check for the target releases >=8.8 and >=9.2
|
||||||
|
- Correct actor.py docstring to support ppc64le for 8to9 upgrade (see PR1042)
|
||||||
|
---
|
||||||
|
.../common/actors/checksaphana/actor.py | 11 +++-
|
||||||
|
.../checksaphana/libraries/checksaphana.py | 57 ++++++++++++-------
|
||||||
|
.../checksaphana/tests/test_checksaphana.py | 31 +---------
|
||||||
|
.../common/files/upgrade_paths.json | 7 ++-
|
||||||
|
.../common/libraries/config/version.py | 2 +-
|
||||||
|
5 files changed, 50 insertions(+), 58 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/repos/system_upgrade/common/actors/checksaphana/actor.py b/repos/system_upgrade/common/actors/checksaphana/actor.py
|
||||||
|
index 70e78147..97d00455 100644
|
||||||
|
--- a/repos/system_upgrade/common/actors/checksaphana/actor.py
|
||||||
|
+++ b/repos/system_upgrade/common/actors/checksaphana/actor.py
|
||||||
|
@@ -12,10 +12,15 @@ class CheckSapHana(Actor):
|
||||||
|
If the upgrade flavour is 'default' no checks are being executed.
|
||||||
|
|
||||||
|
The following checks are executed:
|
||||||
|
- - If this system is _NOT_ running on x86_64, the upgrade is inhibited.
|
||||||
|
- - If SAP HANA 1 has been detected on the system the upgrade is inhibited since it is not supported on RHEL8.
|
||||||
|
+ - If the major target release is 8, and this system is _NOT_ running on x86_64, the upgrade is inhibited.
|
||||||
|
+ - If the major target release is 9, and this system is _NOT_ running on x86_64 or ppc64le,
|
||||||
|
+ the upgrade is inhibited.
|
||||||
|
+ - If SAP HANA 1 has been detected on the system the upgrade is inhibited since there is no supported upgrade path
|
||||||
|
+ with installed SAP HANA 1.
|
||||||
|
- If SAP HANA 2 has been detected, the upgrade will be inhibited if an unsupported version for the target release
|
||||||
|
- has been detected.
|
||||||
|
+ has been detected (<8.8, <9.2).
|
||||||
|
+ - If the target release >=8.8 or >=9.2, the upgrade will be inhibited unless a user confirms to proceed
|
||||||
|
+ for the currently installed SAP HANA 2.0 version and the chosen target release.
|
||||||
|
- If SAP HANA is running the upgrade is inhibited.
|
||||||
|
"""
|
||||||
|
|
||||||
|
diff --git a/repos/system_upgrade/common/actors/checksaphana/libraries/checksaphana.py b/repos/system_upgrade/common/actors/checksaphana/libraries/checksaphana.py
|
||||||
|
index 92109997..1b08f3d2 100644
|
||||||
|
--- a/repos/system_upgrade/common/actors/checksaphana/libraries/checksaphana.py
|
||||||
|
+++ b/repos/system_upgrade/common/actors/checksaphana/libraries/checksaphana.py
|
||||||
|
@@ -10,20 +10,36 @@ SAP_HANA_SUPPORTER_ARCHS = {
|
||||||
|
'9': [architecture.ARCH_X86_64, architecture.ARCH_PPC64LE]
|
||||||
|
}
|
||||||
|
|
||||||
|
-# SAP HANA 2.00 rev 54 is the minimal supported revision for both RHEL 7.9 and RHEL 8.2
|
||||||
|
-
|
||||||
|
SAP_HANA_MINIMAL_MAJOR_VERSION = 2
|
||||||
|
-# RHEL 8.2 target requirements
|
||||||
|
-SAP_HANA_RHEL82_REQUIRED_PATCH_LEVELS = ((5, 54, 0),)
|
||||||
|
-SAP_HANA_RHEL82_MINIMAL_VERSION_STRING = 'HANA 2.0 SPS05 rev 54 or later'
|
||||||
|
|
||||||
|
# RHEL 8.6 target requirements
|
||||||
|
SAP_HANA_RHEL86_REQUIRED_PATCH_LEVELS = ((5, 59, 2),)
|
||||||
|
SAP_HANA_RHEL86_MINIMAL_VERSION_STRING = 'HANA 2.0 SPS05 rev 59.02 or later'
|
||||||
|
|
||||||
|
-# RHEL 9 target requirements
|
||||||
|
-SAP_HANA_RHEL9_REQUIRED_PATCH_LEVELS = ((5, 59, 4), (6, 63, 0))
|
||||||
|
-SAP_HANA_RHEL9_MINIMAL_VERSION_STRING = 'HANA 2.0 SPS05 rev 59.04 or later, or SPS06 rev 63 or later'
|
||||||
|
+# RHEL 9.0 target requirements
|
||||||
|
+SAP_HANA_RHEL90_REQUIRED_PATCH_LEVELS = ((5, 59, 4), (6, 63, 0))
|
||||||
|
+SAP_HANA_RHEL90_MINIMAL_VERSION_STRING = 'HANA 2.0 SPS05 rev 59.04 or later, or SPS06 rev 63 or later'
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+def _report_skip_check():
|
||||||
|
+ summary = (
|
||||||
|
+ 'For the target RHEL releases >=8.8 and >=9.2 '
|
||||||
|
+ 'the leapp utility does not check RHEL and SAP HANA 2.0 '
|
||||||
|
+ 'versions compatibility. Please ensure your SAP HANA 2.0 '
|
||||||
|
+ 'is supported on the target RHEL release and '
|
||||||
|
+ 'proceed on your discretion. '
|
||||||
|
+ 'SAP HANA: Supported Operating Systems '
|
||||||
|
+ 'https://launchpad.support.sap.com/#/notes/2235581')
|
||||||
|
+ remedy_hint = 'Ensure your SAP HANA 2.0 is supported on the target release.'
|
||||||
|
+ reporting.create_report([
|
||||||
|
+ reporting.Title('SAP HANA 2.0 version should be checked prior the upgrade'),
|
||||||
|
+ reporting.Summary(summary),
|
||||||
|
+ reporting.Severity(reporting.Severity.MEDIUM),
|
||||||
|
+ reporting.Groups([reporting.Groups.SANITY]),
|
||||||
|
+ reporting.Remediation(hint=remedy_hint),
|
||||||
|
+ reporting.ExternalLink(url='https://launchpad.support.sap.com/#/notes/2235581',
|
||||||
|
+ title='SAP HANA: Supported Operating Systems'),
|
||||||
|
+ ])
|
||||||
|
|
||||||
|
|
||||||
|
def _manifest_get(manifest, key, default_value=None):
|
||||||
|
@@ -45,7 +61,6 @@ def running_check(info):
|
||||||
|
reporting.Severity(reporting.Severity.HIGH),
|
||||||
|
reporting.Groups([reporting.Groups.SANITY]),
|
||||||
|
reporting.Groups([reporting.Groups.INHIBITOR]),
|
||||||
|
- reporting.Audience('sysadmin')
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
@@ -72,12 +87,10 @@ def _create_detected_instances_list(details):
|
||||||
|
|
||||||
|
|
||||||
|
def _min_ver_string():
|
||||||
|
- if version.get_target_major_version() == '8':
|
||||||
|
+ if version.matches_target_version('8.6'):
|
||||||
|
ver_str = SAP_HANA_RHEL86_MINIMAL_VERSION_STRING
|
||||||
|
- if version.matches_target_version('8.2'):
|
||||||
|
- ver_str = SAP_HANA_RHEL82_MINIMAL_VERSION_STRING
|
||||||
|
else:
|
||||||
|
- ver_str = SAP_HANA_RHEL9_MINIMAL_VERSION_STRING
|
||||||
|
+ ver_str = SAP_HANA_RHEL90_MINIMAL_VERSION_STRING
|
||||||
|
return ver_str
|
||||||
|
|
||||||
|
|
||||||
|
@@ -89,10 +102,9 @@ def version1_check(info):
|
||||||
|
_add_hana_details(found, instance)
|
||||||
|
|
||||||
|
if found:
|
||||||
|
- min_ver_string = _min_ver_string()
|
||||||
|
detected = _create_detected_instances_list(found)
|
||||||
|
reporting.create_report([
|
||||||
|
- reporting.Title('Found SAP HANA 1 which is not supported with the target version of RHEL'),
|
||||||
|
+ reporting.Title('Found SAP HANA 1.0 which is not supported with the target version of RHEL'),
|
||||||
|
reporting.Summary(
|
||||||
|
('SAP HANA 1.00 is not supported with the version of RHEL you are upgrading to.\n\n'
|
||||||
|
'The following instances have been detected to be version 1.00:\n'
|
||||||
|
@@ -101,12 +113,11 @@ def version1_check(info):
|
||||||
|
reporting.Severity(reporting.Severity.HIGH),
|
||||||
|
reporting.RemediationHint((
|
||||||
|
'In order to upgrade RHEL, you will have to upgrade your SAP HANA 1.0 software to '
|
||||||
|
- '{supported}.'.format(supported=min_ver_string))),
|
||||||
|
+ 'SAP HANA 2.0 supported on the target RHEL release first.')),
|
||||||
|
reporting.ExternalLink(url='https://launchpad.support.sap.com/#/notes/2235581',
|
||||||
|
title='SAP HANA: Supported Operating Systems'),
|
||||||
|
reporting.Groups([reporting.Groups.SANITY]),
|
||||||
|
reporting.Groups([reporting.Groups.INHIBITOR]),
|
||||||
|
- reporting.Audience('sysadmin')
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
@@ -160,12 +171,10 @@ def _sp_rev_patchlevel_check(instance, patchlevels):
|
||||||
|
|
||||||
|
def _fullfills_hana_min_version(instance):
|
||||||
|
""" Performs a check whether the version of SAP HANA fulfills the minimal requirements for the target RHEL """
|
||||||
|
- if version.get_target_major_version() == '8':
|
||||||
|
+ if version.matches_target_version('8.6'):
|
||||||
|
patchlevels = SAP_HANA_RHEL86_REQUIRED_PATCH_LEVELS
|
||||||
|
- if version.matches_target_version('8.2'):
|
||||||
|
- patchlevels = SAP_HANA_RHEL82_REQUIRED_PATCH_LEVELS
|
||||||
|
else:
|
||||||
|
- patchlevels = SAP_HANA_RHEL9_REQUIRED_PATCH_LEVELS
|
||||||
|
+ patchlevels = SAP_HANA_RHEL90_REQUIRED_PATCH_LEVELS
|
||||||
|
return _major_version_check(instance) and _sp_rev_patchlevel_check(instance, patchlevels)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -175,6 +184,11 @@ def version2_check(info):
|
||||||
|
for instance in info.instances:
|
||||||
|
if _manifest_get(instance.manifest, 'release', None) == '1.00':
|
||||||
|
continue
|
||||||
|
+ if version.matches_target_version('> 8.6', '< 9.0') or version.matches_target_version('> 9.0'):
|
||||||
|
+ # if a target release is >=8.8 or >=9.2, the SAP HANA and RHEL versions compatibility is not checked
|
||||||
|
+ _report_skip_check()
|
||||||
|
+ return
|
||||||
|
+ # if a starget release is 8.6 or 9.0 we still check SAP HANA and RHEL versions compatibility
|
||||||
|
if not _fullfills_hana_min_version(instance):
|
||||||
|
_add_hana_details(found, instance)
|
||||||
|
|
||||||
|
@@ -196,7 +210,6 @@ def version2_check(info):
|
||||||
|
reporting.Severity(reporting.Severity.HIGH),
|
||||||
|
reporting.Groups([reporting.Groups.SANITY]),
|
||||||
|
reporting.Groups([reporting.Groups.INHIBITOR]),
|
||||||
|
- reporting.Audience('sysadmin')
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/repos/system_upgrade/common/actors/checksaphana/tests/test_checksaphana.py b/repos/system_upgrade/common/actors/checksaphana/tests/test_checksaphana.py
|
||||||
|
index 3dc2c192..1417b00a 100644
|
||||||
|
--- a/repos/system_upgrade/common/actors/checksaphana/tests/test_checksaphana.py
|
||||||
|
+++ b/repos/system_upgrade/common/actors/checksaphana/tests/test_checksaphana.py
|
||||||
|
@@ -166,33 +166,6 @@ class MockSAPHanaVersionInstance(object):
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
-@pytest.mark.parametrize(
|
||||||
|
- 'major,rev,patchlevel,result', (
|
||||||
|
- (2, 52, 0, True),
|
||||||
|
- (2, 52, 1, True),
|
||||||
|
- (2, 52, 2, True),
|
||||||
|
- (2, 53, 0, True),
|
||||||
|
- (2, 60, 0, True),
|
||||||
|
- (2, 48, 2, True),
|
||||||
|
- (2, 48, 1, False),
|
||||||
|
- (2, 48, 0, False),
|
||||||
|
- (2, 38, 2, False),
|
||||||
|
- (2, 49, 0, True),
|
||||||
|
- )
|
||||||
|
-)
|
||||||
|
-def test_checksaphana__fullfills_rhel82_hana_min_version(monkeypatch, major, rev, patchlevel, result):
|
||||||
|
- monkeypatch.setattr(version, 'get_target_major_version', lambda: '8')
|
||||||
|
- monkeypatch.setattr(version, 'get_target_version', lambda: '8.2')
|
||||||
|
- monkeypatch.setattr(checksaphana, 'SAP_HANA_RHEL82_REQUIRED_PATCH_LEVELS', ((4, 48, 2), (5, 52, 0)))
|
||||||
|
- assert checksaphana._fullfills_hana_min_version(
|
||||||
|
- MockSAPHanaVersionInstance(
|
||||||
|
- major=major,
|
||||||
|
- rev=rev,
|
||||||
|
- patchlevel=patchlevel,
|
||||||
|
- )
|
||||||
|
- ) == result
|
||||||
|
-
|
||||||
|
-
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'major,rev,patchlevel,result', (
|
||||||
|
(2, 52, 0, True),
|
||||||
|
@@ -239,10 +212,10 @@ def test_checksaphana__fullfills_rhel86_hana_min_version(monkeypatch, major, rev
|
||||||
|
(2, 64, 0, True),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
-def test_checksaphana__fullfills_hana_rhel9_min_version(monkeypatch, major, rev, patchlevel, result):
|
||||||
|
+def test_checksaphana__fullfills_hana_rhel90_min_version(monkeypatch, major, rev, patchlevel, result):
|
||||||
|
monkeypatch.setattr(version, 'get_target_major_version', lambda: '9')
|
||||||
|
monkeypatch.setattr(version, 'get_target_version', lambda: '9.0')
|
||||||
|
- monkeypatch.setattr(checksaphana, 'SAP_HANA_RHEL9_REQUIRED_PATCH_LEVELS', ((5, 59, 4), (6, 63, 0)))
|
||||||
|
+ monkeypatch.setattr(checksaphana, 'SAP_HANA_RHEL90_REQUIRED_PATCH_LEVELS', ((5, 59, 4), (6, 63, 0)))
|
||||||
|
assert checksaphana._fullfills_hana_min_version(
|
||||||
|
MockSAPHanaVersionInstance(
|
||||||
|
major=major,
|
||||||
|
diff --git a/repos/system_upgrade/common/files/upgrade_paths.json b/repos/system_upgrade/common/files/upgrade_paths.json
|
||||||
|
index 5e3c5d32..5d8b44e9 100644
|
||||||
|
--- a/repos/system_upgrade/common/files/upgrade_paths.json
|
||||||
|
+++ b/repos/system_upgrade/common/files/upgrade_paths.json
|
||||||
|
@@ -7,9 +7,10 @@
|
||||||
|
"8": ["9.2"]
|
||||||
|
},
|
||||||
|
"saphana": {
|
||||||
|
- "7.9": ["8.2", "8.6"],
|
||||||
|
- "7": ["8.2", "8.6"],
|
||||||
|
+ "7.9": ["8.8", "8.6"],
|
||||||
|
+ "7": ["8.8", "8.6"],
|
||||||
|
"8.6": ["9.0"],
|
||||||
|
- "8": ["9.0"]
|
||||||
|
+ "8.8": ["9.2"],
|
||||||
|
+ "8": ["9.2", "9.0"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/repos/system_upgrade/common/libraries/config/version.py b/repos/system_upgrade/common/libraries/config/version.py
|
||||||
|
index cc5bfca5..6bf6b4da 100644
|
||||||
|
--- a/repos/system_upgrade/common/libraries/config/version.py
|
||||||
|
+++ b/repos/system_upgrade/common/libraries/config/version.py
|
||||||
|
@@ -14,7 +14,7 @@ OP_MAP = {
|
||||||
|
_SUPPORTED_VERSIONS = {
|
||||||
|
# Note: 'rhel-alt' is detected when on 'rhel' with kernel 4.x
|
||||||
|
'7': {'rhel': ['7.9'], 'rhel-alt': [], 'rhel-saphana': ['7.9']},
|
||||||
|
- '8': {'rhel': ['8.6', '8.8'], 'rhel-saphana': ['8.6']},
|
||||||
|
+ '8': {'rhel': ['8.6', '8.8'], 'rhel-saphana': ['8.6', '8.8']},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -1,23 +0,0 @@
|
|||||||
From 496abd1775779054377c5e35ae96fa4d390bab42 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Petr Stodulka <pstodulk@redhat.com>
|
|
||||||
Date: Tue, 19 Apr 2022 21:51:03 +0200
|
|
||||||
Subject: [PATCH] Enforce the removal of rubygem-irb (do not install it)
|
|
||||||
|
|
||||||
---
|
|
||||||
etc/leapp/transaction/to_remove | 3 +++
|
|
||||||
1 file changed, 3 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/etc/leapp/transaction/to_remove b/etc/leapp/transaction/to_remove
|
|
||||||
index 0feb782..07c6864 100644
|
|
||||||
--- a/etc/leapp/transaction/to_remove
|
|
||||||
+++ b/etc/leapp/transaction/to_remove
|
|
||||||
@@ -1,3 +1,6 @@
|
|
||||||
### List of packages (each on new line) to be removed from the upgrade transaction
|
|
||||||
# Removing initial-setup package to avoid it asking for EULA acceptance during upgrade - OAMG-1531
|
|
||||||
initial-setup
|
|
||||||
+
|
|
||||||
+# temporary workaround for the file conflict symlink <-> dir (#2030627)
|
|
||||||
+rubygem-irb
|
|
||||||
--
|
|
||||||
2.35.1
|
|
||||||
|
|
7
gating.yaml
Normal file
7
gating.yaml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
--- !Policy
|
||||||
|
product_versions:
|
||||||
|
- rhel-8
|
||||||
|
decision_context: osci_compose_gate
|
||||||
|
rules:
|
||||||
|
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}
|
||||||
|
|
@ -42,7 +42,7 @@ py2_byte_compile "%1" "%2"}
|
|||||||
|
|
||||||
Name: leapp-repository
|
Name: leapp-repository
|
||||||
Version: 0.18.0
|
Version: 0.18.0
|
||||||
Release: 1%{?dist}
|
Release: 2%{?dist}
|
||||||
Summary: Repositories for leapp
|
Summary: Repositories for leapp
|
||||||
|
|
||||||
License: ASL 2.0
|
License: ASL 2.0
|
||||||
@ -55,10 +55,12 @@ BuildArch: noarch
|
|||||||
|
|
||||||
### PATCHES HERE
|
### PATCHES HERE
|
||||||
# Patch0001: filename.patch
|
# Patch0001: filename.patch
|
||||||
|
Patch0001: 0001-Introduce-leapp-data-in-the-RPM-repository.patch
|
||||||
|
Patch0002: 0002-Add-el8toel9-actor-to-handle-directory-symlink.patch
|
||||||
|
Patch0003: 0003-Enable-8-9-upgrades-with-FIPS-enabled-1053.patch
|
||||||
|
Patch0004: 0004-Change-the-upgrade-paths-for-SAP-HANA.patch
|
||||||
|
|
||||||
|
|
||||||
## DO NOT REMOVE THIS PATCH UNLESS THE RUBYGEM-IRB ISSUE IS RESOLVED IN ACTORS!
|
|
||||||
# See: https://bugzilla.redhat.com/show_bug.cgi?id=2030627
|
|
||||||
Patch0004: 0004-Enforce-the-removal-of-rubygem-irb-do-not-install-it.patch
|
|
||||||
|
|
||||||
|
|
||||||
%description
|
%description
|
||||||
@ -201,6 +203,9 @@ Requires: python3-gobject-base
|
|||||||
|
|
||||||
# APPLY PATCHES HERE
|
# APPLY PATCHES HERE
|
||||||
# %%patch0001 -p1
|
# %%patch0001 -p1
|
||||||
|
%patch0001 -p1
|
||||||
|
%patch0002 -p1
|
||||||
|
%patch0003 -p1
|
||||||
%patch0004 -p1
|
%patch0004 -p1
|
||||||
|
|
||||||
|
|
||||||
@ -220,6 +225,7 @@ install -m 0755 -d %{buildroot}%{_sysconfdir}/leapp/repos.d/
|
|||||||
install -m 0755 -d %{buildroot}%{_sysconfdir}/leapp/transaction/
|
install -m 0755 -d %{buildroot}%{_sysconfdir}/leapp/transaction/
|
||||||
install -m 0755 -d %{buildroot}%{_sysconfdir}/leapp/files/
|
install -m 0755 -d %{buildroot}%{_sysconfdir}/leapp/files/
|
||||||
install -m 0644 etc/leapp/transaction/* %{buildroot}%{_sysconfdir}/leapp/transaction
|
install -m 0644 etc/leapp/transaction/* %{buildroot}%{_sysconfdir}/leapp/transaction
|
||||||
|
install -m 0644 etc/leapp/files/* %{buildroot}%{_sysconfdir}/leapp/files
|
||||||
|
|
||||||
# install CLI commands for the leapp utility on the expected path
|
# install CLI commands for the leapp utility on the expected path
|
||||||
install -m 0755 -d %{buildroot}%{leapp_python_sitelib}/leapp/cli/
|
install -m 0755 -d %{buildroot}%{leapp_python_sitelib}/leapp/cli/
|
||||||
@ -267,6 +273,7 @@ done;
|
|||||||
%dir %{repositorydir}
|
%dir %{repositorydir}
|
||||||
%dir %{custom_repositorydir}
|
%dir %{custom_repositorydir}
|
||||||
%dir %{leapp_python_sitelib}/leapp/cli/commands
|
%dir %{leapp_python_sitelib}/leapp/cli/commands
|
||||||
|
%config %{_sysconfdir}/leapp/files/*
|
||||||
%{_sysconfdir}/leapp/repos.d/*
|
%{_sysconfdir}/leapp/repos.d/*
|
||||||
%{_sysconfdir}/leapp/transaction/*
|
%{_sysconfdir}/leapp/transaction/*
|
||||||
%{repositorydir}/*
|
%{repositorydir}/*
|
||||||
@ -277,6 +284,13 @@ done;
|
|||||||
# no files here
|
# no files here
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri May 19 2023 Petr Stodulka <pstodulk@redhat.com> - 0.18.0-2
|
||||||
|
- Include leap data files in the package
|
||||||
|
- Introduce in-place upgrades for systems with enabled FIPS mode
|
||||||
|
- Enable the upgrade path 8.8 -> 9.2 for RHEL with SAP HANA
|
||||||
|
- Fix the upgrade of ruby-irb package
|
||||||
|
- Resolves: rhbz#2030627, rhbz#2097003, rhbz#2203800, rhbz#2203803
|
||||||
|
|
||||||
* Tue Feb 21 2023 Petr Stodulka <pstodulk@redhat.com> - 0.18.0-1
|
* Tue Feb 21 2023 Petr Stodulka <pstodulk@redhat.com> - 0.18.0-1
|
||||||
- Rebase to v0.18.0
|
- Rebase to v0.18.0
|
||||||
- Introduce new upgrade path RHEL 8.8 -> 9.2
|
- Introduce new upgrade path RHEL 8.8 -> 9.2
|
||||||
|
4
plans/tier0.fmf
Normal file
4
plans/tier0.fmf
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
summary: Foo
|
||||||
|
execute:
|
||||||
|
script: leapp --help
|
||||||
|
|
Loading…
Reference in New Issue
Block a user