diff --git a/CHANGES/7846.bugfix b/CHANGES/7846.bugfix new file mode 100644 index 0000000000..b71fc47ada --- /dev/null +++ b/CHANGES/7846.bugfix @@ -0,0 +1 @@ +Fix temp file leak in pull-through metadata streaming. diff --git a/pulpcore/content/handler.py b/pulpcore/content/handler.py index 671ab72c84..dcaef91060 100644 --- a/pulpcore/content/handler.py +++ b/pulpcore/content/handler.py @@ -904,6 +904,7 @@ async def _match_and_stream(self, path, request): # Try to stream the RemoteArtifact and potentially save it as a new Content unit save_artifact = ( remote.get_remote_artifact_content_type(original_rel_path) is not None + and remote.policy != Remote.STREAMED ) ca = ContentArtifact(relative_path=original_rel_path) ra = RemoteArtifact(remote=remote, url=url, content_artifact=ca) @@ -972,7 +973,10 @@ async def _stream_content_artifact(self, request, response, content_artifact): ) async for remote_artifact in remote_artifacts: try: - response = await self._stream_remote_artifact(request, response, remote_artifact) + save_artifact = remote_artifact.remote.policy != Remote.STREAMED + response = await self._stream_remote_artifact( + request, response, remote_artifact, save_artifact=save_artifact + ) return response except SKIPPABLE_EXCEPTIONS as e: log.warning( @@ -1179,7 +1183,7 @@ async def _serve_content_artifact(self, content_artifact, headers, request): return response async def _stream_remote_artifact( - self, request, response, remote_artifact, save_artifact=True, repository=None + self, request, response, remote_artifact, save_artifact, repository=None ): """ Stream and save a RemoteArtifact. @@ -1289,12 +1293,12 @@ async def handle_data(data): data_size_handled = data_size_handled + len(data) else: await response.write(data) - if remote.policy != Remote.STREAMED: + if save_artifact: await original_handle_data(data) async def finalize(): nonlocal failed_download - if save_artifact and remote.policy != Remote.STREAMED: + if save_artifact: await original_finalize() failed_download = False @@ -1342,7 +1346,7 @@ async def finalize(): if hasattr(downloader, "session"): await downloader.session.close() - if save_artifact and remote.policy != Remote.STREAMED: + if save_artifact: content_artifacts = await asyncio.shield( sync_to_async(self._save_artifact)(download_result, remote_artifact, request) )