fix: avoid literal {{WORKSPACE_NAME}} directories in built images
When a manifest mount target uses ~/{{WORKSPACE_NAME}}, the Dockerfile was
building a literal directory named {{WORKSPACE_NAME}} into the image and
creating a broken /workspace symlink. The runtime mount then created the
correct repo-named folder alongside the placeholder folder.
- Only create static mount target directories in the Dockerfile; skip any
target containing {{WORKSPACE_NAME}}
- Only create the /workspace compatibility symlink at image-build time when
the workspace name is known; otherwise let the entrypoint create it from
the WORKSPACE_NAME environment variable
- Update unit tests to cover both build-time workspace names and runtime
placeholders
Quality gates:
- pytest tests/unit: 211 passed
- ruff: clean on changed files
- mypy: clean on changed files
This commit is contained in:
@@ -221,27 +221,34 @@ def compile_dockerfile(manifest: dict) -> str:
|
||||
lines.append(f"RUN chown -R {name}:{name} {home_dir}")
|
||||
lines.append("")
|
||||
|
||||
# Create mount target directories and /workspace compatibility symlink.
|
||||
# The symlink target includes the workspace/repo name so legacy scripts
|
||||
# that cd into /workspace still land on the right project.
|
||||
# Create mount target directories that do NOT depend on runtime variables.
|
||||
# Targets containing {{WORKSPACE_NAME}} will be created at container
|
||||
# startup by the entrypoint, once the actual workspace/repo name is known.
|
||||
mounts = manifest.get("mounts", [])
|
||||
if mounts:
|
||||
dirs = [mount["target"] for mount in mounts]
|
||||
dir_str = " ".join(dirs)
|
||||
static_dirs = [
|
||||
mount["target"] for mount in mounts
|
||||
if "{{WORKSPACE_NAME}}" not in mount.get("target", "")
|
||||
]
|
||||
if static_dirs:
|
||||
dir_str = " ".join(static_dirs)
|
||||
lines.append(f"RUN mkdir -p {dir_str}")
|
||||
if user:
|
||||
lines.append(f"RUN chown -R {user['name']}:{user['name']} {dir_str}")
|
||||
lines.append("")
|
||||
|
||||
# Create the /workspace compatibility symlink only when the workspace name
|
||||
# is known at image-build time. Otherwise the entrypoint creates it at
|
||||
# runtime from the WORKSPACE_NAME environment variable.
|
||||
workspace_target = f"{home_dir}/{workspace_name}"
|
||||
lines.append(f"RUN mkdir -p {workspace_target}")
|
||||
if user:
|
||||
lines.append(
|
||||
f"RUN ln -sfn {workspace_target} /workspace && chown -R {user['name']}:{user['name']} {home_dir}"
|
||||
)
|
||||
else:
|
||||
lines.append(f"RUN ln -sfn {workspace_target} /workspace")
|
||||
lines.append("")
|
||||
if "{{WORKSPACE_NAME}}" not in workspace_name:
|
||||
lines.append(f"RUN mkdir -p {workspace_target}")
|
||||
if user:
|
||||
lines.append(
|
||||
f"RUN ln -sfn {workspace_target} /workspace && chown -R {user['name']}:{user['name']} {home_dir}"
|
||||
)
|
||||
else:
|
||||
lines.append(f"RUN ln -sfn {workspace_target} /workspace")
|
||||
lines.append("")
|
||||
|
||||
# Entrypoint for startup scripts
|
||||
startup_scripts = manifest.get("scripts", {}).get("startup", [])
|
||||
|
||||
@@ -292,9 +292,8 @@ class HealthMonitor:
|
||||
return
|
||||
# Skip "not_found" errors for containers that were never running
|
||||
# (e.g. still starting, or intentionally stopped/deleted).
|
||||
if (
|
||||
snapshot.container_status == "not_found"
|
||||
and (previous is None or previous.container_status != "running")
|
||||
if snapshot.container_status == "not_found" and (
|
||||
previous is None or previous.container_status != "running"
|
||||
):
|
||||
return
|
||||
category = "instance"
|
||||
|
||||
Reference in New Issue
Block a user