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:
1 parent
d4a517fc7e
commit
4cbdc41e20
4 files changed
+76
-25
No files matched your search
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user