#!/usr/bin/env python3 import click import yaml from pathlib import Path RUN_PATH = Path(__file__).parent DEFAULT_CONFIG = RUN_PATH / '..' / '..' / "hermes-profiles.yml" DEFAULT_COMPOSE = RUN_PATH / '..' / '..' / "compose.yml" def load_yaml(path): with open(path, "r", encoding="utf-8") as f: return yaml.safe_load(f) def write_yaml(path, data): with open(path, 'w') as yaml_file: yaml_file.write( yaml.dump(data, default_flow_style=False)) def load_compose(path=None): path = path or DEFAULT_COMPOSE return load_yaml(path) def get_profile_dir(service_name, profile): compose_path = DEFAULT_COMPOSE service = load_compose(path=compose_path)["services"].get(service_name) if not service: raise click.ClickException(f"Unknown service: {service_name}") for volume in service.get("volumes", []): if isinstance(volume, str): parts = volume.split(":") if len(parts) >= 2 and parts[1].rstrip("/") == "/opt/data": host_path = parts[0] return (compose_path.parent / host_path).resolve() / "profiles" / profile elif isinstance(volume, dict): if volume.get("target").rstrip("/") == "/opt/data": source = volume.get("source") if not source: raise click.ClickException(f"{service_name} has /opt/data mount without source") if volume.get("type") == "bind": return (compose_path.parent / source).resolve() / "profiles" / profile raise click.ClickException( f"{service_name} uses a named volume for /opt/data. " "Use a bind mount if hermesctl should write profile files directly.") raise click.ClickException(f"Could not find a host bind mount for /opt/data in service {service_name}")