fix: task files endpoint resolves tenant docker worktrees

GET /tasks/{id}/files previously returned 409 for all docker tasks
on the grounds that tenant docker shares /app/work per project.
Production inspection shows the worker creates a per-task
host-worktrees/<task-id> subdirectory under the tenant work dir
(62 such dirs under the wwww tenant), so per-task reads are
attributable after all: the endpoint now resolves tenant docker
tasks via tenants/<project>/work/host-worktrees/<task-id> (local
worktree as fallback), never serves the shared /app/work mount
itself, and still 409s cloud/cross-host tasks. Docs and the
harness2_tasks boundary notes are updated to match.
This commit is contained in:
host committed 2026-10-29 23:16:01 +08:00
1 parent d4a517fc7e
commit 4cbdc41e20
4 files changed
+76 -25

No files matched your search

+25 -1
View File
@@ -37,6 +37,8 @@ class TaskFilesTestCase(unittest.TestCase):
self.worktrees = os.path.join(self.tmp.name, "host-worktrees")
os.makedirs(self.worktrees)
self.server.host_worktrees_dir = self.worktrees
self.tenants = os.path.join(self.tmp.name, "tenants")
self.server.tenants_root = self.tenants
self.port = self.server.server_address[1]
self.thread = threading.Thread(
target=self.server.serve_forever, daemon=True)
@@ -61,6 +63,14 @@ class TaskFilesTestCase(unittest.TestCase):
Path(self.tmp.name, "outside.txt").write_text("secret\n",
encoding="utf-8")
self._task("task-docker-1", executor="docker")
tenant_wt = os.path.join(
self.tenants, self.project["id"], "work",
"host-worktrees", "task-docker-1")
os.makedirs(tenant_wt)
Path(tenant_wt, "report.md").write_text("Total: 85.15\n",
encoding="utf-8")
self._task("task-docker-nodir", executor="docker")
self._task("task-cloud-1", executor="cloud")
self._task("task-nowt-1", executor=None)
def tearDown(self):
@@ -150,9 +160,23 @@ class TaskFilesTestCase(unittest.TestCase):
status, body = self._files("task-files-1", "big.txt")
self.assertEqual(status, 413, body)
def test_docker_task_409_and_auth(self):
def test_tenant_docker_task_files(self):
# 租户 Docker 任务走 tenants 下的任务级子目录,不再 409。
status, body = self._files("task-docker-1")
self.assertEqual(status, 200, body)
self.assertEqual([e["path"] for e in body["entries"]],
["report.md"])
status, body = self._files("task-docker-1", "report.md")
self.assertEqual(status, 200, body)
self.assertEqual(body["content"], "Total: 85.15\n")
def test_docker_task_without_worktree_404_and_cloud_409(self):
status, _ = self._files("task-docker-nodir")
self.assertEqual(status, 404)
status, body = self._files("task-cloud-1")
self.assertEqual(status, 409, body)
def test_auth(self):
status, _ = self._req("GET", "/tasks/task-files-1/files")
self.assertEqual(status, 401)
status, _ = self._files("task-files-1", key=self.outsider_key)