From 8cfa3fbd18405bb43ee79688aa88b50b367d9737 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 16 Sep 2026 22:05:22 +0100 Subject: [PATCH] fix: let the container pick the staging directory for a restored volume A fixed path under /tmp was both a guess about what the image can write to and a temp-file smell that Bandit flags. The container makes the directory itself with mktemp -d and removes it afterwards. --- docsgpt/deploy/docker.py | 13 +++++++------ tests/deploy/test_docker.py | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/docsgpt/deploy/docker.py b/docsgpt/deploy/docker.py index 2b3dcdfa..cba24375 100644 --- a/docsgpt/deploy/docker.py +++ b/docsgpt/deploy/docker.py @@ -117,13 +117,14 @@ class Docker: def import_volume(self, volume: str, source: Path, image: str) -> None: """Replace ``volume``'s contents with the tar at ``source``; the volume is created when missing.""" - # Unpack into the container's own filesystem first, so a truncated or corrupt tar fails - # before the live volume is touched rather than halfway through emptying it. It goes under - # /tmp because the image does not run as root and cannot write to /. - staging = "/tmp/docsgpt-restore" + # Unpack into a throwaway directory inside the container first, so a truncated or corrupt + # tar fails before the live volume is touched rather than halfway through emptying it. The + # container makes the directory itself: the image does not run as root, and a fixed path + # would be both a guess about what is writable and a temp-file smell. script = ( - f"set -e; rm -rf {staging}; mkdir -p {staging}; tar xf - -C {staging}; " - f"find /data -mindepth 1 -delete; tar cf - -C {staging} . | tar xf - -C /data" + 'set -e; stage=$(mktemp -d); tar xf - -C "$stage"; ' + 'find /data -mindepth 1 -delete; tar cf - -C "$stage" . | tar xf - -C /data; ' + 'rm -rf "$stage"' ) with source.open("rb") as handle: self._run( diff --git a/tests/deploy/test_docker.py b/tests/deploy/test_docker.py index 0f1a3e8b..f42d57c9 100644 --- a/tests/deploy/test_docker.py +++ b/tests/deploy/test_docker.py @@ -130,8 +130,8 @@ class TestVolumes: assert args[-2] == "-c" assert "tar xf - -C /data" in args[-1] command = args[-1] - assert "mkdir -p /tmp/" in command, "the image does not run as root, so staging goes under /tmp" - assert command.index("tar xf - -C /tmp/") < command.index("find /data -mindepth 1 -delete"), ( + assert "mktemp -d" in command, "the container picks the staging directory, not a fixed path" + assert command.index('tar xf - -C "$stage"') < command.index("find /data -mindepth 1 -delete"), ( "the incoming tar is unpacked outside the volume first, so a corrupt one leaves it alone" ) assert runner.streams[0][1] is not None, "the tar is fed in on stdin"