Remove obsolete configurations and improve dependency handling

- Deleted `prole.cfg`, `port-mapping.cfg`, and PostgreSQL version file as part of configuration cleanup.
- Enhanced Homebrew dependency resolution with `_resolve_brew_bin` and `_augment_env_for_brew` methods to manage PATH automatically.
- Updated subprocess calls to respect augmented environment configurations.
- Added unit tests for Homebrew PATH augmentation and dependency validation logic.
This commit is contained in:
chrisfu 2026-03-08 22:09:00 -07:00
parent 8134e27ec3
commit 5fbf03eaae
5 changed files with 111 additions and 12 deletions

View File

@ -1,11 +1,3 @@
# Port mappings for Prole Tools (generated).
# Format: key: local=... remote=... ns=... svc=... address=...
argocd: local=8081 remote=80 ns=argocd svc=argocd-server address=0.0.0.0
garage: local=3900 remote=3900 ns=knoe-system svc=garage address=0.0.0.0
openbao: local=8200 remote=8200 ns=knoe-system svc=openbao address=0.0.0.0
opentofu: local=8080 remote=8080 ns=knoe-system svc=opentofu address=0.0.0.0
dashboard: local=8443 remote=443 ns=kubernetes-dashboard svc=kubernetes-dashboard-kong-proxy address=127.0.0.1
postgres: local=5432 remote=5432 ns=prole-db-chrisfu-4ac8c0 svc=prole-db-rw address=0.0.0.0
prometheus: local=9090 remote=9090 ns=monitoring svc=kps-kube-prometheus-stack-prometheus address=127.0.0.1
grafana: local=3000 remote=80 ns=monitoring svc=kps-grafana address=0.0.0.0

View File

@ -1 +0,0 @@
18

View File

@ -13,6 +13,7 @@ import json
import os
import platform
import re
import shlex
import shutil
import subprocess
import sys
@ -749,17 +750,79 @@ DEPENDENCIES = [
]
def _resolve_brew_bin() -> str | None:
"""Return an absolute path to a `brew` binary if one is found in common locations."""
candidates: list[str] = [
"/home/linuxbrew/.linuxbrew/bin/brew", # Linuxbrew (recommended)
os.path.expanduser("~/.linuxbrew/bin/brew"), # Linuxbrew (legacy single-user)
"/opt/homebrew/bin/brew", # macOS (Apple Silicon)
"/usr/local/bin/brew", # macOS (Intel)
]
for p in candidates:
try:
if os.path.isfile(p) and os.access(p, os.X_OK):
return p
except Exception:
continue
return None
def _augment_env_for_brew(env: dict | None = None) -> dict:
"""Prepend Homebrew `bin`/`sbin` to PATH when brew exists but isn't in PATH.
This keeps dependency checks and `brew install ...` invocations working in
non-interactive environments where shell init files aren't sourced.
"""
if env is None:
env = os.environ.copy()
brew_bin = _resolve_brew_bin()
if not brew_bin:
return env
try:
brew_bin_path = Path(brew_bin)
prefix = brew_bin_path.parent.parent
bin_dir = str(prefix / "bin")
sbin_dir = str(prefix / "sbin")
path_val = env.get("PATH", "") or ""
parts = [p for p in path_val.split(os.pathsep) if p]
prepend: list[str] = []
if bin_dir and bin_dir not in parts:
prepend.append(bin_dir)
try:
if os.path.isdir(sbin_dir) and sbin_dir not in parts:
prepend.append(sbin_dir)
except Exception:
# sbin is optional
pass
if prepend:
env["PATH"] = os.pathsep.join(prepend + parts)
except Exception:
return env
return env
def get_dep_info(dep: dict) -> Tuple[bool, Optional[str], Optional[str]]:
bin_name = dep.get("bin") or dep["name"]
location = None
version = None
installed = False
try:
env = _augment_env_for_brew(os.environ.copy())
if bin_name:
res = subprocess.run(
["bash", "-lc", f"command -v {bin_name}"],
["bash", "-lc", f"command -v -- {shlex.quote(bin_name)}"],
capture_output=True,
text=True,
env=env,
)
if res.returncode == 0:
location = res.stdout.strip()
@ -768,7 +831,10 @@ def get_dep_info(dep: dict) -> Tuple[bool, Optional[str], Optional[str]]:
check_cmd = dep.get("check_cmd")
if check_cmd:
res2 = subprocess.run(
["bash", "-lc", check_cmd], capture_output=True, text=True
["bash", "-lc", check_cmd],
capture_output=True,
text=True,
env=env,
)
if res2.returncode == 0:
installed = True
@ -781,7 +847,10 @@ def get_dep_info(dep: dict) -> Tuple[bool, Optional[str], Optional[str]]:
version_cmd = dep.get("version_cmd")
if version_cmd:
res3 = subprocess.run(
["bash", "-lc", version_cmd], capture_output=True, text=True
["bash", "-lc", version_cmd],
capture_output=True,
text=True,
env=env,
)
if res3.returncode == 0:
v_out = res3.stdout.strip()

View File

@ -53,9 +53,11 @@ class Milestone(ABC):
if isinstance(cmd, str):
cmd = ["bash", "-c", cmd]
import os
import subprocess
try:
env = inst_config._augment_env_for_brew(os.environ.copy())
proc = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
@ -63,6 +65,7 @@ class Milestone(ABC):
text=True,
bufsize=1,
cwd=cwd,
env=env,
)
for line in iter(proc.stdout.readline, ""):
if on_stdout:

View File

@ -270,6 +270,42 @@ def test_get_dep_info_check_cmd_success():
assert "Docker" in (ver or "")
def test_get_dep_info_prepends_linuxbrew_to_path_when_present():
dep = {
"id": "brew",
"name": "Homebrew",
"bin": "brew",
"check_cmd": "brew --version",
}
def _run(args, capture_output=False, text=False, env=None, **kwargs):
assert env is not None
path_parts = (env.get("PATH") or "").split(os.pathsep)
assert path_parts[0] == "/home/linuxbrew/.linuxbrew/bin"
assert "/home/linuxbrew/.linuxbrew/sbin" in path_parts[:2]
m = MagicMock()
cmd = " ".join(args)
if "command -v" in cmd:
m.returncode = 0
m.stdout = "/home/linuxbrew/.linuxbrew/bin/brew\n"
else:
m.returncode = 0
m.stdout = "Homebrew 5.0.0\n"
return m
with patch.dict(os.environ, {"PATH": "/usr/bin:/bin"}, clear=False), \
patch("installer.config.os.path.isfile", side_effect=lambda p: p == "/home/linuxbrew/.linuxbrew/bin/brew"), \
patch("installer.config.os.access", return_value=True), \
patch("installer.config.os.path.isdir", side_effect=lambda p: p == "/home/linuxbrew/.linuxbrew/sbin"), \
patch("installer.config.subprocess.run", side_effect=_run):
ok, loc, ver = get_dep_info(dep)
assert ok is True
assert loc == "/home/linuxbrew/.linuxbrew/bin/brew"
assert ver == "Homebrew 5.0.0"
def test_get_dep_info_version_cmd_success():
dep = {"id": "kubectl", "name": "kubectl", "bin": "kubectl",
"version_cmd": "kubectl version --client --short"}