b1f9e87d6a
mcp-infra-server를 gpu-services/infra/로 통합. core/ 순수 로직은 Agent/NanoClaude에서도 직접 import 가능. 도구: docker_status, docker_logs, service_health, disk_usage, tailscale_status, ollama_models, mlx_models. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
74 lines
2.0 KiB
Python
74 lines
2.0 KiB
Python
"""Host configuration and tool-host validation.
|
|
|
|
All host IPs are Tailscale IPs (except nas-company which also works via Tailscale).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from dataclasses import dataclass, field
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv()
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class HostConfig:
|
|
ip: str
|
|
user: str
|
|
auth: str # "key" | "password"
|
|
docker_path: str = "docker"
|
|
needs_sudo: bool = False
|
|
password: str | None = None # only for auth="password"
|
|
|
|
|
|
HOSTS: dict[str, HostConfig] = {
|
|
"gpu": HostConfig(
|
|
ip="100.111.160.84",
|
|
user="hyungi",
|
|
auth="key",
|
|
),
|
|
"macmini": HostConfig(
|
|
ip="100.76.254.116",
|
|
user="hyungi",
|
|
auth="key",
|
|
),
|
|
"nas-company": HostConfig(
|
|
ip="100.71.132.52",
|
|
user="hyungi",
|
|
auth="password",
|
|
docker_path="/usr/local/bin/docker",
|
|
needs_sudo=True,
|
|
password=os.getenv("NAS_COMPANY_PASSWORD"),
|
|
),
|
|
}
|
|
|
|
# Per-tool allowed hosts — invalid host → immediate error
|
|
TOOL_HOST_MAP: dict[str, list[str]] = {
|
|
"docker_status": ["gpu", "nas-company"],
|
|
"docker_logs": ["gpu", "nas-company"],
|
|
"disk_usage": ["gpu", "macmini", "nas-company"],
|
|
"ollama_models": ["gpu", "macmini"],
|
|
"mlx_models": ["macmini"],
|
|
}
|
|
|
|
# SSH timeouts
|
|
SSH_TIMEOUT = 5 # connection timeout (seconds)
|
|
CMD_TIMEOUT = 10 # command execution timeout (seconds)
|
|
MAX_RETRIES = 1 # retry once on failure
|
|
|
|
|
|
def validate_host(tool: str, host: str) -> HostConfig:
|
|
"""Validate host is allowed for tool and return config. Raises ValueError if invalid."""
|
|
allowed = TOOL_HOST_MAP.get(tool)
|
|
if allowed and host not in allowed:
|
|
raise ValueError(
|
|
f"'{host}'는 {tool}에서 지원하지 않습니다. 허용: {', '.join(allowed)}"
|
|
)
|
|
config = HOSTS.get(host)
|
|
if not config:
|
|
raise ValueError(
|
|
f"알 수 없는 호스트: '{host}'. 허용: {', '.join(HOSTS.keys())}"
|
|
)
|
|
return config
|