From 14fa763399093075c0c8239658cd59af0c045e69 Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Tue, 23 Jan 2024 08:40:49 -0800 Subject: [PATCH] RHEL 8.10: CTC2 candidate -2 - Print nice error msg when device and driver deprecation data is malformed - Fix another cornercase when preserving symlinks to certificates in /etc/pki - Update the leapp upgrade data files - fixing upgrades with idm-tomcatjss - Resolves: RHEL-16729 --- ...her-cornercase-with-symlink-handling.patch | 283 +++++++ ...precation-data-print-nice-error-msg-.patch | 129 ++++ 0069-Update-PES-data-CTC2-2.patch | 695 ++++++++++++++++++ leapp-repository.spec | 16 +- 4 files changed, 1121 insertions(+), 2 deletions(-) create mode 100644 0067-Fix-another-cornercase-with-symlink-handling.patch create mode 100644 0068-device-driver-deprecation-data-print-nice-error-msg-.patch create mode 100644 0069-Update-PES-data-CTC2-2.patch diff --git a/0067-Fix-another-cornercase-with-symlink-handling.patch b/0067-Fix-another-cornercase-with-symlink-handling.patch new file mode 100644 index 0000000..132bae4 --- /dev/null +++ b/0067-Fix-another-cornercase-with-symlink-handling.patch @@ -0,0 +1,283 @@ +From bec6615a9c6fda68153d4d1d76930438a233ae83 Mon Sep 17 00:00:00 2001 +From: Toshio Kuratomi +Date: Fri, 19 Jan 2024 11:42:15 -0800 +Subject: [PATCH 67/69] Fix another cornercase with symlink handling + +* Symlinks to a directory inside of /etc/pki were being created as empty directories. +* Note: unittests being added for both this problem and a second problem: + two links to the same external file will be copied as two separate files but ideally we want one + to be a copy and the other to link to the copy. The unittests for the second problem are + commented out. + +Fixes: https://issues.redhat.com/browse/RHEL-3284 +--- + .../libraries/userspacegen.py | 66 ++++++--- + .../tests/unit_test_targetuserspacecreator.py | 128 ++++++++++++++++++ + 2 files changed, 173 insertions(+), 21 deletions(-) + +diff --git a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py +index 8d804407..d917bfd5 100644 +--- a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py ++++ b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py +@@ -350,7 +350,7 @@ def _mkdir_with_copied_mode(path, mode_from): + + def _choose_copy_or_link(symlink, srcdir): + """ +- Copy file contents or create a symlink depending on where the pointee resides. ++ Determine whether to copy file contents or create a symlink depending on where the pointee resides. + + :param symlink: The source symlink to follow. This must be an absolute path. + :param srcdir: The root directory that every piece of content must be present in. +@@ -415,7 +415,7 @@ def _choose_copy_or_link(symlink, srcdir): + # To make comparisons, we need to resolve all symlinks in the directory + # structure leading up to pointee. However, we can't include pointee + # itself otherwise it will resolve to the file that it points to in the +- # end. ++ # end (which would be wrong if pointee_filename is a symlink). + canonical_pointee_dir, pointee_filename = os.path.split(pointee_as_abspath) + canonical_pointee_dir = os.path.realpath(canonical_pointee_dir) + +@@ -454,6 +454,35 @@ def _choose_copy_or_link(symlink, srcdir): + return ('copy', pointee_as_abspath) + + ++def _copy_symlinks(symlinks_to_process, srcdir): ++ """ ++ Copy file contents or create a symlink depending on where the pointee resides. ++ ++ :param symlinks_to_process: List of 2-tuples of (src_path, target_path). Each src_path ++ should be an absolute path to the symlink. target_path is the path to where we ++ need to create either a link or a copy. ++ :param srcdir: The root directory that every piece of content must be present in. ++ :raises ValueError: if the arguments are not correct ++ """ ++ for source_linkpath, target_linkpath in symlinks_to_process: ++ try: ++ action, source_path = _choose_copy_or_link(source_linkpath, srcdir) ++ except BrokenSymlinkError as e: ++ # Skip and report broken symlinks ++ api.current_logger().warning('{} Will not copy the file!'.format(str(e))) ++ continue ++ ++ if action == "copy": ++ # Note: source_path could be a directory, so '-a' or '-r' must be ++ # given to cp. ++ run(['cp', '-a', source_path, target_linkpath]) ++ elif action == 'link': ++ run(["ln", "-s", source_path, target_linkpath]) ++ else: ++ # This will not happen unless _copy_or_link() has a bug. ++ raise RuntimeError("Programming error: _copy_or_link() returned an unknown action:{}".format(action)) ++ ++ + def _copy_decouple(srcdir, dstdir): + """ + Copy files inside of `srcdir` to `dstdir` while decoupling symlinks. +@@ -467,7 +496,6 @@ def _copy_decouple(srcdir, dstdir): + .. warning:: + `dstdir` must already exist. + """ +- symlinks_to_process = [] + for root, directories, files in os.walk(srcdir): + # relative path from srcdir because srcdir is replaced with dstdir for + # the copy. +@@ -476,11 +504,24 @@ def _copy_decouple(srcdir, dstdir): + # Create all directories with proper permissions for security + # reasons (Putting private data into directories that haven't had their + # permissions set appropriately may leak the private information.) ++ symlinks_to_process = [] + for directory in directories: + source_dirpath = os.path.join(root, directory) + target_dirpath = os.path.join(dstdir, relpath, directory) ++ ++ # Defer symlinks until later because we may end up having to copy ++ # the file contents and the directory may not exist yet. ++ if os.path.islink(source_dirpath): ++ symlinks_to_process.append((source_dirpath, target_dirpath)) ++ continue ++ + _mkdir_with_copied_mode(target_dirpath, source_dirpath) + ++ # Link or create all directories that were pointed to by symlinks and ++ # then reset symlinks_to_process for use by files. ++ _copy_symlinks(symlinks_to_process, srcdir) ++ symlinks_to_process = [] ++ + for filename in files: + source_filepath = os.path.join(root, filename) + target_filepath = os.path.join(dstdir, relpath, filename) +@@ -494,24 +535,7 @@ def _copy_decouple(srcdir, dstdir): + # Not a symlink so we can copy it now too + run(['cp', '-a', source_filepath, target_filepath]) + +- # Now process all symlinks +- for source_linkpath, target_linkpath in symlinks_to_process: +- try: +- action, source_path = _choose_copy_or_link(source_linkpath, srcdir) +- except BrokenSymlinkError as e: +- # Skip and report broken symlinks +- api.current_logger().warning('{} Will not copy the file!'.format(str(e))) +- continue +- +- if action == "copy": +- # Note: source_path could be a directory, so '-a' or '-r' must be +- # given to cp. +- run(['cp', '-a', source_path, target_linkpath]) +- elif action == 'link': +- run(["ln", "-s", source_path, target_linkpath]) +- else: +- # This will not happen unless _copy_or_link() has a bug. +- raise RuntimeError("Programming error: _copy_or_link() returned an unknown action:{}".format(action)) ++ _copy_symlinks(symlinks_to_process, srcdir) + + + def _copy_certificates(context, target_userspace): +diff --git a/repos/system_upgrade/common/actors/targetuserspacecreator/tests/unit_test_targetuserspacecreator.py b/repos/system_upgrade/common/actors/targetuserspacecreator/tests/unit_test_targetuserspacecreator.py +index bd49f657..19b760a1 100644 +--- a/repos/system_upgrade/common/actors/targetuserspacecreator/tests/unit_test_targetuserspacecreator.py ++++ b/repos/system_upgrade/common/actors/targetuserspacecreator/tests/unit_test_targetuserspacecreator.py +@@ -381,6 +381,70 @@ def temp_directory_layout(tmp_path, initial_structure): + }, + id="Absolute_symlink_to_a_file_inside_via_a_symlink_to_the_rootdir" + )), ++ # This should be fixed but not necessarily for this release. ++ # It makes sure that when we have two separate links to the ++ # same file outside of /etc/pki, one of the links is copied ++ # as a real file and the other is made a link to the copy. ++ # (Right now, the real file is copied in place of both links.) ++ # (pytest.param( ++ # { ++ # 'dir': { ++ # 'fileA': '/outside/fileC', ++ # 'fileB': '/outside/fileC', ++ # }, ++ # 'outside': { ++ # 'fileC': None, ++ # }, ++ # }, ++ # { ++ # 'dir': { ++ # 'fileA': None, ++ # 'fileB': '/dir/fileA', ++ # }, ++ # }, ++ # id="Absolute_two_symlinks_to_the_same_copied_file" ++ # )), ++ (pytest.param( ++ { ++ 'dir': { ++ 'fileA': None, ++ 'link_to_dir': '/dir/inside', ++ 'inside': { ++ 'fileB': None, ++ }, ++ }, ++ }, ++ { ++ 'dir': { ++ 'fileA': None, ++ 'link_to_dir': '/dir/inside', ++ 'inside': { ++ 'fileB': None, ++ }, ++ }, ++ }, ++ id="Absolute_symlink_to_a_dir_inside" ++ )), ++ (pytest.param( ++ { ++ 'dir': { ++ 'fileA': None, ++ 'link_to_dir': '/outside', ++ }, ++ 'outside': { ++ 'fileB': None, ++ }, ++ }, ++ { ++ 'dir': { ++ 'fileA': None, ++ 'link_to_dir': { ++ 'fileB': None, ++ }, ++ }, ++ }, ++ id="Absolute_symlink_to_a_dir_outside" ++ )), + (pytest.param( + # This one is very tricky: + # * The user has made /etc/pki a symlink to some other directory that +@@ -671,6 +735,70 @@ def temp_directory_layout(tmp_path, initial_structure): + }, + id="Relative_symlink_to_a_file_inside_via_a_symlink_to_the_rootdir" + )), ++ # This should be fixed but not necessarily for this release. ++ # It makes sure that when we have two separate links to the ++ # same file outside of /etc/pki, one of the links is copied ++ # as a real file and the other is made a link to the copy. ++ # (Right now, the real file is copied in place of both links.) ++ # (pytest.param( ++ # { ++ # 'dir': { ++ # 'fileA': '../outside/fileC', ++ # 'fileB': '../outside/fileC', ++ # }, ++ # 'outside': { ++ # 'fileC': None, ++ # }, ++ # }, ++ # { ++ # 'dir': { ++ # 'fileA': None, ++ # 'fileB': 'fileA', ++ # }, ++ # }, ++ # id="Relative_two_symlinks_to_the_same_copied_file" ++ # )), ++ (pytest.param( ++ { ++ 'dir': { ++ 'fileA': None, ++ 'link_to_dir': '../outside', ++ }, ++ 'outside': { ++ 'fileB': None, ++ }, ++ }, ++ { ++ 'dir': { ++ 'fileA': None, ++ 'link_to_dir': { ++ 'fileB': None, ++ }, ++ }, ++ }, ++ id="Relative_symlink_to_a_dir_outside" ++ )), ++ (pytest.param( ++ { ++ 'dir': { ++ 'fileA': None, ++ 'link_to_dir': 'inside', ++ 'inside': { ++ 'fileB': None, ++ }, ++ }, ++ }, ++ { ++ 'dir': { ++ 'fileA': None, ++ 'link_to_dir': 'inside', ++ 'inside': { ++ 'fileB': None, ++ }, ++ }, ++ }, ++ id="Relative_symlink_to_a_dir_inside" ++ )), + (pytest.param( + # This one is very tricky: + # * The user has made /etc/pki a symlink to some other directory that +-- +2.42.0 + diff --git a/0068-device-driver-deprecation-data-print-nice-error-msg-.patch b/0068-device-driver-deprecation-data-print-nice-error-msg-.patch new file mode 100644 index 0000000..6529bba --- /dev/null +++ b/0068-device-driver-deprecation-data-print-nice-error-msg-.patch @@ -0,0 +1,129 @@ +From 98a1057bb40a53a2200b0cfba9e4ad75b1d8f796 Mon Sep 17 00:00:00 2001 +From: Petr Stodulka +Date: Mon, 22 Jan 2024 18:40:07 +0100 +Subject: [PATCH 68/69] device driver deprecation data: print nice error msg on + malformed data + +In case of malformed device_driver_deprecation_data.json user could +originally see raw traceback without having too much information +what it actually means or how to fix it. That usually happens only +when the file is manually modified on the machine. So in this case +we inform user what file is problematic and how to restore the original +file installed by our package. + +In case of upstream development, this msg could be seen also when +new data is provided if: + * data file is malformed + * data file has a new format of data (still json expected) + * etc. +These issues however will be discovered prior the merge as the +running tests will fail, so such a problematic file should never +get part of the upstream. From that point, we will be expect that +user has malformed / customized data file. So no need to handle +all possible errors differently in this case. + +Jira: OAMG-7549 + +Co-authored-by: Toshio Kuratomi +--- + .../deviceanddriverdeprecationdataload.py | 36 ++++++++++++++----- + .../tests/test_ddddload.py | 28 +++++++++++++++ + 2 files changed, 56 insertions(+), 8 deletions(-) + +diff --git a/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/libraries/deviceanddriverdeprecationdataload.py b/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/libraries/deviceanddriverdeprecationdataload.py +index f422c2c3..b12e77c9 100644 +--- a/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/libraries/deviceanddriverdeprecationdataload.py ++++ b/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/libraries/deviceanddriverdeprecationdataload.py +@@ -1,6 +1,9 @@ ++from leapp.exceptions import StopActorExecutionError + from leapp.libraries.common import fetch ++from leapp.libraries.common.rpms import get_leapp_packages, LeappComponents + from leapp.libraries.stdlib import api + from leapp.models import DeviceDriverDeprecationData, DeviceDriverDeprecationEntry ++from leapp.models.fields import ModelViolationError + + + def process(): +@@ -22,12 +25,29 @@ def process(): + docs_url='', + docs_title='') + +- api.produce( +- DeviceDriverDeprecationData( +- entries=[ +- DeviceDriverDeprecationEntry(**entry) +- for entry in deprecation_data['data'] +- if entry.get('device_type') in supported_device_types +- ] ++ try: ++ api.produce( ++ DeviceDriverDeprecationData( ++ entries=[ ++ DeviceDriverDeprecationEntry(**entry) ++ for entry in deprecation_data['data'] ++ if entry.get('device_type') in supported_device_types ++ ] ++ ) + ) +- ) ++ except (ModelViolationError, ValueError, KeyError, AttributeError, TypeError) as err: ++ # For the listed errors, we expect this to happen only when data is malformed ++ # or manually updated. Corrupted data in the upstream is discovered ++ # prior the merge thanks to testing. So just suggest the restoration ++ # of the file. ++ msg = 'Invalid device and driver deprecation data: {}'.format(err) ++ hint = ( ++ 'This issue is usually caused by manual update of the {lp} file.' ++ ' The data inside is either incorrect or old. To restore the original' ++ ' {lp} file, remove it and reinstall the following packages: {rpms}' ++ .format( ++ lp='/etc/leapp/file/device_driver_deprecation_data.json', ++ rpms=', '.join(get_leapp_packages(component=LeappComponents.REPOSITORY)) ++ ) ++ ) ++ raise StopActorExecutionError(msg, details={'hint': hint}) +diff --git a/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/tests/test_ddddload.py b/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/tests/test_ddddload.py +index 69bcd09c..c3386745 100644 +--- a/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/tests/test_ddddload.py ++++ b/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/tests/test_ddddload.py +@@ -1,5 +1,9 @@ ++import pytest ++ ++from leapp.exceptions import StopActorExecutionError + from leapp.libraries.actor import deviceanddriverdeprecationdataload as ddddload + from leapp.libraries.common import fetch ++from leapp.libraries.common.testutils import CurrentActorMocked + + TEST_DATA = { + 'data': [ +@@ -57,3 +61,27 @@ def test_filtered_load(monkeypatch): + assert produced + assert len(produced[0].entries) == 3 + assert not any([e.device_type == 'unsupported' for e in produced[0].entries]) ++ ++ ++@pytest.mark.parametrize('data', ( ++ {}, ++ {'foo': 'bar'}, ++ {'data': 1, 'foo': 'bar'}, ++ {'data': 'string', 'foo': 'bar'}, ++ {'data': {'foo': 1}, 'bar': 2}, ++ {'data': {'foo': 1, 'device_type': None}}, ++ {'data': {'foo': 1, 'device_type': 'cpu'}}, ++ {'data': {'driver_name': ['foo'], 'device_type': 'cpu'}}, ++)) ++def test_invalid_dddd_data(monkeypatch, data): ++ produced = [] ++ ++ def load_data_asset_mock(*args, **kwargs): ++ return data ++ ++ monkeypatch.setattr(fetch, 'load_data_asset', load_data_asset_mock) ++ monkeypatch.setattr(ddddload.api, 'current_actor', CurrentActorMocked()) ++ monkeypatch.setattr(ddddload.api, 'produce', lambda *v: produced.extend(v)) ++ with pytest.raises(StopActorExecutionError): ++ ddddload.process() ++ assert not produced +-- +2.42.0 + diff --git a/0069-Update-PES-data-CTC2-2.patch b/0069-Update-PES-data-CTC2-2.patch new file mode 100644 index 0000000..7dfb0e6 --- /dev/null +++ b/0069-Update-PES-data-CTC2-2.patch @@ -0,0 +1,695 @@ +From b75dc49bb3d41e89067a8b609eeb35c485fb40a1 Mon Sep 17 00:00:00 2001 +From: Petr Stodulka +Date: Tue, 23 Jan 2024 16:48:44 +0100 +Subject: [PATCH 69/69] Update PES data (CTC2-2) + +Includes fixed idm-tomcatjss related events for upgrades IPU 8 -> 9. + +Jira: RHEL-21779 +--- + etc/leapp/files/pes-events.json | 666 +++++++++++++++++++++++++++++++- + 1 file changed, 665 insertions(+), 1 deletion(-) + +diff --git a/etc/leapp/files/pes-events.json b/etc/leapp/files/pes-events.json +index 5b4b4f87..dfc09de5 100644 +--- a/etc/leapp/files/pes-events.json ++++ b/etc/leapp/files/pes-events.json +@@ -500344,10 +500344,674 @@ null + "minor_version": 4, + "os_name": "RHEL" + } ++}, ++{ ++"action": 0, ++"architectures": [ ++"aarch64", ++"ppc64le", ++"s390x", ++"x86_64" ++], ++"id": 13841, ++"in_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "libtimezonemap-devel", ++"repository": "rhel9-CRB" ++} ++], ++"set_id": 19633 ++}, ++"initial_release": { ++"major_version": 9, ++"minor_version": 3, ++"os_name": "RHEL" ++}, ++"modulestream_maps": [], ++"out_packageset": null, ++"release": { ++"major_version": 9, ++"minor_version": 4, ++"os_name": "RHEL" ++} ++}, ++{ ++"action": 0, ++"architectures": [ ++"aarch64", ++"ppc64le", ++"s390x", ++"x86_64" ++], ++"id": 13842, ++"in_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "libtimezonemap-devel", ++"repository": "rhel8-CRB" ++} ++], ++"set_id": 19634 ++}, ++"initial_release": { ++"major_version": 8, ++"minor_version": 9, ++"os_name": "RHEL" ++}, ++"modulestream_maps": [], ++"out_packageset": null, ++"release": { ++"major_version": 8, ++"minor_version": 10, ++"os_name": "RHEL" ++} ++}, ++{ ++"action": 0, ++"architectures": [ ++"aarch64", ++"ppc64le", ++"s390x", ++"x86_64" ++], ++"id": 13843, ++"in_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "libadwaita", ++"repository": "rhel9-AppStream" ++} ++], ++"set_id": 19635 ++}, ++"initial_release": { ++"major_version": 9, ++"minor_version": 3, ++"os_name": "RHEL" ++}, ++"modulestream_maps": [], ++"out_packageset": null, ++"release": { ++"major_version": 9, ++"minor_version": 4, ++"os_name": "RHEL" ++} ++}, ++{ ++"action": 0, ++"architectures": [ ++"aarch64", ++"ppc64le", ++"s390x", ++"x86_64" ++], ++"id": 13844, ++"in_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "libadwaita-devel", ++"repository": "rhel9-CRB" ++} ++], ++"set_id": 19636 ++}, ++"initial_release": { ++"major_version": 9, ++"minor_version": 3, ++"os_name": "RHEL" ++}, ++"modulestream_maps": [], ++"out_packageset": null, ++"release": { ++"major_version": 9, ++"minor_version": 4, ++"os_name": "RHEL" ++} ++}, ++{ ++"action": 1, ++"architectures": [ ++"aarch64", ++"ppc64le", ++"s390x", ++"x86_64" ++], ++"id": 13845, ++"in_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "libtimezonemap-devel", ++"repository": "rhel8-CRB" ++} ++], ++"set_id": 19637 ++}, ++"initial_release": { ++"major_version": 8, ++"minor_version": 10, ++"os_name": "RHEL" ++}, ++"modulestream_maps": [], ++"out_packageset": null, ++"release": { ++"major_version": 9, ++"minor_version": 0, ++"os_name": "RHEL" ++} ++}, ++{ ++"action": 1, ++"architectures": [ ++"aarch64", ++"ppc64le", ++"s390x", ++"x86_64" ++], ++"id": 13846, ++"in_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "graphviz-ruby", ++"repository": "rhel8-AppStream" ++} ++], ++"set_id": 19638 ++}, ++"initial_release": { ++"major_version": 8, ++"minor_version": 10, ++"os_name": "RHEL" ++}, ++"modulestream_maps": [], ++"out_packageset": null, ++"release": { ++"major_version": 9, ++"minor_version": 0, ++"os_name": "RHEL" ++} ++}, ++{ ++"action": 2, ++"architectures": [ ++"aarch64", ++"ppc64le", ++"s390x", ++"x86_64" ++], ++"id": 13847, ++"in_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "graphviz-ruby", ++"repository": "rhel8-AppStream" ++} ++], ++"set_id": 19639 ++}, ++"initial_release": { ++"major_version": 8, ++"minor_version": 9, ++"os_name": "RHEL" ++}, ++"modulestream_maps": [], ++"out_packageset": null, ++"release": { ++"major_version": 8, ++"minor_version": 10, ++"os_name": "RHEL" ++} ++}, ++{ ++"action": 0, ++"architectures": [ ++"aarch64", ++"ppc64le", ++"s390x", ++"x86_64" ++], ++"id": 13848, ++"in_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "vulkan-utility-libraries-devel", ++"repository": "rhel9-CRB" ++} ++], ++"set_id": 19640 ++}, ++"initial_release": { ++"major_version": 9, ++"minor_version": 3, ++"os_name": "RHEL" ++}, ++"modulestream_maps": [], ++"out_packageset": null, ++"release": { ++"major_version": 9, ++"minor_version": 4, ++"os_name": "RHEL" ++} ++}, ++{ ++"action": 0, ++"architectures": [ ++"aarch64", ++"ppc64le", ++"s390x", ++"x86_64" ++], ++"id": 13849, ++"in_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "gtk-vnc2-devel", ++"repository": "rhel8-CRB" ++} ++], ++"set_id": 19641 ++}, ++"initial_release": { ++"major_version": 8, ++"minor_version": 8, ++"os_name": "RHEL" ++}, ++"modulestream_maps": [], ++"out_packageset": null, ++"release": { ++"major_version": 8, ++"minor_version": 9, ++"os_name": "RHEL" ++} ++}, ++{ ++"action": 0, ++"architectures": [ ++"aarch64", ++"ppc64le", ++"s390x", ++"x86_64" ++], ++"id": 13850, ++"in_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "gvnc-devel", ++"repository": "rhel8-CRB" ++} ++], ++"set_id": 19642 ++}, ++"initial_release": { ++"major_version": 8, ++"minor_version": 8, ++"os_name": "RHEL" ++}, ++"modulestream_maps": [], ++"out_packageset": null, ++"release": { ++"major_version": 8, ++"minor_version": 9, ++"os_name": "RHEL" ++} ++}, ++{ ++"action": 0, ++"architectures": [ ++"aarch64", ++"ppc64le", ++"s390x", ++"x86_64" ++], ++"id": 13851, ++"in_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "graphviz-ruby", ++"repository": "rhel9-AppStream" ++} ++], ++"set_id": 19643 ++}, ++"initial_release": { ++"major_version": 9, ++"minor_version": 3, ++"os_name": "RHEL" ++}, ++"modulestream_maps": [], ++"out_packageset": null, ++"release": { ++"major_version": 9, ++"minor_version": 4, ++"os_name": "RHEL" ++} ++}, ++{ ++"action": 3, ++"architectures": [ ++"aarch64", ++"ppc64le", ++"s390x", ++"x86_64" ++], ++"id": 13852, ++"in_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++{ ++"name": "pki-deps", ++"stream": "10.6" ++} ++], ++"name": "pki-servlet-engine", ++"repository": "rhel8-AppStream" ++} ++], ++"set_id": 19644 ++}, ++"initial_release": { ++"major_version": 8, ++"minor_version": 9, ++"os_name": "RHEL" ++}, ++"modulestream_maps": [ ++{ ++"in_modulestream": { ++"name": "pki-deps", ++"stream": "10.6" ++}, ++"out_modulestream": null ++} ++], ++"out_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "tomcat", ++"repository": "rhel8-AppStream" ++} ++], ++"set_id": 19645 ++}, ++"release": { ++"major_version": 8, ++"minor_version": 10, ++"os_name": "RHEL" ++} ++}, ++{ ++"action": 3, ++"architectures": [ ++"aarch64", ++"ppc64le", ++"s390x", ++"x86_64" ++], ++"id": 13853, ++"in_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "idm-tomcatjss", ++"repository": "rhel9-AppStream" ++} ++], ++"set_id": 19646 ++}, ++"initial_release": { ++"major_version": 9, ++"minor_version": 3, ++"os_name": "RHEL" ++}, ++"modulestream_maps": [ ++{ ++"in_modulestream": null, ++"out_modulestream": null ++} ++], ++"out_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "idm-jss-tomcat", ++"repository": "rhel9-AppStream" ++} ++], ++"set_id": 19647 ++}, ++"release": { ++"major_version": 9, ++"minor_version": 4, ++"os_name": "RHEL" ++} ++}, ++{ ++"action": 0, ++"architectures": [ ++"aarch64", ++"ppc64le", ++"s390x", ++"x86_64" ++], ++"id": 13854, ++"in_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "gtk-vnc2-devel", ++"repository": "rhel9-CRB" ++} ++], ++"set_id": 19648 ++}, ++"initial_release": { ++"major_version": 9, ++"minor_version": 3, ++"os_name": "RHEL" ++}, ++"modulestream_maps": [], ++"out_packageset": null, ++"release": { ++"major_version": 9, ++"minor_version": 4, ++"os_name": "RHEL" ++} ++}, ++{ ++"action": 7, ++"architectures": [ ++"aarch64", ++"ppc64le", ++"s390x", ++"x86_64" ++], ++"id": 13855, ++"in_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "leapp-upgrade-el7toel8", ++"repository": "rhel7-extras" ++} ++], ++"set_id": 19649 ++}, ++"initial_release": { ++"major_version": 7, ++"minor_version": 9, ++"os_name": "RHEL" ++}, ++"modulestream_maps": [ ++{ ++"in_modulestream": null, ++"out_modulestream": null ++} ++], ++"out_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "leapp-upgrade-el8toel9", ++"repository": "rhel8-AppStream" ++} ++], ++"set_id": 19650 ++}, ++"release": { ++"major_version": 8, ++"minor_version": 6, ++"os_name": "RHEL" ++} ++}, ++{ ++"action": 7, ++"architectures": [ ++"aarch64", ++"ppc64le", ++"s390x", ++"x86_64" ++], ++"id": 13856, ++"in_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "python2-leapp", ++"repository": "rhel7-extras" ++} ++], ++"set_id": 19651 ++}, ++"initial_release": { ++"major_version": 7, ++"minor_version": 9, ++"os_name": "RHEL" ++}, ++"modulestream_maps": [ ++{ ++"in_modulestream": null, ++"out_modulestream": null ++} ++], ++"out_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "python3-leapp", ++"repository": "rhel8-AppStream" ++} ++], ++"set_id": 19652 ++}, ++"release": { ++"major_version": 8, ++"minor_version": 6, ++"os_name": "RHEL" ++} ++}, ++{ ++"action": 7, ++"architectures": [ ++"aarch64", ++"ppc64le", ++"s390x", ++"x86_64" ++], ++"id": 13857, ++"in_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "leapp-upgrade-el7toel8-deps", ++"repository": "rhel7-extras" ++} ++], ++"set_id": 19653 ++}, ++"initial_release": { ++"major_version": 7, ++"minor_version": 9, ++"os_name": "RHEL" ++}, ++"modulestream_maps": [ ++{ ++"in_modulestream": null, ++"out_modulestream": null ++} ++], ++"out_packageset": { ++"package": [ ++{ ++"modulestreams": [ ++null ++], ++"name": "leapp-upgrade-el8toel9-deps", ++"repository": "rhel8-AppStream" ++} ++], ++"set_id": 19654 ++}, ++"release": { ++"major_version": 8, ++"minor_version": 6, ++"os_name": "RHEL" ++} + } + ], + "provided_data_streams": [ + "3.0" + ], +-"timestamp": "202401101404Z" ++"timestamp": "202401231304Z" + } +-- +2.42.0 + diff --git a/leapp-repository.spec b/leapp-repository.spec index 0c4b99c..5d0d243 100644 --- a/leapp-repository.spec +++ b/leapp-repository.spec @@ -42,7 +42,7 @@ py2_byte_compile "%1" "%2"} Name: leapp-repository Version: 0.19.0 -Release: 9%{?dist} +Release: 10%{?dist} Summary: Repositories for leapp License: ASL 2.0 @@ -126,6 +126,10 @@ Patch0064: 0064-Cover-upgrades-RHEL-8-to-RHEL-9-using-RHUI-on-Alibab.patch Patch0065: 0065-load-data-files-do-not-try-to-download-data-files-wh.patch Patch0066: 0066-upgrade-data-files-loading-update-error-msgs-and-rep.patch +# CTC2-2 +Patch0067: 0067-Fix-another-cornercase-with-symlink-handling.patch +Patch0068: 0068-device-driver-deprecation-data-print-nice-error-msg-.patch +Patch0069: 0069-Update-PES-data-CTC2-2.patch %description %{summary} @@ -343,7 +347,9 @@ Requires: python3-gobject-base %patch0064 -p1 %patch0065 -p1 %patch0066 -p1 - +%patch0067 -p1 +%patch0068 -p1 +%patch0069 -p1 %build %if 0%{?rhel} == 7 @@ -420,6 +426,12 @@ done; # no files here %changelog +* Tue Jan 23 2024 Toshio Kuratomi - 0.19.0-10 +- Print nice error msg when device and driver deprecation data is malformed +- Fix another cornercase when preserving symlinks to certificates in /etc/pki +- Update the leapp upgrade data files - fixing upgrades with idm-tomcatjss +- Resolves: RHEL-16729 + * Fri Jan 19 2024 Petr Stodulka - 0.19.0-9 - Do not try to download data files anymore when missing as the service is obsoleted since the data is part of installed packages