Files
insar-management-system-v2/backend/app/services/wsl_runtime_registry.py
T

207 lines
8.0 KiB
Python

from __future__ import annotations
import os
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any, Dict, Mapping, Tuple
from ..config import settings
def _windows_path_to_wsl_mount(path: str) -> str:
text = str(path or "").strip()
if not text:
return ""
drive, tail = os.path.splitdrive(os.path.normpath(text))
if not drive:
return text.replace("\\", "/")
drive_letter = drive.rstrip(":").lower()
normalized_tail = tail.replace("\\", "/")
return f"/mnt/{drive_letter}/{normalized_tail}"
def _project_file_windows(*relative_parts: str) -> str:
return os.path.normpath(str(Path(settings.PROJECT_ROOT, *relative_parts)))
def _default_runtime_root_windows() -> str:
root = os.path.normpath(str(settings.PROJECT_ROOT))
drive, _tail = os.path.splitdrive(root)
if drive:
return os.path.join(drive + os.sep, "production_runtime")
return os.path.join(root, "runtime")
@dataclass(frozen=True)
class WslRuntimeDefinition:
runtime_id: str
engine_code: str
display_name: str
distro: str
conda_env_name: str
python_path: str
runner_path_windows: str
runner_path_wsl: str
allowed_operations: Tuple[str, ...] = ()
env_profile_path_windows: str = ""
env_profile_path_wsl: str = ""
metadata_json: Dict[str, Any] = field(default_factory=dict)
def entrypoint_argv(self) -> list[str]:
return [self.python_path, self.runner_path_wsl]
def to_dict(self) -> Dict[str, Any]:
return {
"runtime_id": self.runtime_id,
"engine_code": self.engine_code,
"display_name": self.display_name,
"distro": self.distro,
"conda_env_name": self.conda_env_name,
"python_path": self.python_path,
"runner_path_windows": self.runner_path_windows,
"runner_path_wsl": self.runner_path_wsl,
"allowed_operations": list(self.allowed_operations),
"env_profile_path_windows": self.env_profile_path_windows,
"env_profile_path_wsl": self.env_profile_path_wsl,
"metadata_json": dict(self.metadata_json or {}),
}
@dataclass(frozen=True)
class WslRuntimeRegistry:
shared_distro: str
shared_conda_env_name: str
shared_python_path: str
broker_job_root_windows: str
broker_job_root_wsl: str
runtimes: Mapping[str, WslRuntimeDefinition]
def require(self, runtime_id: str) -> WslRuntimeDefinition:
key = str(runtime_id or "").strip()
runtime = self.runtimes.get(key)
if runtime is None:
known_ids = ", ".join(sorted(self.runtimes.keys()))
raise KeyError(f"Unknown WSL runtime_id '{runtime_id}'. Known: {known_ids}")
return runtime
def to_dict(self) -> Dict[str, Any]:
return {
"shared_distro": self.shared_distro,
"shared_conda_env_name": self.shared_conda_env_name,
"shared_python_path": self.shared_python_path,
"broker_job_root_windows": self.broker_job_root_windows,
"broker_job_root_wsl": self.broker_job_root_wsl,
"runtimes": {
runtime_id: runtime.to_dict()
for runtime_id, runtime in sorted(self.runtimes.items())
},
}
def build_wsl_runtime_registry() -> WslRuntimeRegistry:
shared_distro = str(
settings.WSL_DISTRO
or settings.ISCE2_WSL_DISTRO
or settings.PYINT_WSL_DISTRO
or "Ubuntu-24.04"
).strip()
shared_conda_env = str(settings.WSL_SHARED_CONDA_ENV or "insar_wsl_v1").strip() or "insar_wsl_v1"
shared_python_path = str(
settings.WSL_SHARED_PYTHON
or settings.ISCE2_PYTHON
or settings.PYINT_WSL_PYTHON
or f"/home/administrator/miniconda3/envs/{shared_conda_env}/bin/python"
).strip()
broker_job_root_windows = os.path.normpath(
settings.WSL_BROKER_JOB_ROOT
or os.path.join(_default_runtime_root_windows(), "wsl_jobs")
)
broker_job_root_wsl = _windows_path_to_wsl_mount(broker_job_root_windows)
isce2_runner_windows = _project_file_windows("deploy", "wsl", "runners", "isce2_runner.py")
gamma_runner_windows = _project_file_windows("deploy", "wsl", "runners", "gamma_pyint_runner.py")
gamma_sbas_runner_windows = _project_file_windows("deploy", "wsl", "runners", "gamma_sbas_runner.py")
gamma_profile_windows = _project_file_windows("deploy", "wsl", "profiles", "gamma_env.sh")
runtimes = {
settings.ISCE2_RUNTIME_ID: WslRuntimeDefinition(
runtime_id=settings.ISCE2_RUNTIME_ID,
engine_code="isce2",
display_name="ISCE2 Runtime V1",
distro=shared_distro,
conda_env_name=shared_conda_env,
python_path=shared_python_path,
runner_path_windows=isce2_runner_windows,
runner_path_wsl=_windows_path_to_wsl_mount(isce2_runner_windows),
allowed_operations=("lt1_stripmap",),
metadata_json={
"shared_runtime": True,
"legacy_distro_env_var": "ISCE2_WSL_DISTRO",
"legacy_python_env_var": "ISCE2_PYTHON",
"legacy_pipeline_env_var": "ISCE2_PIPELINE_SCRIPT",
},
),
settings.PYINT_RUNTIME_ID: WslRuntimeDefinition(
runtime_id=settings.PYINT_RUNTIME_ID,
engine_code="pyint",
display_name="Gamma / PyINT Runtime V1",
distro=shared_distro,
conda_env_name=shared_conda_env,
python_path=shared_python_path,
runner_path_windows=gamma_runner_windows,
runner_path_wsl=_windows_path_to_wsl_mount(gamma_runner_windows),
allowed_operations=("lt1_gamma_dinsar", "gamma_refine"),
env_profile_path_windows=gamma_profile_windows,
env_profile_path_wsl=_windows_path_to_wsl_mount(gamma_profile_windows),
metadata_json={
"shared_runtime": True,
"legacy_distro_env_var": "PYINT_WSL_DISTRO",
"legacy_python_env_var": "PYINT_WSL_PYTHON",
"legacy_profile_env_var": "PYINT_GAMMA_ENV_SCRIPT",
},
),
settings.GAMMA_SBAS_RUNTIME_ID: WslRuntimeDefinition(
runtime_id=settings.GAMMA_SBAS_RUNTIME_ID,
engine_code="gamma",
display_name="Gamma SBAS Runtime V1",
distro=str(settings.GAMMA_SBAS_WSL_DISTRO or shared_distro).strip() or shared_distro,
conda_env_name=shared_conda_env,
python_path=str(settings.GAMMA_SBAS_PYTHON or shared_python_path).strip() or shared_python_path,
runner_path_windows=gamma_sbas_runner_windows,
runner_path_wsl=_windows_path_to_wsl_mount(gamma_sbas_runner_windows),
allowed_operations=("lt1_gamma_sbas_workflow", "lt1_gamma_sbas_step"),
env_profile_path_windows=str(settings.GAMMA_SBAS_ENV_SCRIPT or gamma_profile_windows).strip(),
env_profile_path_wsl=_windows_path_to_wsl_mount(
str(settings.GAMMA_SBAS_ENV_SCRIPT or gamma_profile_windows).strip()
),
metadata_json={
"shared_runtime": True,
"workflow_code": "sbas_insar",
"processor_code": "gamma_ipta_sbas",
"env_vars": {
"runtime_id": "GAMMA_SBAS_RUNTIME_ID",
"python": "GAMMA_SBAS_PYTHON",
"env_profile": "GAMMA_SBAS_ENV_SCRIPT",
"work_root": "GAMMA_SBAS_WORK_ROOT",
"product_root": "GAMMA_SBAS_PRODUCT_ROOT",
},
},
),
}
return WslRuntimeRegistry(
shared_distro=shared_distro,
shared_conda_env_name=shared_conda_env,
shared_python_path=shared_python_path,
broker_job_root_windows=broker_job_root_windows,
broker_job_root_wsl=broker_job_root_wsl,
runtimes=runtimes,
)
def get_wsl_runtime(runtime_id: str) -> WslRuntimeDefinition:
return wsl_runtime_registry.require(runtime_id)
wsl_runtime_registry = build_wsl_runtime_registry()