#!/usr/bin/env python3 """Shared utilities for remote Docker / SSH scripts.""" from __future__ import annotations import os import shlex from pathlib import Path def load_env_file(path: Path) -> None: if not path.exists(): return for raw_line in path.read_text(encoding="utf-8").splitlines(): line = raw_line.strip() if not line or line.startswith("#") or "=" not in line: continue key, value = line.split("=", 1) key = key.strip() value = value.strip() if not key or key in os.environ: continue if len(value) >= 2 and value[0] == value[-1] and value[0] in {"'", '"'}: value = value[1:-1] os.environ[key] = value def parse_timeout_seconds(value: str) -> float: value = value.strip().lower() if value.endswith("ms"): return float(value[:-2]) / 1000 if value.endswith("s"): return float(value[:-1]) if value.endswith("m"): return float(value[:-1]) * 60 if value.endswith("h"): return float(value[:-1]) * 3600 return float(value) def build_remote_script(container: str, workdir: str, command: str) -> str: q_container = shlex.quote(container) q_workdir = shlex.quote(workdir) inner_command = ( "set -Eeuo pipefail; " 'if [ -f "$HOME/.bashrc" ]; then source "$HOME/.bashrc"; fi; ' "if command -v direnv >/dev/null 2>&1 && [ -f .envrc ]; then " " direnv allow . >/dev/null 2>&1 || true; " ' eval "$(direnv export bash)"; ' "fi; " f"{command}" ) q_command = shlex.quote(inner_command) return f""" set -Eeuo pipefail if ! command -v docker >/dev/null 2>&1; then echo 'error: docker not found on remote host' >&2 exit 127 fi if ! docker inspect {q_container} >/dev/null 2>&1; then echo 'error: docker container not found: {container}' >&2 exit 127 fi if [ "$(docker inspect -f '{{{{.State.Running}}}}' {q_container})" != "true" ]; then echo 'error: docker container is not running: {container}' >&2 exit 127 fi docker exec -i \\ -w {q_workdir} \\ {q_container} \\ bash -lc {q_command} """.strip() def build_ssh_command( *, ssh_target: str, ssh_port: str, ssh_opts: str, ) -> list[str]: ssh_cmd = [ "ssh", "-p", ssh_port, "-o", "BatchMode=yes", "-o", "StrictHostKeyChecking=accept-new", ] if ssh_opts: ssh_cmd.extend(shlex.split(ssh_opts)) ssh_cmd.extend([ssh_target, "bash", "-s", "--"]) return ssh_cmd