fix: use runuser for privilege drop and capture container stderr in logs

The container still exited immediately after the su-based fix.  can
interfere with TTY/stdin handling for interactive shells. Switch to
, which is root-only, skips PAM, and preserves file descriptors so
bash stays interactive.

Also improve container failure diagnostics:
-  now combines stdout and stderr
- This helps surface the real reason when a container exits with code 0

Quality gates:
- pytest tests/unit: 219 passed
- ruff: clean on changed files
- mypy: clean on changed files
This commit is contained in:
Developer
2026-06-15 10:41:37 +00:00
parent e35e605914
commit 1d345eba32
20 changed files with 81 additions and 34 deletions
@@ -172,6 +172,47 @@ def _merge_mounts(
return result
def _find_mount_conflicts(
profile: ConfigProfile,
resolved: ResolvedProfile,
) -> list[dict[str, Any]]:
"""Find mounts on the profile that override mounts from included profiles.
Returns a list of conflict descriptors with the target path, the included
profile that originally provided the mount, and the current profile name.
"""
conflicts = []
own_targets = {m["target"] for m in (profile.mounts or [])}
own_files = {f for m in (profile.mounts or []) for f in m.get("files", {}).keys()}
for mount in resolved.mounts.values():
if mount.target in own_targets:
# The profile itself has a mount at the same target as an included one.
conflicts.append(
{
"type": "mount_target",
"target": mount.target,
"overridden_by": profile.name,
"source": resolved.profile_name,
}
)
continue
for rel_path in mount.files:
if rel_path in own_files:
conflicts.append(
{
"type": "mount_file",
"target": mount.target,
"file": rel_path,
"overridden_by": profile.name,
"source": resolved.profile_name,
}
)
return conflicts
def _merge_git_mounts(
base: list[dict[str, Any]],
overlay: list[dict[str, Any]],