Fix compose path: resolve real project path via list_projects API

_find_compose_path was constructing {compose_base_path}/{project_name}
which didn't match the actual NAS path (e.g. /volume1/docker/frostiq/jenkins).
Now calls _find_project() first and uses project["path"] as the base
directory, with the old constructed path as a fallback only.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-13 15:55:34 +02:00
parent e13324e10c
commit dac215840e
+24 -6
View File
@@ -16,6 +16,8 @@ if TYPE_CHECKING:
from mcp_synology_container.config import AppConfig from mcp_synology_container.config import AppConfig
from mcp_synology_container.dsm_client import DsmClient from mcp_synology_container.dsm_client import DsmClient
from mcp_synology_container.modules.projects import _find_project
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# Recognized compose file names (in priority order) # Recognized compose file names (in priority order)
@@ -42,10 +44,15 @@ def register_compose(mcp: FastMCP, config: AppConfig, client: DsmClient) -> None
""" """
path = await _find_compose_path(client, config, project_name) path = await _find_compose_path(client, config, project_name)
if path is None: if path is None:
project = await _find_project(client, project_name)
searched = (
project.get("path", f"{config.compose_base_path}/{project_name}")
if project
else f"{config.compose_base_path}/{project_name}"
)
return ( return (
f"No compose file found for project '{project_name}'.\n" f"No compose file found for project '{project_name}'.\n"
f"Looked in {config.compose_base_path}/{project_name}/ for: " f"Looked in {searched}/ for: " + ", ".join(_COMPOSE_FILENAMES)
+ ", ".join(_COMPOSE_FILENAMES)
) )
try: try:
@@ -295,22 +302,33 @@ async def _find_compose_path(
) -> str | None: ) -> str | None:
"""Find the compose file path for a project. """Find the compose file path for a project.
Tries each recognized filename under {compose_base_path}/{project_name}/. Resolves the project's real directory via SYNO.Docker.Project list,
then probes each recognised filename under that directory.
Falls back to {compose_base_path}/{project_name} when the project
cannot be found in Container Manager.
Args: Args:
client: DsmClient instance. client: DsmClient instance.
config: AppConfig with compose_base_path. config: AppConfig with compose_base_path (used as fallback).
project_name: Project name. project_name: Project name.
Returns: Returns:
Full path to the compose file if found, None otherwise. Full path to the compose file if found, None otherwise.
""" """
base = f"{config.compose_base_path}/{project_name}" project = await _find_project(client, project_name)
if project is not None:
base = project.get("path", "").rstrip("/")
else:
base = f"{config.compose_base_path}/{project_name}"
logger.debug(
"Project '%s' not found via API, falling back to base path: %s",
project_name,
base,
)
for filename in _COMPOSE_FILENAMES: for filename in _COMPOSE_FILENAMES:
path = f"{base}/{filename}" path = f"{base}/{filename}"
try: try:
# Try to list the file; if it exists, return the path
await client.request( await client.request(
"SYNO.FileStation.Info", "SYNO.FileStation.Info",
"get", "get",