fix: check root before sudo when creating /workspace symlink
The previous ordering checked SUDO before checking if the process was already running as root. When Docker starts the container with a non-root user, SUDO may be empty, but the real fix is that the entrypoint should try root first (e.g. when the image is started as root) and only then fall back to sudo. - Reorder symlink creation logic: root first, then sudo, then best-effort - Update unit test to assert root is checked before sudo Quality gates: - pytest tests/unit: 208 passed - ruff: clean on changed files - mypy: clean on changed files
This commit is contained in:
@@ -24,9 +24,16 @@ def test_compile_dockerfile_creates_config_dirs_for_user() -> None:
|
||||
assert "groupadd -g 1000 dev" in dockerfile
|
||||
assert "useradd -u 1000 -g 1000 -m -s /bin/bash dev" in dockerfile
|
||||
assert "mkdir -p /home/dev && chown -R dev:dev /home/dev" in dockerfile
|
||||
assert "mkdir -p /home/dev/.config && chown -R dev:dev /home/dev/.config" in dockerfile
|
||||
assert "mkdir -p /home/dev/.local/share && chown -R dev:dev /home/dev/.local/share" in dockerfile
|
||||
assert "mkdir -p /home/dev/.cache && chown -R dev:dev /home/dev/.cache" in dockerfile
|
||||
assert (
|
||||
"mkdir -p /home/dev/.config && chown -R dev:dev /home/dev/.config" in dockerfile
|
||||
)
|
||||
assert (
|
||||
"mkdir -p /home/dev/.local/share && chown -R dev:dev /home/dev/.local/share"
|
||||
in dockerfile
|
||||
)
|
||||
assert (
|
||||
"mkdir -p /home/dev/.cache && chown -R dev:dev /home/dev/.cache" in dockerfile
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@@ -175,9 +182,7 @@ class TestCompileComposeHomeDirectory:
|
||||
"interface_type": "terminal",
|
||||
"home_directory": "/home/custom",
|
||||
"user": {"name": "dev", "uid": 1000, "gid": 1000},
|
||||
"mounts": [
|
||||
{"source_type": "repo", "target": "~/{{WORKSPACE_NAME}}"}
|
||||
],
|
||||
"mounts": [{"source_type": "repo", "target": "~/{{WORKSPACE_NAME}}"}],
|
||||
}
|
||||
variables = {
|
||||
"IMAGE_TAG": "test:latest",
|
||||
@@ -250,8 +255,8 @@ class TestCompileEntrypoint:
|
||||
assert 'ln -sfn "$WORKSPACE_TARGET" /workspace' in entrypoint
|
||||
assert 'WORKSPACE_NAME="${WORKSPACE_NAME:-workspace}"' in entrypoint
|
||||
|
||||
def test_entrypoint_uses_sudo_for_workspace_symlink(self) -> None:
|
||||
"""/workspace is under /, so the non-root entrypoint needs sudo to recreate it."""
|
||||
def test_entrypoint_uses_root_then_sudo_for_workspace_symlink(self) -> None:
|
||||
"""/workspace is under /, so root takes precedence; non-root falls back to sudo."""
|
||||
manifest = {
|
||||
"base_image": "ubuntu:24.04",
|
||||
"interface_type": "terminal",
|
||||
@@ -260,9 +265,12 @@ class TestCompileEntrypoint:
|
||||
}
|
||||
entrypoint = compile_entrypoint(manifest)
|
||||
|
||||
assert 'if [ -n "$SUDO" ]; then' in entrypoint
|
||||
root_idx = entrypoint.find('if [ "$(id -u)" = "0" ]; then')
|
||||
sudo_idx = entrypoint.find('elif [ -n "$SUDO" ]; then')
|
||||
assert root_idx != -1
|
||||
assert sudo_idx != -1
|
||||
assert root_idx < sudo_idx
|
||||
assert 'sudo ln -sfn "$WORKSPACE_TARGET" /workspace' in entrypoint
|
||||
assert 'elif [ "$(id -u)" = "0" ]; then' in entrypoint
|
||||
|
||||
def test_entrypoint_fixes_mount_owners(self) -> None:
|
||||
manifest = {
|
||||
@@ -279,4 +287,3 @@ class TestCompileEntrypoint:
|
||||
|
||||
assert 'fix_owner "/home/custom/.config"' in entrypoint
|
||||
assert 'fix_owner "/opt/readonly"' not in entrypoint
|
||||
|
||||
|
||||
Reference in New Issue
Block a user