prole/installer/workstation.py
chrisfu 120c9c2567 feat(installer): unified welcome flow, reliable footer gating; externalize install scripts; add Ollama; centralize canvas helpers
- Startup/UI: open main window with background; run dependency check on-canvas; hide footer during scan; reveal Next after debounce; add 600ms refresh and 9s failsafe; fixed background image replacement without clearing content.

- Canvas helpers: route all canvas calls via installer/screen.py; consistent status drawing.

- Installer script externalization: per-dependency templates + validator; compose install_dependencies.sh.

- Dependencies: add Ollama and template; install order: brew → ollama → k3d → kubectl → helm → krew → cmctl → plugins.

- Cleanup: removed deprecated splash and unused code paths.
2025-12-04 14:01:28 -08:00

71 lines
2.5 KiB
Python

"""
Workstation (Docker) build helpers for the Prole installer (root-level).
Compose a deterministic Docker build command and derive the image tag version
from the workstation/Dockerfile. Includes helpers to check if the current
image tag already exists locally to avoid redundant builds.
"""
from __future__ import annotations
from pathlib import Path
import re
import subprocess
from . import config as cfg
def get_workstation_version(project_root: Path) -> str:
"""Parse the workstation Dockerfile for a version.
Looks for one of the following (first match wins):
- ARG WORKSTATION_VERSION=1.2.3
- LABEL org.opencontainers.image.version="1.2.3"
Falls back to "0.1.0" if none found.
"""
ws = Path(project_root) / "workstation" / "Dockerfile"
default_ver = "0.1.0"
try:
text = ws.read_text(encoding="utf-8")
except Exception:
return default_ver
# ARG pattern
m = re.search(r"^\s*ARG\s+WORKSTATION_VERSION\s*=\s*([\w\.-]+)\s*$", text, re.MULTILINE)
if m:
return m.group(1)
# LABEL pattern
m2 = re.search(r"org\.opencontainers\.image\.version\s*=\s*\"?([\w\.-]+)\"?", text)
if m2:
return m2.group(1)
return default_ver
def get_docker_build_command(project_root: Path) -> str:
"""Return the canonical Docker build command for the workstation image.
docker build -t prole-workstation:<version> .
Includes platform flags for Apple Silicon when appropriate.
"""
ws = Path(project_root) / "workstation"
version = get_workstation_version(project_root)
platform_args = cfg.get_docker_build_platform_args()
plat = (" ".join(platform_args) + " ") if platform_args else ""
return f"cd \"{ws}\" && docker build {plat}-t prole-workstation:{version} ."
def is_workstation_image_current(project_root: Path) -> bool:
"""Return True if the local Docker image prole-workstation:<version> exists.
This checks only for the presence of the tag. It does not verify whether
the image is up-to-date with the Dockerfile. For most installer scenarios,
skipping a rebuild when the tag exists is sufficient and saves time.
"""
version = get_workstation_version(project_root)
try:
r = subprocess.run(
["bash", "-lc", f"docker image inspect prole-workstation:{version} >/dev/null 2>&1"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
return r.returncode == 0
except Exception:
return False