fix(config-profiles): preserve bound file inodes
Overwrite individually bind-mounted profile files in place so editor saves remain visible to running containers.
This commit is contained in:
@@ -515,7 +515,13 @@ def apply_resolved_profile(
|
||||
files_dir = profile_dir / "files"
|
||||
mounts_dir = profile_dir / "mounts"
|
||||
|
||||
def write_canonical_file(root: Path, relative_path: str, content: str) -> Path | None:
|
||||
def write_canonical_file(
|
||||
root: Path,
|
||||
relative_path: str,
|
||||
content: str,
|
||||
*,
|
||||
preserve_inode: bool = False,
|
||||
) -> Path | None:
|
||||
path = root / relative_path
|
||||
try:
|
||||
path.resolve().relative_to(root.resolve())
|
||||
@@ -523,6 +529,12 @@ def apply_resolved_profile(
|
||||
logger.warning("Profile file path escapes canonical storage: %s", relative_path)
|
||||
return None
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
if preserve_inode and path.is_file():
|
||||
# A file bind mount follows its inode, not its directory entry.
|
||||
# Replacing this path would leave a running container attached to
|
||||
# the old inode, so overwrite the existing file in place.
|
||||
path.write_text(content, encoding="utf-8")
|
||||
return path
|
||||
with tempfile.NamedTemporaryFile(
|
||||
mode="w", encoding="utf-8", dir=path.parent, delete=False
|
||||
) as temporary_file:
|
||||
@@ -534,7 +546,9 @@ def apply_resolved_profile(
|
||||
# Top-level profile files are individual bind mounts under the working
|
||||
# directory. They therefore cannot mask the workspace directory itself.
|
||||
for file_path, content in resolved.files.items():
|
||||
canonical_file = write_canonical_file(files_dir, file_path, content)
|
||||
canonical_file = write_canonical_file(
|
||||
files_dir, file_path, content, preserve_inode=True
|
||||
)
|
||||
if canonical_file is None:
|
||||
continue
|
||||
volume_mounts.append(
|
||||
|
||||
Reference in New Issue
Block a user