fix: run the reclaim helper as root regardless of the image's default USER

The one-shot reclaim container inherited the image's baked-in USER:
ghcr.io/nokia/srlinux runs as "user:user", so the "privileged" helper
was exactly as unprivileged as the server itself — chmod/chown on files
written by other uids (srlinux writes as a large internal uid) failed
with EPERM and node/project deletion still broke, just with a different
error. Pass --user 0:0 explicitly so the helper is root no matter what
the image declares, and fix the manual reclaim hint the same way.

Validated live on two stuck srlinux node directories (257/258
foreign-owned entries reclaimed to 0 in ~0.5 s each).
This commit is contained in:
YueGuobin committed 2026-09-12 23:15:52 +08:00
1 parent 54d9d7c08f
commit 4b239cc11a
2 files changed
+9 -5

No files matched your search

+2 -2
View File
@@ -2093,7 +2093,7 @@ async def test_reclaim_runs_helper_container(vm, tmp_path):
assert await vm._reclaim_directory_ownership(str(directory)) is True
args, _ = mock_exec.call_args
assert args[:7] == ("docker", "run", "--rm", "--network", "none", "--pull", "never")
assert args[:9] == ("docker", "run", "--rm", "--network", "none", "--pull", "never", "--user", "0:0")
assert args[args.index("--entrypoint") + 1] == "/gns3/bin/busybox"
assert "/gns3-share:/gns3:ro" in args
assert f"{directory}:/target" in args
@@ -2149,7 +2149,7 @@ async def test_delete_reports_root_files_when_reclaim_fails(vm):
with patch.object(vm, "_reclaim_directory_ownership", new_callable=AsyncioMagicMock, return_value=False):
with patch("gns3server.compute.base_node.shutil.rmtree",
side_effect=OSError("permission denied")):
with pytest.raises(ComputeError, match="owned by root"):
with pytest.raises(ComputeError, match="owned by another user"):
await vm.delete()