Skip to content

Commit 17cfb6d

Browse files
jopemachineclaude
andcommitted
feat(BA-6041): honor MountOption.mount_destination on session creation
Session creation previously read ``permission`` and ``subpath`` from ``mount_options[uuid]`` but silently dropped ``mount_destination`` — destinations had to come from a separate ``mount_id_map``. Inference service creation, on the other hand, always honored the inline ``mount_destination`` because ``extra_mounts`` has no separate destination map on the wire. Add the fallback so the same ``MountOption`` shape works for both paths. Precedence: ``mount_id_map`` (explicit destination) > ``mount_options[uuid].mount_destination`` (per-vfolder fallback). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent f1a770c commit 17cfb6d

3 files changed

Lines changed: 60 additions & 1 deletion

File tree

changes/11610.enhance.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Session creation now honors `MountOption.mount_destination` from `mount_options[uuid]` (as a fallback after `mount_id_map`), so both session and inference service paths accept the same `MountOption` shape. Previously the field was silently ignored on the session path, forcing callers to use `mount_map` / `mount_id_map` for destinations.

src/ai/backend/manager/registry.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,16 @@ def _mount_entries_from_creation_config(
252252
perm = None
253253
raw_subpath = opts.get("subpath")
254254
subpath_value = str(raw_subpath) if raw_subpath is not None else None
255-
dst_path = mount_id_map.get(vfolder_uuid) or mount_id_map.get(raw_id)
255+
# Destination may come from either the explicit ``mount_id_map``
256+
# (preferred — atomic to the destination concept) or, as a
257+
# fallback, the per-vfolder ``mount_options[uuid].mount_destination``
258+
# so callers can express both option and destination in a single
259+
# dict — matching the inference service creation surface.
260+
dst_path = (
261+
mount_id_map.get(vfolder_uuid)
262+
or mount_id_map.get(raw_id)
263+
or opts.get("mount_destination")
264+
)
256265
entries.append(
257266
MountInfoEntry(
258267
vfolder_id=VFolderUUID(vfolder_uuid),

tests/unit/manager/test_registry.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,3 +392,52 @@ async def _hang(cache_id: str) -> AsyncIterator[AbstractEvent]:
392392
await mock_registry_obj._wait_for_session_running(
393393
session_id, mock_propagator, max_wait=0
394394
)
395+
396+
397+
class TestMountEntriesFromCreationConfig:
398+
"""Session creation honors ``mount_destination`` from both ``mount_id_map``
399+
(preferred) and ``mount_options[uuid].mount_destination`` (fallback), so the
400+
same ``MountOption`` shape that inference service creation accepts also
401+
works for sessions.
402+
"""
403+
404+
def test_mount_id_map_supplies_destination(self) -> None:
405+
vfid = uuid.uuid4()
406+
creation_config = {
407+
"mount_ids": [vfid],
408+
"mount_id_map": {vfid: "/data/dst"},
409+
"mount_options": {vfid: {"permission": "ro"}},
410+
}
411+
412+
entries = AgentRegistry._mount_entries_from_creation_config(creation_config)
413+
414+
assert len(entries) == 1
415+
assert entries[0].mount_destination == "/data/dst"
416+
417+
def test_mount_options_mount_destination_fallback(self) -> None:
418+
vfid = uuid.uuid4()
419+
creation_config = {
420+
"mount_ids": [vfid],
421+
"mount_id_map": {},
422+
"mount_options": {
423+
vfid: {"mount_destination": "/data/from-options", "permission": "ro"},
424+
},
425+
}
426+
427+
entries = AgentRegistry._mount_entries_from_creation_config(creation_config)
428+
429+
assert len(entries) == 1
430+
assert entries[0].mount_destination == "/data/from-options"
431+
432+
def test_mount_id_map_takes_precedence_over_mount_options(self) -> None:
433+
vfid = uuid.uuid4()
434+
creation_config = {
435+
"mount_ids": [vfid],
436+
"mount_id_map": {vfid: "/data/winner"},
437+
"mount_options": {vfid: {"mount_destination": "/data/loser"}},
438+
}
439+
440+
entries = AgentRegistry._mount_entries_from_creation_config(creation_config)
441+
442+
assert len(entries) == 1
443+
assert entries[0].mount_destination == "/data/winner"

0 commit comments

Comments
 (0)