From 849a8f2fcd04ee6d419b3856562fbff5b85577f5 Mon Sep 17 00:00:00 2001 From: Michal Hecko Date: Thu, 6 Mar 2025 11:33:05 +0100 Subject: [PATCH 06/37] livemode(cfg): use framework's configurability instead of ad-hoc INI Drop the ad-hoc INI-based config for livemode in favour and replace it with configuration facilitated by the leapp framework. The list of configuration options remains (and their semantics) remains almost unchanged, save for some field names that are renamed in a way that better reveals their effect to the user. Jira-ref: RHELMISC-10648 --- commands/upgrade/util.py | 1 - etc/leapp/files/devel-livemode.ini | 9 -- .../livemode/livemode_config_scanner/actor.py | 2 + .../libraries/scan_livemode_config.py | 101 +++++------------- .../tests/test_config_scanner.py | 40 +++---- 5 files changed, 44 insertions(+), 109 deletions(-) delete mode 100644 etc/leapp/files/devel-livemode.ini diff --git a/commands/upgrade/util.py b/commands/upgrade/util.py index bfdbc4fa..6cdfa6d8 100644 --- a/commands/upgrade/util.py +++ b/commands/upgrade/util.py @@ -16,7 +16,6 @@ from leapp.utils.audit import get_checkpoints, get_connection, get_messages from leapp.utils.output import report_unsupported from leapp.utils.report import fetch_upgrade_report_messages, generate_report_file - EXPERIMENTAL_FEATURES = { 'livemode': [ 'live_image_generator', diff --git a/etc/leapp/files/devel-livemode.ini b/etc/leapp/files/devel-livemode.ini deleted file mode 100644 index b79ed4df..00000000 --- a/etc/leapp/files/devel-livemode.ini +++ /dev/null @@ -1,9 +0,0 @@ -# Configuration for the *experimental* livemode feature -# It is likely that this entire configuration file will be replaced by some -# other mechanism/file in the future. For the full list of configuration options, -# see models/livemode.py -[livemode] -squashfs_fullpath=/var/lib/leapp/live-upgrade.img -setup_network_manager=no -autostart_upgrade_after_reboot=yes -setup_passwordless_root=no diff --git a/repos/system_upgrade/common/actors/livemode/livemode_config_scanner/actor.py b/repos/system_upgrade/common/actors/livemode/livemode_config_scanner/actor.py index dc79ecff..bd909736 100644 --- a/repos/system_upgrade/common/actors/livemode/livemode_config_scanner/actor.py +++ b/repos/system_upgrade/common/actors/livemode/livemode_config_scanner/actor.py @@ -1,4 +1,5 @@ from leapp.actors import Actor +from leapp.configs.actor import livemode as livemode_config_lib from leapp.libraries.actor import scan_livemode_config as scan_livemode_config_lib from leapp.models import InstalledRPM, LiveModeConfig from leapp.tags import ExperimentalTag, FactsPhaseTag, IPUWorkflowTag @@ -10,6 +11,7 @@ class LiveModeConfigScanner(Actor): """ name = 'live_mode_config_scanner' + config_schemas = livemode_config_lib.livemode_cfg_fields consumes = (InstalledRPM,) produces = (LiveModeConfig,) tags = (ExperimentalTag, FactsPhaseTag, IPUWorkflowTag,) diff --git a/repos/system_upgrade/common/actors/livemode/livemode_config_scanner/libraries/scan_livemode_config.py b/repos/system_upgrade/common/actors/livemode/livemode_config_scanner/libraries/scan_livemode_config.py index b2f0af7f..57408c23 100644 --- a/repos/system_upgrade/common/actors/livemode/livemode_config_scanner/libraries/scan_livemode_config.py +++ b/repos/system_upgrade/common/actors/livemode/livemode_config_scanner/libraries/scan_livemode_config.py @@ -1,14 +1,9 @@ -try: - import configparser -except ImportError: - import ConfigParser as configparser - +from leapp.configs.actor import livemode as livemode_config_lib from leapp.exceptions import StopActorExecutionError from leapp.libraries.common.config import architecture, get_env from leapp.libraries.common.rpms import has_package from leapp.libraries.stdlib import api from leapp.models import InstalledRPM, LiveModeConfig -from leapp.models.fields import ModelViolationError LIVEMODE_CONFIG_LOCATION = '/etc/leapp/files/devel-livemode.ini' DEFAULT_SQUASHFS_PATH = '/var/lib/leapp/live-upgrade.img' @@ -50,76 +45,32 @@ def scan_config_and_emit_message(): return api.current_logger().info('Loading livemode config from %s', LIVEMODE_CONFIG_LOCATION) - parser = configparser.ConfigParser() - try: - parser.read((LIVEMODE_CONFIG_LOCATION, )) - except configparser.ParsingError as error: - api.current_logger().error('Failed to parse live mode configuration due to the following error: %s', error) + config = api.current_actor().config[livemode_config_lib.LIVEMODE_CONFIG_SECTION] + + # Mapping from model field names to configuration fields - because we might have + # changed some configuration field names for configuration to be more + # comprehensible for our users. + model_fields_to_config_options_map = { + 'url_to_load_squashfs_from': livemode_config_lib.URLToLoadSquashfsImageFrom, + 'squashfs_fullpath': livemode_config_lib.SquashfsImagePath, + 'dracut_network': livemode_config_lib.DracutNetwork, + 'setup_network_manager': livemode_config_lib.SetupNetworkManager, + 'additional_packages': livemode_config_lib.AdditionalPackages, + 'autostart_upgrade_after_reboot': livemode_config_lib.AutostartUpgradeAfterReboot, + 'setup_opensshd_with_auth_keys': livemode_config_lib.SetupOpenSSHDUsingAuthKeys, + 'setup_passwordless_root': livemode_config_lib.SetupPasswordlessRoot, + 'capture_upgrade_strace_into': livemode_config_lib.CaptureSTraceInfoInto + } - details = 'Failed to read livemode configuration due to the following error: {0}.' - raise StopActorExecutionError( - 'Failed to read livemode configuration', - details={'Problem': details.format(error)} - ) + # Read values of model fields from user-supplied configuration according to the above mapping + config_msg_init_kwargs = {} + for model_field_name, config_field in model_fields_to_config_options_map.items(): + config_msg_init_kwargs[model_field_name] = config[config_field.name] - livemode_section = 'livemode' - if not parser.has_section(livemode_section): - details = 'The configuration is missing the \'[{0}]\' section'.format(livemode_section) - raise StopActorExecutionError( - 'Live mode configuration does not have the required structure', - details={'Problem': details} - ) - - config_kwargs = { - 'is_enabled': True, - 'url_to_load_squashfs_from': None, - 'squashfs_fullpath': DEFAULT_SQUASHFS_PATH, - 'dracut_network': None, - 'setup_network_manager': False, - 'additional_packages': [], - 'autostart_upgrade_after_reboot': True, - 'setup_opensshd_with_auth_keys': None, - 'setup_passwordless_root': False, - 'capture_upgrade_strace_into': None - } + # Some fields of the LiveModeConfig are historical and can no longer be changed by the user + # in the config. Therefore, we just hard-code them here. + config_msg_init_kwargs['is_enabled'] = True - config_str_options = ( - 'url_to_load_squashfs_from', - 'squashfs_fullpath', - 'dracut_network', - 'setup_opensshd_with_auth_keys', - 'capture_upgrade_strace_into' - ) - - config_list_options = ( - 'additional_packages', - ) - - config_bool_options = ( - 'setup_network_manager', - 'setup_passwordless_root', - 'autostart_upgrade_after_reboot', - ) - - for config_option in config_str_options: - if parser.has_option(livemode_section, config_option): - config_kwargs[config_option] = parser.get(livemode_section, config_option) - - for config_option in config_bool_options: - if parser.has_option(livemode_section, config_option): - config_kwargs[config_option] = parser.getboolean(livemode_section, config_option) - - for config_option in config_list_options: - if parser.has_option(livemode_section, config_option): - option_val = parser.get(livemode_section, config_option) - option_list = (opt_val.strip() for opt_val in option_val.split(',')) - option_list = [opt for opt in option_list if opt] - config_kwargs[config_option] = option_list - - try: - config = LiveModeConfig(**config_kwargs) - except ModelViolationError as error: - raise StopActorExecutionError('Failed to parse livemode configuration.', details={'Problem': str(error)}) - - api.produce(config) + config_msg = LiveModeConfig(**config_msg_init_kwargs) + api.produce(config_msg) diff --git a/repos/system_upgrade/common/actors/livemode/livemode_config_scanner/tests/test_config_scanner.py b/repos/system_upgrade/common/actors/livemode/livemode_config_scanner/tests/test_config_scanner.py index 016f6c04..8ddde22e 100644 --- a/repos/system_upgrade/common/actors/livemode/livemode_config_scanner/tests/test_config_scanner.py +++ b/repos/system_upgrade/common/actors/livemode/livemode_config_scanner/tests/test_config_scanner.py @@ -86,29 +86,21 @@ def test_enablement_conditions(monkeypatch, case_descr): def test_config_scanning(monkeypatch): """ Test whether scanning a valid config is properly transcribed into a config message. """ - config_lines = [ - '[livemode]', - 'squashfs_fullpath=IMG', - 'setup_network_manager=yes', - 'autostart_upgrade_after_reboot=no', - 'setup_opensshd_with_auth_keys=/root/.ssh/authorized_keys', - 'setup_passwordless_root=no', - 'additional_packages=pkgA,pkgB' - ] - config_content = '\n'.join(config_lines) + '\n' - - if sys.version[0] == '2': - config_content = config_content.decode('utf-8') # python2 compat - - class ConfigParserMock(configparser.ConfigParser): # pylint: disable=too-many-ancestors - def read(self, file_paths, *args, **kwargs): - self.read_string(config_content) - return file_paths - - monkeypatch.setattr(configparser, 'ConfigParser', ConfigParserMock) - + config = { + 'livemode': { + 'squashfs_image_path': '/var/lib/leapp/live-upgrade2.img', + 'additional_packages': ['petri-nets'], + 'autostart_upgrade_after_reboot': True, + 'setup_network_manager': True, + 'setup_passwordless_root': True, + 'dracut_network': '', + 'url_to_load_squashfs_image_from': '', + 'setup_opensshd_using_auth_keys': '/root/.ssh/authorized_keys', + 'capture_strace_info_into': '' + } + } + monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(config=config)) monkeypatch.setattr(scan_livemode_config_lib, 'should_scan_config', lambda: True) - monkeypatch.setattr(api, 'produce', produce_mocked()) scan_livemode_config_lib.scan_config_and_emit_message() @@ -119,7 +111,7 @@ def test_config_scanning(monkeypatch): produced_message = api.produce.model_instances[0] assert isinstance(produced_message, LiveModeConfig) - assert produced_message.additional_packages == ['pkgA', 'pkgB'] - assert produced_message.squashfs_fullpath == 'IMG' + assert produced_message.additional_packages == ['petri-nets'] + assert produced_message.squashfs_fullpath == '/var/lib/leapp/live-upgrade2.img' assert produced_message.setup_opensshd_with_auth_keys == '/root/.ssh/authorized_keys' assert produced_message.setup_network_manager -- 2.49.0