This is an automated email from the ASF dual-hosted git repository. rahulvats pushed a commit to branch py-client-sync in repository https://gitbox.apache.org/repos/asf/airflow.git
commit dfa6b2d3e465d90b95675cdb0822f178baa65035 Author: Yoann <[email protected]> AuthorDate: Mon Mar 23 23:04:52 2026 -0700 fix(providers/alibaba): pass relative path to oss_write in OSSRemoteLogIO.upload (#63246) upload() was passing the full OSS URI (built with remote_base prefix) to oss_write(), which prepends base_folder internally, producing a doubled path like oss://bucket/prefix/oss://bucket/prefix/dag_id=.../attempt=1.log. Pass only the relative path so oss_write() constructs the correct key. Closes: #63242 --- .../providers/alibaba/cloud/log/oss_task_handler.py | 6 +++--- .../unit/alibaba/cloud/log/test_oss_task_handler.py | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/providers/alibaba/src/airflow/providers/alibaba/cloud/log/oss_task_handler.py b/providers/alibaba/src/airflow/providers/alibaba/cloud/log/oss_task_handler.py index 236a94ba257..4a50538fc9a 100644 --- a/providers/alibaba/src/airflow/providers/alibaba/cloud/log/oss_task_handler.py +++ b/providers/alibaba/src/airflow/providers/alibaba/cloud/log/oss_task_handler.py @@ -49,15 +49,15 @@ class OSSRemoteLogIO(LoggingMixin): # noqa: D101 path = Path(path) if path.is_absolute(): local_loc = path - remote_loc = os.path.join(self.remote_base, path.relative_to(self.base_log_folder)) + relative_path = str(path.relative_to(self.base_log_folder)) else: local_loc = self.base_log_folder.joinpath(path) - remote_loc = os.path.join(self.remote_base, path) + relative_path = str(path) if local_loc.is_file(): # read log and remove old logs to get just the latest additions log = local_loc.read_text() - has_uploaded = self.oss_write(log, remote_loc) + has_uploaded = self.oss_write(log, relative_path) if has_uploaded and self.delete_local_copy: shutil.rmtree(os.path.dirname(local_loc)) diff --git a/providers/alibaba/tests/unit/alibaba/cloud/log/test_oss_task_handler.py b/providers/alibaba/tests/unit/alibaba/cloud/log/test_oss_task_handler.py index 1fcc9be4f89..cfdcdcab480 100644 --- a/providers/alibaba/tests/unit/alibaba/cloud/log/test_oss_task_handler.py +++ b/providers/alibaba/tests/unit/alibaba/cloud/log/test_oss_task_handler.py @@ -184,6 +184,27 @@ class TestOSSTaskHandler: handler.close() assert os.path.exists(handler.handler.baseFilename) == expected_existence_of_local_copy + @mock.patch(OSS_TASK_HANDLER_STRING.format("OSSRemoteLogIO.oss_write")) + def test_upload_passes_relative_path_to_oss_write(self, mock_oss_write, tmp_path): + """Test that upload() passes only the relative path to oss_write(), not the full OSS URI.""" + mock_oss_write.return_value = True + log_dir = tmp_path / "dag_id=test" / "run_id=test" / "task_id=test" + log_dir.mkdir(parents=True) + log_file = log_dir / "attempt=1.log" + log_file.write_text("test log content") + + handler = OSSTaskHandler(str(tmp_path), self.oss_log_folder) + + # Test with relative path + relative_path = "dag_id=test/run_id=test/task_id=test/attempt=1.log" + handler.io.upload(relative_path, self.ti) + mock_oss_write.assert_called_once_with("test log content", relative_path) + + # Test with absolute path — should also pass relative portion + mock_oss_write.reset_mock() + handler.io.upload(str(log_file), self.ti) + mock_oss_write.assert_called_once_with("test log content", relative_path) + def test_filename_template_for_backward_compatibility(self): # filename_template arg support for running the latest provider on airflow 2 OSSTaskHandler(self.base_log_folder, self.oss_log_folder, filename_template=None)
