From c0ee20842258aba73c1e4787bfb3834cfb99ce2b Mon Sep 17 00:00:00 2001 From: Ashwini Kumar Date: Tue, 4 Feb 2025 19:50:58 +0530 Subject: [PATCH] CLOUDDST-24254 : Merge index image failing with FBC operator present in source This commit fix this bug by ignoring deprecation operators which are not available in database. --- iib/workers/tasks/build_merge_index_image.py | 10 ++++++ iib/workers/tasks/utils.py | 38 ++++++++++++++++++++ tests/test_workers/test_tasks/test_utils.py | 31 ++++++++++++++++ 3 files changed, 79 insertions(+) diff --git a/iib/workers/tasks/build_merge_index_image.py b/iib/workers/tasks/build_merge_index_image.py index 6e0c2cf37..103466ec3 100644 --- a/iib/workers/tasks/build_merge_index_image.py +++ b/iib/workers/tasks/build_merge_index_image.py @@ -39,6 +39,7 @@ from iib.workers.tasks.utils import ( add_max_ocp_version_property, chmod_recursively, + filter_deprecation_operator_from_db, get_bundles_from_deprecation_list, request_logger, set_registry_token, @@ -326,6 +327,15 @@ def handle_merge_request( bundle['bundlePath'] for bundle in invalid_version_bundles ] + index_db_file = os.path.join(temp_dir, get_worker_config()['temp_index_db_path']) + + # Operator passed in deprecation list should be available in operator database, + # filter_deprecation_operator_from_db removes operaors which are passed in + # deprecation list and does not exists in database. + deprecation_bundles = filter_deprecation_operator_from_db( + deprecation_bundles, index_db_file + ) + if deprecation_bundles: intermediate_image_name = _get_external_arch_pull_spec( request_id, arch, include_transport=False diff --git a/iib/workers/tasks/utils.py b/iib/workers/tasks/utils.py index dddde80ed..afe2fc5c5 100644 --- a/iib/workers/tasks/utils.py +++ b/iib/workers/tasks/utils.py @@ -1293,3 +1293,41 @@ def get_bundle_metadata( for pullspec in operator_csv.get_pullspecs(): bundle_metadata['found_pullspecs'].add(pullspec) return bundle_metadata + + +def filter_deprecation_operator_from_db( + deprecation_bundles: List[str], index_db_file: str +) -> List[str]: + """ + Check if operator marked for deprecation is available in operator db, if not drop them. + + :param List[str] deprecation_bundles: List of bundles to be depricated + :param str index_db_file: Path of operator database + + :return: A List of operator bundle to be deprecated + :raises: + """ + try: + with sqlite3.connect(index_db_file) as conn: + query = "SELECT bundlepath FROM operatorbundler WHERE bundlepath IN ({})".format( + ','.join('?' for _ in deprecation_bundles) + ) + + cursor = conn.cursor() + cursor.execute(query, deprecation_bundles) + + results = cursor.fetchall() + log.info( + f"Deprication bundles available in databse : {results}" + ) + + if len(results) >= 1: + deprecation_bundles = list(results[0]) + else: + deprecation_bundles = [] + + return deprecation_bundles + + except Exception as e: + log.error(f"Failed to filter deprication bundle not available in db : {e}") + raise e diff --git a/tests/test_workers/test_tasks/test_utils.py b/tests/test_workers/test_tasks/test_utils.py index 4c1f0210b..e0a35ce88 100644 --- a/tests/test_workers/test_tasks/test_utils.py +++ b/tests/test_workers/test_tasks/test_utils.py @@ -1309,3 +1309,34 @@ def test_add_max_ocp_version_property_empty_index(mock_apti, mock_cmd, mock_gbj, mock_gbj.assert_not_called() mock_apti.assert_not_called() + + +@mock.patch('iib.workers.tasks.utils.sqlite3') +def test_filter_deprecation_operator_from_db(mock_db): + + mock_db.connect.return_value.__enter__.return_value.cursor.return_value.fetchall.return_value = [ + ["test_operator_1"] + ] + deprecation_bundles = [ + "test_operator_1", + ] + + operator_after_deprication = utils.filter_deprecation_operator_from_db( + "index/db/file", deprecation_bundles + ) + + assert operator_after_deprication == ["test_operator_1"] + + +@mock.patch('iib.workers.tasks.utils.sqlite3') +def test_failed_filter_deprecation_operator_from_db(mock_db): + + import sqlite3 + + mock_db.connect.side_effect = sqlite3.IntegrityError() + deprecation_bundles = [ + "test_operator_1", + ] + + with pytest.raises(sqlite3.IntegrityError): + utils.filter_deprecation_operator_from_db("index/db/file", deprecation_bundles)