44 lines
1.2 KiB
Python
44 lines
1.2 KiB
Python
"""OS and architecture detection."""
|
|
|
|
import platform as _platform
|
|
import shutil
|
|
from dataclasses import dataclass
|
|
from typing import Optional
|
|
|
|
|
|
@dataclass
|
|
class PlatformInfo:
|
|
os: str = "linux" # "linux" or "macos"
|
|
arch: str = "amd64" # "amd64" or "arm64"
|
|
platform: str = "" # "linux-amd64", etc.
|
|
|
|
def __post_init__(self):
|
|
if not self.platform:
|
|
self.platform = f"{self.os}-{self.arch}"
|
|
|
|
|
|
_OS_MAP = {"Darwin": "macos", "Linux": "linux"}
|
|
_ARCH_MAP = {"x86_64": "amd64", "aarch64": "arm64", "arm64": "arm64"}
|
|
|
|
|
|
def detect_platform() -> PlatformInfo:
|
|
raw_os = _platform.system()
|
|
os_name = _OS_MAP.get(raw_os)
|
|
if os_name is None:
|
|
raise RuntimeError(f"Unsupported operating system: {raw_os}")
|
|
|
|
raw_arch = _platform.machine().lower()
|
|
arch = _ARCH_MAP.get(raw_arch)
|
|
if arch is None:
|
|
raise RuntimeError(f"Unsupported architecture: {raw_arch}")
|
|
|
|
return PlatformInfo(os=os_name, arch=arch, platform=f"{os_name}-{arch}")
|
|
|
|
|
|
def detect_container_runtime() -> Optional[str]:
|
|
"""Return 'docker' or 'podman' if available, else None."""
|
|
for runtime in ("docker", "podman"):
|
|
if shutil.which(runtime):
|
|
return runtime
|
|
return None
|