diff --git a/iib/workers/tasks/fbc_utils.py b/iib/workers/tasks/fbc_utils.py index 5e809648b..158d5c72d 100644 --- a/iib/workers/tasks/fbc_utils.py +++ b/iib/workers/tasks/fbc_utils.py @@ -196,19 +196,35 @@ def extract_fbc_fragment( # store the fbc_fragment at /tmp/iib-**/fbc-fragment-{index} to prevent # cross-contamination conf = get_worker_config() - fbc_fragment_path = os.path.join(temp_dir, f"{conf['temp_fbc_fragment_path']}-{fragment_index}") + fbc_fragment_base_path = os.path.join( + temp_dir, f"{conf['temp_fbc_fragment_path']}-{fragment_index}" + ) # Copy fbc_fragment's catalog to /tmp/iib-**/fbc-fragment-{index} extract_directory_from_image_non_privileged( - image=fbc_fragment, src_path=conf['fbc_fragment_catalog_path'], dest_path=fbc_fragment_path + image=fbc_fragment, + src_path=conf['fbc_fragment_catalog_path'], + dest_path=fbc_fragment_base_path, + ) + + # extract_directory_from_image_non_privileged creates dest_path//, + # e.g. /tmp/iib-**/fbc-fragment-0/configs/example-operator. Match get_catalog_dir(). + fbc_fragment_catalog_dir = os.path.join( + fbc_fragment_base_path, + os.path.basename(conf['fbc_fragment_catalog_path'].rstrip('/')), ) + if not os.path.isdir(fbc_fragment_catalog_dir): + raise IIBError( + f"FBC fragment catalog directory not found at {fbc_fragment_catalog_dir} " + f"after extracting {fbc_fragment}" + ) - log.info("fbc_fragment extracted at %s", fbc_fragment_path) - operator_packages = os.listdir(fbc_fragment_path) + log.info("fbc_fragment extracted at %s", fbc_fragment_catalog_dir) + operator_packages = os.listdir(fbc_fragment_catalog_dir) log.info("fbc_fragment contains packages %s", operator_packages) if not operator_packages: raise IIBError("No operator packages in fbc_fragment %s", fbc_fragment) - return fbc_fragment_path, operator_packages + return fbc_fragment_catalog_dir, operator_packages def _serialize_datetime(obj: datetime) -> str: diff --git a/tests/test_workers/test_tasks/test_fbc_utils.py b/tests/test_workers/test_tasks/test_fbc_utils.py index 3aced8e6c..532d0acc0 100644 --- a/tests/test_workers/test_tasks/test_fbc_utils.py +++ b/tests/test_workers/test_tasks/test_fbc_utils.py @@ -215,19 +215,27 @@ def test_extract_fbc_fragment(mock_extract_dir, mock_osldr, ldr_output, tmpdir): test_fbc_fragment = "example.com/test/fbc_fragment:latest" mock_osldr.return_value = ldr_output # The function now adds -0 suffix by default when fragment_index is not provided - fbc_fragment_path = os.path.join(tmpdir, f"{get_worker_config()['temp_fbc_fragment_path']}-0") + fbc_fragment_base_path = os.path.join( + tmpdir, f"{get_worker_config()['temp_fbc_fragment_path']}-0" + ) + fbc_fragment_catalog_dir = os.path.join( + fbc_fragment_base_path, os.path.basename(get_worker_config()['fbc_fragment_catalog_path']) + ) + os.makedirs(fbc_fragment_catalog_dir) if not ldr_output: with pytest.raises(IIBError): extract_fbc_fragment(tmpdir, test_fbc_fragment) else: - extract_fbc_fragment(tmpdir, test_fbc_fragment) + result_path, result_operators = extract_fbc_fragment(tmpdir, test_fbc_fragment) + assert result_path == fbc_fragment_catalog_dir + assert result_operators == ldr_output mock_extract_dir.assert_called_once_with( image=test_fbc_fragment, src_path=get_worker_config()['fbc_fragment_catalog_path'], - dest_path=fbc_fragment_path, + dest_path=fbc_fragment_base_path, ) - mock_osldr.assert_called_once_with(fbc_fragment_path) + mock_osldr.assert_called_once_with(fbc_fragment_catalog_dir) @pytest.mark.parametrize('ldr_output', [['testoperator'], ['test1', 'test2']]) @@ -240,26 +248,30 @@ def test_extract_fbc_fragment_with_index(mock_extract_dir, mock_osldr, ldr_outpu # Test with fragment_index = 2 fragment_index = 2 - fbc_fragment_path = os.path.join( + fbc_fragment_base_path = os.path.join( tmpdir, f"{get_worker_config()['temp_fbc_fragment_path']}-{fragment_index}" ) + fbc_fragment_catalog_dir = os.path.join( + fbc_fragment_base_path, os.path.basename(get_worker_config()['fbc_fragment_catalog_path']) + ) + os.makedirs(fbc_fragment_catalog_dir) result_path, result_operators = extract_fbc_fragment( tmpdir, test_fbc_fragment, fragment_index=fragment_index ) - # Verify the path includes the correct index - assert result_path == fbc_fragment_path - assert result_path.endswith(f"-{fragment_index}") + # Verify the path includes the correct index and catalog directory + assert result_path == fbc_fragment_catalog_dir + assert result_path.endswith(f"fbc-fragment-{fragment_index}/configs") assert result_operators == ldr_output # Verify the function was called with the correct path mock_extract_dir.assert_called_once_with( image=test_fbc_fragment, src_path=get_worker_config()['fbc_fragment_catalog_path'], - dest_path=fbc_fragment_path, + dest_path=fbc_fragment_base_path, ) - mock_osldr.assert_called_once_with(fbc_fragment_path) + mock_osldr.assert_called_once_with(fbc_fragment_catalog_dir) @mock.patch('os.listdir') @@ -272,6 +284,25 @@ def test_extract_fbc_fragment_isolation(mock_extract_dir, mock_osldr, tmpdir): # Mock different outputs for each fragment mock_osldr.side_effect = [['operator1'], ['operator2']] + fbc_fragment_base_path_0 = os.path.join( + tmpdir, f"{get_worker_config()['temp_fbc_fragment_path']}-0" + ) + fbc_fragment_base_path_1 = os.path.join( + tmpdir, f"{get_worker_config()['temp_fbc_fragment_path']}-1" + ) + os.makedirs( + os.path.join( + fbc_fragment_base_path_0, + os.path.basename(get_worker_config()['fbc_fragment_catalog_path']), + ) + ) + os.makedirs( + os.path.join( + fbc_fragment_base_path_1, + os.path.basename(get_worker_config()['fbc_fragment_catalog_path']), + ) + ) + # Extract first fragment with index 0 path1, operators1 = extract_fbc_fragment(tmpdir, test_fbc_fragment1, fragment_index=0) @@ -280,8 +311,8 @@ def test_extract_fbc_fragment_isolation(mock_extract_dir, mock_osldr, tmpdir): # Verify paths are different and include correct indices assert path1 != path2 - assert path1.endswith("-0") - assert path2.endswith("-1") + assert path1.endswith("fbc-fragment-0/configs") + assert path2.endswith("fbc-fragment-1/configs") # Verify operators are different (no cross-contamination) assert operators1 == ['operator1'] @@ -292,12 +323,12 @@ def test_extract_fbc_fragment_isolation(mock_extract_dir, mock_osldr, tmpdir): mock.call( image=test_fbc_fragment1, src_path=get_worker_config()['fbc_fragment_catalog_path'], - dest_path=path1, + dest_path=fbc_fragment_base_path_0, ), mock.call( image=test_fbc_fragment2, src_path=get_worker_config()['fbc_fragment_catalog_path'], - dest_path=path2, + dest_path=fbc_fragment_base_path_1, ), ] mock_extract_dir.assert_has_calls(expected_calls, any_order=True)