Files
Mini-Nav/scripts/common.py
SikongJueluo 0ae6d757dc refactor(scripts): extract shared utilities into common module
- Move load_env_file, parse_timeout_seconds, build_remote_script, and
  build_ssh_command to scripts/common.py
- Update remote_docker_run.py to import from common module
- Improves code organization and reusability
2026-05-03 19:49:45 +08:00

111 lines
2.5 KiB
Python

#!/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