Enhance CLI options and idle-killer functionality

- Added a `--update` option to the `up` command in the CLI for forced updates during warm ACTIVE states.
- Improved the idle-killer logic with new functions to check for reusable credentials and refresh settings on existing remote credentials.
- Enhanced the `seed_civitai` function to implement caching for model jobs, optimizing the provisioning process.
- Updated the installation script for Ollama to prevent unnecessary restarts when the service configuration has not changed.
- Added diagnostics for model job caching and improved error handling in various functions.
This commit is contained in:
Leonid Pershin
2026-08-21 11:22:14 +03:00
parent d3d689052d
commit 241ada62cb
7 changed files with 300 additions and 9 deletions
+58
View File
@@ -138,6 +138,57 @@ WantedBy=timers.target
log(f"systemd timer {UNIT}.timer")
def _remote_killer_reusable(cfg: Config, host: str, server_id: str) -> bool:
"""True if VM already has matching idle-killer creds + active timer."""
cmd = (
f"sid=$(cat {DATA}/.gpu-rent-server-id 2>/dev/null | tr -d '[:space:]'); "
f"echo sid=$sid; echo want={server_id}; "
f"test -f {DATA}/.gpu-rent-killer-creds-ok && echo creds=yes || echo creds=no; "
f"test -f {DATA}/.gpu-rent-killer-armed && echo armed=yes || echo armed=no; "
f"sudo -n test -f {CREDS_REMOTE} && echo rootcreds=yes || echo rootcreds=no; "
f"echo timer=$(systemctl is-active {UNIT}.timer 2>/dev/null || echo inactive)"
)
try:
out = run_ssh(cfg, host, cmd, check=False, timeout=25)
except Exception:
return False
parsed: dict[str, str] = {}
for line in out.splitlines():
if "=" in line:
k, v = line.strip().split("=", 1)
parsed[k] = v
return (
parsed.get("sid") == server_id
and parsed.get("want") == server_id
and parsed.get("creds") == "yes"
and parsed.get("armed") == "yes"
and parsed.get("rootcreds") == "yes"
and parsed.get("timer") == "active"
)
def _refresh_killer_grace(cfg: Config, host: str) -> None:
"""Bump grace_from / idle settings on existing remote creds; clear idle-since."""
run_ssh(
cfg,
host,
"sudo -n python3 -c \""
"import json,time; from pathlib import Path; "
f"p=Path('{CREDS_REMOTE}'); d=json.loads(p.read_text()); "
f"d['idle_minutes']={int(cfg.idle_minutes)}; "
f"d['grace_minutes']={int(cfg.idle_grace_minutes)}; "
"d['grace_from']=int(time.time()); "
"p.write_text(json.dumps(d,indent=2)+chr(10)); p.chmod(0o600)"
"\" && "
f"sudo -n rm -f {DATA}/.gpu-rent-idle-since && "
f"date -u +%Y-%m-%dT%H:%M:%SZ | sudo -n tee {DATA}/.gpu-rent-killer-armed >/dev/null && "
f"sudo -n chmod 644 {DATA}/.gpu-rent-killer-armed "
f"{DATA}/.gpu-rent-killer-creds-ok {DATA}/.gpu-rent-server-id 2>/dev/null || true",
check=False,
timeout=30,
)
def arm_idle_killer(
cfg: Config,
host: str,
@@ -147,6 +198,13 @@ def arm_idle_killer(
) -> None:
if not server_id:
raise CloudError("idle-killer: нет server_id")
if _remote_killer_reusable(cfg, host, server_id):
_refresh_killer_grace(cfg, host)
log(
f"idle-killer: reuse app cred (server {server_id[:12]}…) — "
f"льгота {cfg.idle_grace_minutes} мин, потом {cfg.idle_minutes} мин → delete"
)
return
creds = create_application_credential(conn, cfg, server_id, log)
put_text(
cfg,