74 lines
1.8 KiB
Python
74 lines
1.8 KiB
Python
"""doctor: validate host prerequisites for running bot-bottle."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from ._common import PROG
|
|
|
|
|
|
def _ok(label: str, detail: str) -> None:
|
|
print(f"ok: {label}: {detail}")
|
|
|
|
|
|
def _fail(label: str, detail: str) -> None:
|
|
print(f"fail: {label}: {detail}")
|
|
|
|
|
|
def _check_python() -> bool:
|
|
version = sys.version_info
|
|
detail = f"{version.major}.{version.minor}.{version.micro}"
|
|
if version >= (3, 11):
|
|
_ok("python", detail)
|
|
return True
|
|
_fail("python", f"{detail}; need 3.11 or newer")
|
|
return False
|
|
|
|
|
|
def _check_docker() -> bool:
|
|
docker = shutil.which("docker")
|
|
if not docker:
|
|
_fail("docker", "docker command not found")
|
|
return False
|
|
try:
|
|
result = subprocess.run(
|
|
[docker, "info"],
|
|
stdout=subprocess.DEVNULL,
|
|
stderr=subprocess.DEVNULL,
|
|
check=False,
|
|
timeout=10,
|
|
)
|
|
except (OSError, subprocess.TimeoutExpired) as exc:
|
|
_fail("docker", f"daemon check failed: {exc}")
|
|
return False
|
|
if result.returncode == 0:
|
|
_ok("docker", "daemon reachable")
|
|
return True
|
|
_fail("docker", "daemon not reachable")
|
|
return False
|
|
|
|
|
|
def _check_config_dir() -> bool:
|
|
config = Path.home() / ".bot-bottle"
|
|
if config.is_dir():
|
|
_ok("config", str(config))
|
|
return True
|
|
_fail("config", f"{config} does not exist")
|
|
return False
|
|
|
|
|
|
def cmd_doctor(argv: list[str]) -> int:
|
|
parser = argparse.ArgumentParser(prog=f"{PROG} doctor", add_help=True)
|
|
parser.parse_args(argv)
|
|
|
|
checks = (
|
|
_check_python(),
|
|
_check_docker(),
|
|
_check_config_dir(),
|
|
)
|
|
return 0 if all(checks) else 1
|