fix: skip read-only mounts in permission fixer and remove redundant ssh_keys manifest mount
- apply_mount_permissions now skips mounts with readonly=true to avoid 'Read-only file system' warnings on post-start chown/chmod - Removed the ssh_keys mount from the pi-agent manifest definition; instance-level SSH key mounting now handles this exclusively - Added unit test for read-only mount skipping Quality gates: pytest (15 passed)
This commit is contained in:
@@ -232,14 +232,6 @@ def upgrade() -> None:
|
|||||||
"writable": True,
|
"writable": True,
|
||||||
"owner": "user",
|
"owner": "user",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "ssh_keys",
|
|
||||||
"target": "/home/user/.ssh",
|
|
||||||
"source_type": "ssh_key",
|
|
||||||
"mode": "0700",
|
|
||||||
"file_mode": "0600",
|
|
||||||
"readonly": True,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "pi_state",
|
"name": "pi_state",
|
||||||
"target": "/tmp/.pi/agents",
|
"target": "/tmp/.pi/agents",
|
||||||
|
|||||||
@@ -1347,7 +1347,9 @@ async def start_instance(
|
|||||||
ToolDefinitionManifest, manifest_def.base_definition_id
|
ToolDefinitionManifest, manifest_def.base_definition_id
|
||||||
)
|
)
|
||||||
if base_def:
|
if base_def:
|
||||||
manifest = resolve_base(deep_merge(dict(base_def.manifest), manifest))
|
manifest = resolve_base(
|
||||||
|
deep_merge(dict(base_def.manifest), manifest)
|
||||||
|
)
|
||||||
home_dir = get_manifest_home_dir(manifest)
|
home_dir = get_manifest_home_dir(manifest)
|
||||||
user_cfg = manifest.get("user")
|
user_cfg = manifest.get("user")
|
||||||
if user_cfg:
|
if user_cfg:
|
||||||
|
|||||||
@@ -40,6 +40,17 @@ def apply_mount_permissions(
|
|||||||
"error": None,
|
"error": None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Skip read-only mounts — their permissions cannot be changed
|
||||||
|
# post-start because the bind mount is locked.
|
||||||
|
if mount.get("readonly", False):
|
||||||
|
logger.debug(
|
||||||
|
"Skipping permission fix for read-only mount %s (target=%s)",
|
||||||
|
name,
|
||||||
|
target,
|
||||||
|
)
|
||||||
|
results.append(result)
|
||||||
|
continue
|
||||||
|
|
||||||
# Skip if no permission policy defined
|
# Skip if no permission policy defined
|
||||||
if not owner and not mode and not file_mode:
|
if not owner and not mode and not file_mode:
|
||||||
results.append(result)
|
results.append(result)
|
||||||
|
|||||||
@@ -64,6 +64,24 @@ class TestApplyMountPermissions:
|
|||||||
"find /home/user/.ssh -type f -exec chmod 0600" in file_mode_call[0][1][2]
|
"find /home/user/.ssh -type f -exec chmod 0600" in file_mode_call[0][1][2]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@patch("src.services.permission_fixer._run_in_container")
|
||||||
|
def test_skips_readonly_mount(self, mock_run) -> None:
|
||||||
|
mounts = [
|
||||||
|
{
|
||||||
|
"name": "ssh_keys",
|
||||||
|
"target": "/home/user/.ssh",
|
||||||
|
"readonly": True,
|
||||||
|
"mode": "0700",
|
||||||
|
"file_mode": "0600",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
results = apply_mount_permissions("abc123", mounts)
|
||||||
|
|
||||||
|
assert len(results) == 1
|
||||||
|
assert results[0]["mount_name"] == "ssh_keys"
|
||||||
|
assert results[0]["success"] is True
|
||||||
|
mock_run.assert_not_called()
|
||||||
|
|
||||||
@patch("src.services.permission_fixer._run_in_container")
|
@patch("src.services.permission_fixer._run_in_container")
|
||||||
def test_skips_mount_with_no_policy(self, mock_run) -> None:
|
def test_skips_mount_with_no_policy(self, mock_run) -> None:
|
||||||
mounts = [
|
mounts = [
|
||||||
|
|||||||
Reference in New Issue
Block a user