- Updated version number in pyproject.toml and __init__.py to 0.2.0. - Revised README.md to reflect the current state of the project, including usage instructions and setup steps. - Improved CLI documentation in cli.md, adding details about new commands and their functionalities. - Enhanced the quick start section in README.md for better clarity on initial setup. - Updated local folder documentation to clarify file handling and commands. - Added a new command for listing GPU flavors and improved error handling in the CLI. - Implemented a watchdog feature in the tunnel to manage server states effectively.
64 lines
2.1 KiB
Python
64 lines
2.1 KiB
Python
"""Boot volume snapshot after first Idle (once)."""
|
||
|
||
from __future__ import annotations
|
||
|
||
import time
|
||
from collections.abc import Callable
|
||
from typing import Any
|
||
|
||
from gpu_rent.config import Config
|
||
from gpu_rent.errors import CloudError
|
||
from gpu_rent.os_client import find_snapshot_by_name
|
||
|
||
Log = Callable[[str], None]
|
||
|
||
|
||
def ensure_boot_snapshot(
|
||
conn,
|
||
*,
|
||
boot_volume_id: str | None,
|
||
cfg: Config,
|
||
log: Log,
|
||
) -> Any | None:
|
||
"""Create named boot snapshot if missing. Safe to call every up."""
|
||
name = cfg.boot_snapshot_name
|
||
existing = find_snapshot_by_name(conn, name)
|
||
if existing:
|
||
log(f"boot snapshot уже есть: {name}")
|
||
return existing
|
||
if not boot_volume_id:
|
||
log("boot snapshot пропущен: нет boot_volume_id")
|
||
return None
|
||
log(f"создаю snapshot {name} с boot volume {boot_volume_id} (force)…")
|
||
try:
|
||
snap = conn.block_storage.create_snapshot(
|
||
volume_id=boot_volume_id,
|
||
name=name,
|
||
description="gpu-rent first Idle; reuse for next boot",
|
||
force=True,
|
||
)
|
||
except TypeError:
|
||
try:
|
||
snap = conn.block_storage.create_snapshot(
|
||
volume_id=boot_volume_id,
|
||
name=name,
|
||
force=True,
|
||
)
|
||
except Exception as exc:
|
||
raise CloudError(f"snapshot boot: {exc}") from exc
|
||
except Exception as exc:
|
||
raise CloudError(f"snapshot boot: {exc}") from exc
|
||
|
||
snap_id = getattr(snap, "id", None)
|
||
deadline = time.time() + 1800
|
||
while time.time() < deadline:
|
||
cur = conn.block_storage.get_snapshot(snap_id)
|
||
status = (getattr(cur, "status", None) or "").lower()
|
||
if status == "available":
|
||
log(f"snapshot {name} ready ({snap_id})")
|
||
return cur
|
||
if status in {"error", "error_deleting"}:
|
||
raise CloudError(f"snapshot {name} в статусе {status}")
|
||
time.sleep(8)
|
||
raise CloudError(f"snapshot {name} не стал available за 30 мин")
|