Merge branch 'fix/config-mount-permissions' into dev
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
"""Tool instance service functions."""
|
"""Tool instance service functions."""
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import contextlib
|
||||||
import glob as glob_module
|
import glob as glob_module
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
@@ -71,6 +72,41 @@ from src.auth.dependencies import _get_owned_project, _get_user
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
_event_bus = InstanceEventBus()
|
_event_bus = InstanceEventBus()
|
||||||
|
|
||||||
|
|
||||||
|
def _chown_path(path: str, uid: int, gid: int) -> None:
|
||||||
|
"""Recursively chown a path, suppressing permission errors."""
|
||||||
|
try:
|
||||||
|
if os.path.isdir(path):
|
||||||
|
for root, dirs, files in os.walk(path):
|
||||||
|
for name in dirs + files:
|
||||||
|
full = os.path.join(root, name)
|
||||||
|
with contextlib.suppress(OSError):
|
||||||
|
os.chown(full, uid, gid)
|
||||||
|
with contextlib.suppress(OSError):
|
||||||
|
os.chown(path, uid, gid)
|
||||||
|
except Exception as exc:
|
||||||
|
logger.warning("Failed to chown %s to %s:%s: %s", path, uid, gid, exc)
|
||||||
|
|
||||||
|
|
||||||
|
def _chown_staged_mounts(
|
||||||
|
extra_volumes: list[dict],
|
||||||
|
instance_dir: str,
|
||||||
|
uid: int,
|
||||||
|
gid: int,
|
||||||
|
) -> None:
|
||||||
|
"""Recursively chown staged mount sources to the container user.
|
||||||
|
|
||||||
|
Config-profile mounts, git mounts, and SSH key mounts are staged under
|
||||||
|
instance_dir by the API process (root). Without this, the container
|
||||||
|
user cannot write into bind-mounted directories such as ~/.config.
|
||||||
|
"""
|
||||||
|
for vol in extra_volumes:
|
||||||
|
source = vol.get("source", "")
|
||||||
|
if not source or not source.startswith(instance_dir):
|
||||||
|
continue
|
||||||
|
_chown_path(source, uid, gid)
|
||||||
|
|
||||||
|
|
||||||
async def resolve_git_mounts(
|
async def resolve_git_mounts(
|
||||||
session: AsyncSession,
|
session: AsyncSession,
|
||||||
resolved: ResolvedProfile,
|
resolved: ResolvedProfile,
|
||||||
@@ -1308,6 +1344,10 @@ async def start_tool_instance(
|
|||||||
ssh_target,
|
ssh_target,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Ensure staged bind-mount sources are owned by the container user so
|
||||||
|
# directories like ~/.config remain writable inside the container.
|
||||||
|
_chown_staged_mounts(extra_volumes, instance_dir, container_uid, container_gid)
|
||||||
|
|
||||||
# ── MANIFEST-BASED FLOW ──────────────────────────────────────
|
# ── MANIFEST-BASED FLOW ──────────────────────────────────────
|
||||||
resolved_manifest = None
|
resolved_manifest = None
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user