From 7083418c02739b062ece0aa6903aa3444b21da7e Mon Sep 17 00:00:00 2001 From: Yuriy Kohut Date: Tue, 30 Jun 2026 20:52:54 +0300 Subject: [PATCH] Bump leapp-framework version Bump the package release --- ...-normalize_schemas-for-conflicting-a.patch | 228 ++++++++++++++++++ 0012-Makefile-add-test_no_lint.patch | 28 +++ leapp.spec | 11 +- 3 files changed, 265 insertions(+), 2 deletions(-) create mode 100644 0011-Fix-exception-in-normalize_schemas-for-conflicting-a.patch create mode 100644 0012-Makefile-add-test_no_lint.patch diff --git a/0011-Fix-exception-in-normalize_schemas-for-conflicting-a.patch b/0011-Fix-exception-in-normalize_schemas-for-conflicting-a.patch new file mode 100644 index 0000000..d6f08bd --- /dev/null +++ b/0011-Fix-exception-in-normalize_schemas-for-conflicting-a.patch @@ -0,0 +1,228 @@ +From 66883ef34b1e241838b9812a8920bf6f6fb380e0 Mon Sep 17 00:00:00 2001 +From: Matej Matuska +Date: Wed, 20 May 2026 12:32:48 +0200 +Subject: [PATCH] Fix exception in normalize_schemas for conflicting actor + config schemas + +The normalize_schemas function incorrectly raises an exception when a +config schema (subclass of Config) is contained more than once in it's +input, regardless of whether it's a conflicting (same section and name, +but a difference in other members) or the same (same section and name). +Traceback: + +Traceback (most recent call last): + File "/usr/bin/leapp", line 33, in + sys.exit(load_entry_point('leapp==0.21.0', 'console_scripts', 'leapp')()) + File "/usr/lib/python3.9/site-packages/leapp/cli/__init__.py", line 51, in main + cli.command.execute('leapp version {}'.format(VERSION)) + File "/usr/lib/python3.9/site-packages/leapp/utils/clicmd.py", line 111, in execute + args.func(args) + File "/usr/lib/python3.9/site-packages/leapp/utils/clicmd.py", line 133, in called + self.target(args) + File "/usr/lib/python3.9/site-packages/leapp/cli/commands/upgrade/breadcrumbs.py", line 169, in wrapper + return f(*args, breadcrumbs=breadcrumbs, **kwargs) + File "/usr/lib/python3.9/site-packages/leapp/cli/commands/preupgrade/__init__.py", line 86, in preupgrade + command_utils.load_actor_configs_and_store_it_in_db(context, repositories, cfg) + File "/usr/lib/python3.9/site-packages/leapp/cli/commands/command_utils.py", line 291, in load_actor_configs_and_store_it_in_db + actor_config_schemas = actor_config.normalize_schemas(actor_config_schemas) + File "/usr/lib/python3.9/site-packages/leapp/actors/config.py", line 180, in normalize_schemas + if unique_name in added_fields and added_fields[unique_name] != field: +TypeError: 'set' object is not subscriptable + +The added_fields variable is a set. The condition for checking conflicts +attempts to do indexing on the set, which is not possible in Python sets +and results in a TypeError. + +This patch removes the set altogether since it doesn't bring any +advantage over just using the normalized_schemas dict. + +Also add unit tests for the function. +--- + leapp/actors/config.py | 44 ++++++----- + tests/scripts/test_actor_config.py | 114 +++++++++++++++++++++++++++++ + 2 files changed, 138 insertions(+), 20 deletions(-) + create mode 100644 tests/scripts/test_actor_config.py + +diff --git a/leapp/actors/config.py b/leapp/actors/config.py +index 55775d5..d952bb6 100644 +--- a/leapp/actors/config.py ++++ b/leapp/actors/config.py +@@ -169,31 +169,35 @@ def _get_config(config_dir='/etc/leapp/actor_conf.d'): + def normalize_schemas(schemas): + """ + Merge all schemas into a single dictionary and validate them for errors we can detect. ++ ++ :param schemas: List of schemas to normalize ++ :type schemas: Iterable[Iterable[Type[Config]]] ++ :return A dictionary with structure: section -> name -> Config ++ :rtype: DefaultDict[str, Dict[str, Type[Config]]] + """ +- added_fields = set() + normalized_schema = defaultdict(dict) + for schema in schemas: + for field in schema: +- unique_name = (field.section, field.name) +- ++ # section and name are the unique key for a config ++ existing_field = normalized_schema[field.section].get(field.name, None) + # Error if the field has been added by another schema +- if unique_name in added_fields and added_fields[unique_name] != field: +- # TODO: Also include information on what Actor contains the +- # conflicting fields but that information isn't passed into +- # this function right now. +- message = ('Two actors added incompatible configuration items' +- ' with the same name for Section: {section},' +- ' Field: {field}'.format(section=field.section, +- field=field.name)) +- log.error(message) +- raise SchemaError(message) +- +- # TODO: More validation here. +- +- # Store the fields from the schema in a way that we can easily look +- # up while validating +- added_fields.add(unique_name) +- normalized_schema[field.section][field.name] = field ++ if existing_field: ++ if existing_field != field: ++ # TODO: Also include information on what Actor contains the ++ # conflicting fields but that information isn't passed into ++ # this function right now. ++ message = ( ++ 'Two actors added incompatible configuration items with' ++ ' the same name for Section: {section}, Field: {field}' ++ ).format(section=field.section, field=field.name) ++ ++ log.error(message) ++ raise SchemaError(message) ++ ++ # TODO: More validation here. ++ ++ else: ++ normalized_schema[field.section][field.name] = field + + return normalized_schema + +diff --git a/tests/scripts/test_actor_config.py b/tests/scripts/test_actor_config.py +new file mode 100644 +index 0000000..b8c02cd +--- /dev/null ++++ b/tests/scripts/test_actor_config.py +@@ -0,0 +1,114 @@ ++from collections import defaultdict ++import pytest ++ ++from leapp.actors.config import Config, SchemaError, normalize_schemas ++from leapp.models import fields ++ ++ ++class _TestConfigA(Config): ++ section = "test" ++ name = "a_setting" ++ type_ = fields.String() ++ description = 'Description here' ++ default = "default value" ++ ++ ++class _TestConfigB(Config): ++ section = "other_section" ++ name = "other_setting" ++ type_ = fields.String() ++ description = 'Description here' ++ default = "some default value" ++ ++ ++# conflicts in default ++class _TestConfigConflictsInDefault(Config): ++ section = "test" ++ name = "a_setting" ++ type_ = fields.String() ++ description = 'Description here' ++ default = "different than in A" ++ ++ ++# conflicts in type_ ++class _TestConfigConflictsInType(Config): ++ section = "test" ++ name = "a_setting" ++ type_ = fields.Integer() ++ description = 'Description here' ++ default = "default value" ++ ++ ++@pytest.mark.parametrize( ++ "schemas", ++ [ ++ # test configs from single actors are merged ++ [(_TestConfigA, _TestConfigB)], ++ # test configs from multiple actors are merged ++ [(_TestConfigA,), (_TestConfigB,)], ++ # test "deduplication" ++ [(_TestConfigA, _TestConfigA, _TestConfigB)], ++ [(_TestConfigA,), (_TestConfigA, _TestConfigB,)] ++ ], ++) ++def test_normalize_schemas_ok(schemas): ++ """ ++ Test that valid schemas are detected and if required deduplicated ++ """ ++ expect = defaultdict(dict) ++ expect["test"] = {"a_setting": _TestConfigA} ++ expect["other_section"] = {"other_setting": _TestConfigB} ++ ret = normalize_schemas(schemas) ++ assert ret == expect ++ ++ ++def test_normalize_schemas_identical(): ++ """ ++ Test that identical Config class objects are deduplicated ++ """ ++ expect = defaultdict(dict) ++ expect["test"] = {"a_setting": _TestConfigA} ++ ++ config = _TestConfigA ++ ++ schemas = [(config, config)] ++ ret = normalize_schemas(schemas) ++ assert ret == expect ++ ++ schemas = [(config,), (config,)] ++ ret = normalize_schemas(schemas) ++ assert ret == expect ++ ++ ++@pytest.mark.parametrize( ++ "schemas", ++ [ ++ [(_TestConfigA, _TestConfigConflictsInDefault)], ++ [(_TestConfigA, _TestConfigConflictsInType)], ++ ] ++) ++def test_normalize_schemas_intra_conflict(schemas): ++ """ ++ Test that conflicts within a single Actor config schema are detected ++ """ ++ with pytest.raises(SchemaError): ++ normalize_schemas(schemas) ++ ++ ++@pytest.mark.parametrize( ++ "schemas", ++ [ ++ [(_TestConfigA,), (_TestConfigConflictsInDefault,)], ++ [(_TestConfigA,), (_TestConfigConflictsInType,)], ++ ] ++) ++def test_normalize_schemas_inter_conflict(schemas): ++ """ ++ Test that conflicts between multiple Actor config schemas are detected ++ """ ++ with pytest.raises(SchemaError): ++ normalize_schemas(schemas) ++ ++ ++def test_normalize_schemas_empty(): ++ assert normalize_schemas([]) == defaultdict(dict) +-- +2.54.0 + diff --git a/0012-Makefile-add-test_no_lint.patch b/0012-Makefile-add-test_no_lint.patch new file mode 100644 index 0000000..1ec1032 --- /dev/null +++ b/0012-Makefile-add-test_no_lint.patch @@ -0,0 +1,28 @@ +From 0a5b9b7bb44fbe71c97b10673be71e343abcf58c Mon Sep 17 00:00:00 2001 +From: Matej Matuska +Date: Wed, 20 May 2026 12:45:21 +0200 +Subject: [PATCH] Makefile: add test_no_lint + +The test rules always lints, add a variant which just tests. +--- + Makefile | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/Makefile b/Makefile +index a68b8fe..dd2d8b9 100644 +--- a/Makefile ++++ b/Makefile +@@ -202,6 +202,10 @@ test: lint + @ $(ENTER_VENV) \ + pytest -vv --cov-report term-missing --cov=leapp tests/scripts + ++test_no_lint: ++ @ $(ENTER_VENV) \ ++ pytest -vv --cov-report term-missing --cov=leapp tests/scripts ++ + # TODO(pstodulk): create ticket to add rhel10 for testing.... py: 3.12 + test_container: + @case $(_TEST_CONTAINER) in \ +-- +2.54.0 + diff --git a/leapp.spec b/leapp.spec index 0595b0e..d00a3f7 100644 --- a/leapp.spec +++ b/leapp.spec @@ -7,7 +7,7 @@ # it. In case of upstream, dependencies are set differently, but YUM is not # capable enough to deal with them correctly all the time; we continue to use # simplified deps in RHEL to ensure that YUM can deal with it. -%global framework_version 6.5 +%global framework_version 6.6 # IMPORTANT: everytime the requirements are changed, increment number by one # - same for Provides in deps subpackage @@ -37,7 +37,7 @@ Name: leapp Version: 0.21.0 -Release: 2%{?dist} +Release: 2%{?dist}.elevate.1 Summary: OS & Application modernization framework License: ASL 2.0 @@ -75,6 +75,8 @@ Patch0007: 0007-reporting-fix-incorrect-converting-of-list-based-com.patch Patch0008: 0008-fixup-reporting-fix-incorrect-converting-of-list-bas.patch Patch0009: 0009-python-test-deps-update-pytest-requirements.patch Patch0010: 0010-fix-reporting-use-single-quoting-when-converting-rem.patch +Patch0011: 0011-Fix-exception-in-normalize_schemas-for-conflicting-a.patch +Patch0012: 0012-Makefile-add-test_no_lint.patch %description @@ -182,6 +184,8 @@ Requires: findutils %patch -P 0008 -p1 %patch -P 0009 -p1 %patch -P 0010 -p1 +%patch -P 0011 -p1 +%patch -P 0012 -p1 ################################################## # Build ################################################## @@ -265,6 +269,9 @@ install -m 0644 -p man/leapp.1 %{buildroot}%{_mandir}/man1/ # no files here %changelog +* Tue Jun 30 2026 Yuriy Kohut - 0.21.0-1.elevate.1 +- Bump leapp-framework to 6.6 + * Fri Apr 17 2026 Matej Matuska - 0.21.0-1 - Bump leapp-framework to 6.5 - Change how commands are converted for text based report from the list representation