sync dari sicabe-doc/deploy @ bc1a6e6

This commit is contained in:
2026-10-11 13:59:47 +07:00
parent 4ca7a9a58e
commit cbabe96061
29 changed files with 1210 additions and 650 deletions
+32 -3
View File
@@ -127,14 +127,36 @@ def apply_preset(doc: dict) -> dict:
return doc
def external_components(doc: dict) -> set[str]:
"""Komponen yang dikelola SISTEM LAIN: ditandai `components.<c>.address`.
Komponen ini TIDAK dijalankan cluster (tak masuk `placement`/`plan`); endpoint-nya
diarahkan ke alamat itu di SEMUA host (lihat generate.endpoint_lines). Berguna untuk
IAM/objek-storage milik pihak lain, termasuk di host/IP yang berbeda satu per komponen.
"""
return {n for n, s in (doc.get("components") or {}).items()
if (s.get("address") or "").strip()}
def external_address(doc: dict, service: str) -> str | None:
"""Alamat eksternal komponen (components.<svc>.address) bila ada, selain itu None."""
spec = (doc.get("components") or {}).get(service) or {}
a = (spec.get("address") or "").strip()
return a or None
def resolve(doc: dict) -> dict[str, list[str]]:
"""Komponen → daftar host (tier `engine` bisa >1 host)."""
"""Komponen → daftar host (tier `engine` bisa >1 host). Komponen EKSTERNAL
(ber-`address`) TIDAK masuk hasil — ia bukan milik host mana pun."""
hosts = doc.get("hosts") or {}
tiers_by_service = {svc: tier for tier, svcs in TIER_SERVICES.items() for svc in svcs}
explicit = {name: spec.get("host") for name, spec in (doc.get("components") or {}).items()}
external = external_components(doc)
placement: dict[str, list[str]] = {}
for service, tier in tiers_by_service.items():
if service in external:
continue # eksternal (pihak lain) → bukan milik host mana pun
if service in explicit and explicit[service]:
placement[service] = [explicit[service]]
continue
@@ -246,18 +268,23 @@ def validate(doc: dict) -> list[str]:
components = doc.get("components") or {}
for name, spec in components.items():
host = spec.get("host")
addr = (spec.get("address") or "").strip()
if host and host not in hosts:
errors.append(f"komponen '{name}': host '{host}' tidak ada di 'hosts'")
if host and addr:
errors.append(f"komponen '{name}': 'host' dan 'address' tak boleh bersamaan "
f"(host = dijalankan cluster; address = dikelola sistem lain)")
if tier_of(name) is None and name not in ("dremio",):
errors.append(f"komponen '{name}' tidak ada di taksonomi tier (TIER_SERVICES)")
# (c) tiap komponen harus bisa ditempatkan
placement = resolve(doc)
for service in (svc for svcs in TIER_SERVICES.values() for svc in svcs):
if service not in placement:
if service not in placement and not external_address(doc, service):
errors.append(
f"komponen '{service}' tidak bisa ditempatkan — tidak ada host bertier "
f"'{tier_of(service)}' dan tidak ada components.{service}.host"
f"'{tier_of(service)}', tidak ada components.{service}.host, "
f"dan bukan eksternal (components.{service}.address)"
)
# stateful: cegah pindah host tanpa migrasi (peringatan, bukan error)
@@ -331,6 +358,8 @@ def cmd_components(path: str) -> int:
doc = apply_preset(load(path))
for service, owners in sorted(resolve(doc).items()):
print(f"{service:24s} -> {','.join(owners)}")
for service in sorted(external_components(doc)):
print(f"{service:24s} -> (eksternal {external_address(doc, service)})")
return 0