sites: Inventar und Registry an echte Knoten (pve44–pve61) angepasst; ADR-0001/0002/0006 und PLAN §1.3/1.4/9 ergänzt
Inventar mit pve44–pve61 und den Ada-Rechnern gode-pc-05/06 (M4000 weiter disabled). Registry-ops auf gpu-pve44/gpu-pve48/infra laut Placement, bei den Ada-Slots entfallen pve_node und vmid (Worker-Registry v2, Task 6.4). Tests: neuer test_site_knaster_matches_real_nodes, Konsistenztest auf gpus-Liste umgestellt. ADR-Nachträge zu D1 (Variante B), D2 (eine GPU-VM pro Knoten) und D3 (Ada bleibt Windows, vorgeschlagen). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
9b2ad426da
commit
e88e0ea46b
@@ -52,6 +52,8 @@ def test_ops_labels_consistent_between_registry_and_prometheus():
|
||||
next(j for j in prom["scrape_configs"] if j["job_name"] == "vllm")["static_configs"]}
|
||||
for slot, labels in vllm.items():
|
||||
ops = reg["slots"][slot]["ops"]
|
||||
if "vmid" not in ops:
|
||||
continue # Ada-Slots ohne Proxmox-VM (D3); die Prometheus-Ziele folgen in Task 5.2
|
||||
assert ops["vmid"] == labels["vmid"] and ops["container"] == labels["container"]
|
||||
|
||||
|
||||
@@ -160,22 +162,24 @@ def test_proxmox_site_consistent_with_registry_and_prometheus():
|
||||
reg = yaml.safe_load((REPO_ROOT / "sites/knaster/registry.yaml").read_text())
|
||||
vms = site["vms"]
|
||||
for vm in vms.values():
|
||||
assert vm["gpu"] in site["pci_mappings"]
|
||||
assert site["pci_mappings"][vm["gpu"]]["node"] == vm["node"] # Mapping liegt auf dem Host der VM
|
||||
assert vm["gpus"], vm # eine GPU-VM pro Knoten mit allen Karten des Knotens (D2)
|
||||
for gpu in vm["gpus"]:
|
||||
assert gpu in site["pci_mappings"]
|
||||
assert site["pci_mappings"][gpu]["node"] == vm["node"] # Mapping liegt auf dem Host der VM
|
||||
assert vm["driver_generation"] in {"legacy", "modern"}
|
||||
gpus = [vm["gpu"] for vm in vms.values()]
|
||||
gpus = [gpu for vm in vms.values() for gpu in vm["gpus"]]
|
||||
assert len(gpus) == len(set(gpus)) # keine GPU doppelt durchgereicht
|
||||
assert set(gpus) == set(site["pci_mappings"]) # jede gemappte Karte steckt in einer VM
|
||||
by_vmid = {str(vm["vmid"]): (name, vm) for name, vm in {**vms, **site["containers"]}.items()}
|
||||
for slot, spec in reg["slots"].items():
|
||||
ops = spec.get("ops")
|
||||
if not ops:
|
||||
continue
|
||||
if not ops or "vmid" not in ops:
|
||||
continue # Ada-Slots ohne Proxmox-VM (D3, Worker-Registry v2)
|
||||
name, vm = by_vmid[ops["vmid"]]
|
||||
assert vm["node"] == ops["pve_node"], slot
|
||||
assert ops["docker_host"].startswith(name.split("-")[0]), slot
|
||||
assert ops["docker_host"] == name, slot
|
||||
# vLLM und PyTorch nur auf modernen Karten (ADR-0006)
|
||||
if spec["engine"] in {"vllm", "pytorch"} and name in vms:
|
||||
assert vm["driver_generation"] == "modern", slot
|
||||
vmids = [str(v["vmid"]) for v in vms.values()] + [str(c["vmid"]) for c in site["containers"].values()]
|
||||
assert len(vmids) == len(set(vmids))
|
||||
# vLLM nur auf modernen Karten
|
||||
for vm in vms.values():
|
||||
if vm["role"] == "gpu-vllm":
|
||||
assert vm["driver_generation"] == "modern"
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import ipaddress
|
||||
import json
|
||||
import re
|
||||
|
||||
import yaml
|
||||
|
||||
from knaster.cli import main
|
||||
from knaster.inventory.placement import load_catalog, load_nodes, plan
|
||||
@@ -45,12 +49,26 @@ def test_placement_knaster():
|
||||
assert p.free_gpus == []
|
||||
assert len(p.disabled_gpus) == 4 and all("M4000" in g for g in p.disabled_gpus)
|
||||
tts = {a.role: a for a in p.assignments if a.role.startswith("tts")}
|
||||
assert tts["tts-hq"].mode == "shared" and tts["tts-hq"].node == "pve-ada"
|
||||
assert tts["tts-hq"].mode == "shared" and tts["tts-hq"].node == by_role["gpu-flex"][0].node == "gode-pc-06"
|
||||
assert "qwen3-tts-1.7b" in tts["tts-hq"].models_fitting
|
||||
assert tts["tts-cpu"].node == by_role["infra"][0].node
|
||||
assert tts["tts-cpu"].models_fitting == ["piper-de-thorsten-medium"]
|
||||
|
||||
|
||||
def test_site_knaster_matches_real_nodes():
|
||||
"""Site-Dateien beschreiben die echten Knoten (Stand 12.10.2026), nicht mehr die Annahmen pve-ada/pve1–pve4."""
|
||||
names = {n.name for n in load_nodes(REPO_ROOT / "sites/knaster/inventory.yaml")}
|
||||
assert names == {"pve44", "pve46", "pve48", "pve52", "pve61", "gode-pc-05", "gode-pc-06"}
|
||||
text = (REPO_ROOT / "sites/knaster/proxmox.yaml").read_text(encoding="utf-8")
|
||||
old_net = ipaddress.ip_network("10.20.0.0/24")
|
||||
ips = re.findall(r"\b\d{1,3}(?:\.\d{1,3}){3}\b", text)
|
||||
assert [ip for ip in ips if ipaddress.ip_address(ip) in old_net] == []
|
||||
site = yaml.safe_load(text)
|
||||
gpu_nodes = {"pve44", "pve46", "pve48", "pve52"}
|
||||
assert {m["node"] for m in site["pci_mappings"].values()} <= gpu_nodes
|
||||
assert {vm["node"] for vm in site["vms"].values()} <= gpu_nodes
|
||||
|
||||
|
||||
def test_placement_other_cluster():
|
||||
roles, models = load_catalog(REPO_ROOT / "catalog")
|
||||
p = plan(load_nodes(REPO_ROOT / "sites/example-single-gpu/inventory.yaml"), roles, models)
|
||||
|
||||
Reference in New Issue
Block a user