-
Notifications
You must be signed in to change notification settings - Fork 150
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Verify supported target OS version in actors
Originally when user specified the target system release using `--target` CLI option the verification has been performed immediately as only supported releases have been listed as possible choices for this option. The benefit of this solution was that users did not have to wait for all other checks to realize they execute leapp probably incorrectly. Unfortunately, * number of users do not understand why only some versions are supported * users upgrading with via various webUIs presenting only leapp reports could not see the error message available in terminal To resolve this problem the checks are moved into actors so in case of specified unsupported target version the information is present in generated leapp reports. Current behaviour is like this: * in case of invalid input (incorrect format of input data) the hard error is raised as before immediately. Malformed input data will not be processed anyhow by any actors * report error when the specified target major version is not direct successor of the current system version. I.e. specify 10.0 when upgrading from RHEL 8 (only RHEL 9 is acceptable). * this prevents number of cryptic errors as actors are not prepared for this situation * report standard inhibitor if the target release is not in the defined upgrade path, unless LEAPP_UNSUPPORTED=1 * running leapp in unsupported (devel) mode skips the inhibitor and entire report Additional changes: * Update error message when format of target version is incorrect to clarify the expected version format jira: RHEL-51072 Co-authored-by: Petr Stodulk <[email protected]>
- Loading branch information
Showing
7 changed files
with
229 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
repos/system_upgrade/common/actors/checktargetversion/actor.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
from leapp.actors import Actor | ||
from leapp.libraries.actor import checktargetversion | ||
from leapp.models import IPUPaths | ||
from leapp.reporting import Report | ||
from leapp.tags import ChecksPhaseTag, IPUWorkflowTag | ||
|
||
|
||
class CheckTargetVersion(Actor): | ||
""" | ||
Check that the target system version is supported by the upgrade process. | ||
Invoke inhibitor if the target system is not supported. | ||
Allow unsupported target if `LEAPP_UNSUPPORTED=1` is set. | ||
""" | ||
|
||
name = 'check_target_version' | ||
consumes = (IPUPaths,) | ||
produces = (Report,) | ||
tags = (ChecksPhaseTag, IPUWorkflowTag) | ||
|
||
def process(self): | ||
checktargetversion.process() |
86 changes: 86 additions & 0 deletions
86
repos/system_upgrade/common/actors/checktargetversion/libraries/checktargetversion.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
from leapp import reporting | ||
from leapp.exceptions import StopActorExecutionError | ||
from leapp.libraries.common.config import get_env, version | ||
from leapp.libraries.stdlib import api | ||
from leapp.models import IPUPaths | ||
from leapp.utils.deprecation import suppress_deprecation | ||
|
||
FMT_LIST_SEPARATOR = '\n - ' | ||
|
||
|
||
@suppress_deprecation(IPUPaths) | ||
def get_supported_target_versions(): | ||
ipu_paths = next(api.consume(IPUPaths), None) | ||
src_version = version.get_source_version() | ||
if not ipu_paths: | ||
# NOTE: missing unit-tests. Unexpected situation and the solution | ||
# is possibly temporary | ||
raise StopActorExecutionError('Missing the IPUPaths message. Cannot determine defined upgrade paths.') | ||
for ipu_path in ipu_paths.data: | ||
if ipu_path.source_version == src_version: | ||
return ipu_path.target_versions | ||
|
||
# Nothing discovered. Current src_version is not already supported or not yet. | ||
# Problem of supported source versions is handled now separately in other | ||
# actors. Fallbak from X.Y versioning to major version only. | ||
api.current_logger().warning( | ||
'Cannot discover support upgrade path for this system release: {}' | ||
.format(src_version) | ||
) | ||
maj_version = version.get_source_major_version() | ||
for ipu_path in ipu_paths.data: | ||
if ipu_path.source_version == maj_version: | ||
return ipu_path.target_versions | ||
|
||
# Completely unknown | ||
api.current_logger().warning( | ||
'Cannot discover supported upgrade path for this system major version: {}' | ||
.format(maj_version) | ||
) | ||
return [] | ||
|
||
|
||
def process(): | ||
target_version = version.get_target_version() | ||
supported_target_versions = get_supported_target_versions() | ||
|
||
if target_version in supported_target_versions: | ||
api.current_logger().info('Target version is supported. Continue.') | ||
return | ||
|
||
if get_env('LEAPP_UNSUPPORTED', '0') == '1': | ||
api.current_logger().warning( | ||
'Upgrading to an unsupported version of the target system but LEAPP_UNSUPPORTED=1. Continue.' | ||
) | ||
return | ||
|
||
# inhibit the upgrade - unsupported target and leapp running in production mode | ||
hint = ( | ||
'Choose a supported version of the target OS for the upgrade.' | ||
' Alternatively, if you require to upgrade using an unsupported upgrade path,' | ||
' set the `LEAPP_UNSUPPORTED=1` environment variable to confirm you' | ||
' want to upgrade on your own risk.' | ||
) | ||
|
||
reporting.create_report([ | ||
reporting.Title('Specified version of the target system is not supported'), | ||
reporting.Summary( | ||
'The in-place upgrade to the specified version ({tgt_ver}) of the target system' | ||
' is not supported from the current system version. Follow the official' | ||
' documentation for up to date information about supported upgrade' | ||
' paths and future plans (see the attached link).' | ||
' The in-place upgrade is enabled to the following versions of the target system:{sep}{ver_list}' | ||
.format( | ||
sep=FMT_LIST_SEPARATOR, | ||
ver_list=FMT_LIST_SEPARATOR.join(supported_target_versions), | ||
tgt_ver=target_version | ||
) | ||
), | ||
reporting.Groups([reporting.Groups.INHIBITOR]), | ||
reporting.Severity(reporting.Severity.HIGH), | ||
reporting.Remediation(hint=hint), | ||
reporting.ExternalLink( | ||
url='https://access.redhat.com/articles/4263361', | ||
title='Supported in-place upgrade paths for Red Hat Enterprise Linux' | ||
) | ||
]) |
90 changes: 90 additions & 0 deletions
90
repos/system_upgrade/common/actors/checktargetversion/tests/test_checktargetversion.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import os | ||
|
||
import pytest | ||
|
||
from leapp import reporting | ||
from leapp.libraries.actor import checktargetversion | ||
from leapp.libraries.common.testutils import create_report_mocked, CurrentActorMocked, logger_mocked | ||
from leapp.libraries.stdlib import api | ||
from leapp.models import IPUPath, IPUPaths | ||
from leapp.utils.deprecation import suppress_deprecation | ||
from leapp.utils.report import is_inhibitor | ||
|
||
|
||
# It must be in a function so we can suppress the deprecation warning in tests. | ||
@suppress_deprecation(IPUPaths) | ||
def _get_upgrade_paths_data(): | ||
return IPUPaths(data=[ | ||
IPUPath(source_version='7.9', target_versions=['8.10']), | ||
IPUPath(source_version='8.10', target_versions=['9.4', '9.5', '9.6']), | ||
IPUPath(source_version='9.6', target_versions=['10.0']), | ||
IPUPath(source_version='7', target_versions=['8.10']), | ||
IPUPath(source_version='8', target_versions=['9.4', '9.5', '9.6']), | ||
IPUPath(source_version='9', target_versions=['10.0']) | ||
]) | ||
|
||
|
||
@pytest.fixture | ||
def setup_monkeypatch(monkeypatch): | ||
"""Fixture to set up common monkeypatches.""" | ||
|
||
def _setup(source_version, target_version, leapp_unsupported='0'): | ||
curr_actor_mocked = CurrentActorMocked( | ||
src_ver=source_version, | ||
dst_ver=target_version, | ||
envars={'LEAPP_UNSUPPORTED': leapp_unsupported}, | ||
msgs=[_get_upgrade_paths_data()] | ||
) | ||
monkeypatch.setattr(api, 'current_actor', curr_actor_mocked) | ||
monkeypatch.setattr(api, 'current_logger', logger_mocked()) | ||
monkeypatch.setattr(reporting, 'create_report', create_report_mocked()) | ||
return _setup | ||
|
||
|
||
@pytest.mark.parametrize(('source_version', 'target_version', 'leapp_unsupported'), [ | ||
# LEAPP_UNSUPPORTED=0 | ||
('7.9', '9.0', '0'), | ||
('8.10', '9.0', '0'), | ||
('9.6', '10.1', '0'), | ||
('7', '9.0', '0'), | ||
('8', '9.0', '0'), | ||
('9', '10.1', '0'), | ||
# LEAPP_UNSUPPORTED=1 | ||
('7.9', '9.0', '1'), | ||
('8.10', '9.0', '1'), | ||
('9.6', '10.1', '1'), | ||
('7', '9.0', '1'), | ||
('8', '9.0', '1'), | ||
('9', '10.1', '1'), | ||
]) | ||
def test_unsuppoted_paths(setup_monkeypatch, source_version, target_version, leapp_unsupported): | ||
setup_monkeypatch(source_version, target_version, leapp_unsupported) | ||
|
||
if leapp_unsupported == '1': | ||
checktargetversion.process() | ||
assert reporting.create_report.called == 0 | ||
assert api.current_logger.warnmsg | ||
else: | ||
checktargetversion.process() | ||
assert reporting.create_report.called == 1 | ||
assert is_inhibitor(reporting.create_report.report_fields) | ||
|
||
|
||
@pytest.mark.parametrize(('source_version', 'target_version'), [ | ||
('7.9', '8.10'), | ||
('8.10', '9.4'), | ||
('8.10', '9.5'), | ||
('8.10', '9.6'), | ||
('9.6', '10.0'), | ||
('7', '8.10'), | ||
('8', '9.4'), | ||
('8', '9.5'), | ||
('8', '9.6'), | ||
('9', '10.0'), | ||
]) | ||
def test_supported_paths(setup_monkeypatch, source_version, target_version): | ||
setup_monkeypatch(source_version, target_version, leapp_unsupported='0') | ||
|
||
checktargetversion.process() | ||
assert reporting.create_report.called == 0 | ||
assert api.current_logger.infomsg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters