iris-server-hosts: gpu-hosts zu allgemeinen Hosts weiterentwickeln, SSH-Felder aus den Plugin-Konfigurationen entfernen #115

Closed
opened 2026-10-16 22:36:00 +00:00 by alf · 33 comments
Owner

Warum

Plugins, die einen Rechner brauchen, trugen in ihren eigenen Einstellungen SSH-Felder („Anderer Rechner (SSH-Ziel …)“, „Erweitert: SSH-Schlüssel“ in whisper, heartmula, marker, qwen-tts-linux, comfyui-bridge; comfyui-bridge/python/comfyui_client.py las ein SSH-Ziel aus der Plugin-Konfiguration). gpu-hosts verwaltete Hosts, den gemeinsamen Schlüssel und die Einrichtung bereits, war aber nach der GPU benannt, obwohl immer mehr Plugins nur einen Rechner brauchen (geplant: iris-forgejo, iris-plugins#113; ein Nextcloud-Plugin, das komplette Nextcloud-Server einrichtet).

Spezifikation

Hosts statt GPU-Hosts. gpu-hosts heißt iris-server-hosts und führt schlicht „Hosts“. „Dieser Iris-Server“ (self) ist immer ein Host. Adresse und Schlüssel eines Hosts stehen genau einmal dort (host-add, host-probe, Einrichtung), in keiner Plugin-Konfiguration, auch nicht unter „Erweitert“.

Zugang zu Hosts. SSH-Adresse und Schlüssel werden nur in diesem Plugin konfiguriert, auch der Zugang zu „Dieser Iris-Server“ (Fenster: Passwort einmalig, Befehl self-authorize).

Fähigkeiten. Beim Prüfen erkannt und im Host-Eintrag gespeichert: GPU (mit VRAM und Treiber), Docker, Betriebssystem/Architektur. Die GPU ist eine erkannte Eigenschaft wie jede andere, nicht die Art des Eintrags. Ein Host ohne checked_at gilt als ungeprüft und wird beim Öffnen der Verwaltung einmal eingelesen.

Laufzeit. Ein Plugin speichert nur die Host-Kennung (host_id, self), nie Adresse oder Schlüssel. Der Server löst die Kennung auf (SSH-Ziel plus Schlüssel), byte-genau auf Mac- und Linux-Server; Plugins ohne eigene Server-Route bekommen eine Resolver-Route. Ein Plugin-Skript liest nie die Datei eines fremden Plugins. Die Verknüpfungs-Maschinerie von gpu-hosts (Nachziehen, Abweichungen, GPU_PLUGINS-Tabelle) entfällt.

Anforderungen. Das Manifest-Feld host_capabilities nennt, was ein Plugin von seinem Rechner verlangt; der Server prüft bei Picker, Installation und Anwenden. Der Picker-Parameter needs=… ergänzt es je Aufruf, lockert es nie (ComfyUI: GPU und Docker). Der Picker liefert GET /hosts/targets.

Installations-Sperre. Ein Plugin lässt sich nur installieren, wenn mindestens ein Rechner alle seine Anforderungen erfüllt (nicht jede Anforderung irgendein Rechner). Kein passender Host: nicht installierbar, keine Leiche im System. Dieselbe reine Funktion auf Plugin-Kern, Linux-Server und Mac-Seite; der Restore-Bericht führt gesperrte Plugins als blocked.

Harter Schnitt, beide Server gleichzeitig. ID iris-server-hosts, Route GET /hosts/targets, Store iris_server_hosts.json, Python-Module, Tests, Mac-Seite (IrisHosts/, GPUHost/), Store-Material, Doku, PLAN.md, Gedächtnis. Keine Übergangszeit für alte Aufrufer, keine automatische Migration.

Die fünf GPU-Plugins (heartmula, whisper, marker, qwen-tts-linux, comfyui-bridge) werden ausgeschaltet, ihre Dateien bleiben. Ihre ssh_target-Felder sind später die Quelle für die Umstellung, je Plugin in einem eigenen Issue (Picker mit needs, host_id statt ssh_target, Panel ohne SSH-Felder).

Nicht in diesem Issue: der Check-Knopf auf der Iris-Seite (prüft alle Plugins gegen ihre Hosts: da, ansprechbar, verbindbar; bei Ausfall Plugins markiert und gesperrt) und die Umstellung der einzelnen Plugins: eigene Issues.

Stand

  • Kern: Host-Liste mit Fähigkeiten, Sonde, GET /hosts/targets mit needs, host_capabilities, Auflösung host_id → Ziel, Installations-Sperre (Plugin-Repo, Linux-Server, Mac-Seite)
  • Mac-Seite: Picker-Route, iris_server_hosts.json, Host-Kern in Iris/IrisHosts/
  • GPU-Plugins auf dem Mac ausgeschaltet (Dateien bleiben)
  • Verwaltungsfenster: ungeprüfte Hosts werden eingelesen, Anzeige „noch nicht geprüft“
  • GET /hosts/targets live gegen die Mac-App geprüft (self seit Iris PR #84 auch in der Mac-Route)
  • Restflächen umbenennen: scripts/build-gpu-host-bundle.sh, Referenz-Eintrag für IrisHosts/, Store-Material, Gedächtnis, Mutationstests
  • Veröffentlichen, nur auf Alfs Wort

Betroffen: die fünf genannten Plugins, iris-server-hosts selbst, Linux- und Mac-Server. Verwandt: iris-plugins#113 (iris-forgejo). Verlauf mit PRs und Messungen steht in den Kommentaren.

## Warum Plugins, die einen Rechner brauchen, trugen in ihren eigenen Einstellungen SSH-Felder („Anderer Rechner (SSH-Ziel …)“, „Erweitert: SSH-Schlüssel“ in `whisper`, `heartmula`, `marker`, `qwen-tts-linux`, `comfyui-bridge`; `comfyui-bridge/python/comfyui_client.py` las ein SSH-Ziel aus der Plugin-Konfiguration). `gpu-hosts` verwaltete Hosts, den gemeinsamen Schlüssel und die Einrichtung bereits, war aber nach der GPU benannt, obwohl immer mehr Plugins nur einen Rechner brauchen (geplant: `iris-forgejo`, iris-plugins#113; ein Nextcloud-Plugin, das komplette Nextcloud-Server einrichtet). ## Spezifikation **Hosts statt GPU-Hosts.** `gpu-hosts` heißt `iris-server-hosts` und führt schlicht „Hosts“. „Dieser Iris-Server“ (`self`) ist immer ein Host. Adresse und Schlüssel eines Hosts stehen genau einmal dort (`host-add`, `host-probe`, Einrichtung), in keiner Plugin-Konfiguration, auch nicht unter „Erweitert“. **Zugang zu Hosts.** SSH-Adresse und Schlüssel werden nur in diesem Plugin konfiguriert, auch der Zugang zu „Dieser Iris-Server“ (Fenster: Passwort einmalig, Befehl `self-authorize`). **Fähigkeiten.** Beim Prüfen erkannt und im Host-Eintrag gespeichert: GPU (mit VRAM und Treiber), Docker, Betriebssystem/Architektur. Die GPU ist eine erkannte Eigenschaft wie jede andere, nicht die Art des Eintrags. Ein Host ohne `checked_at` gilt als ungeprüft und wird beim Öffnen der Verwaltung einmal eingelesen. **Laufzeit.** Ein Plugin speichert nur die Host-Kennung (`host_id`, `self`), nie Adresse oder Schlüssel. Der Server löst die Kennung auf (SSH-Ziel plus Schlüssel), byte-genau auf Mac- und Linux-Server; Plugins ohne eigene Server-Route bekommen eine Resolver-Route. Ein Plugin-Skript liest nie die Datei eines fremden Plugins. Die Verknüpfungs-Maschinerie von `gpu-hosts` (Nachziehen, Abweichungen, `GPU_PLUGINS`-Tabelle) entfällt. **Anforderungen.** Das Manifest-Feld `host_capabilities` nennt, was ein Plugin von seinem Rechner verlangt; der Server prüft bei Picker, Installation und Anwenden. Der Picker-Parameter `needs=…` ergänzt es je Aufruf, lockert es nie (ComfyUI: GPU und Docker). Der Picker liefert `GET /hosts/targets`. **Installations-Sperre.** Ein Plugin lässt sich nur installieren, wenn mindestens ein Rechner alle seine Anforderungen erfüllt (nicht jede Anforderung irgendein Rechner). Kein passender Host: nicht installierbar, keine Leiche im System. Dieselbe reine Funktion auf Plugin-Kern, Linux-Server und Mac-Seite; der Restore-Bericht führt gesperrte Plugins als `blocked`. **Harter Schnitt, beide Server gleichzeitig.** ID `iris-server-hosts`, Route `GET /hosts/targets`, Store `iris_server_hosts.json`, Python-Module, Tests, Mac-Seite (`IrisHosts/`, `GPUHost/`), Store-Material, Doku, PLAN.md, Gedächtnis. Keine Übergangszeit für alte Aufrufer, keine automatische Migration. **Die fünf GPU-Plugins** (heartmula, whisper, marker, qwen-tts-linux, comfyui-bridge) werden ausgeschaltet, ihre Dateien bleiben. Ihre `ssh_target`-Felder sind später die Quelle für die Umstellung, je Plugin in einem eigenen Issue (Picker mit `needs`, `host_id` statt `ssh_target`, Panel ohne SSH-Felder). **Nicht in diesem Issue:** der Check-Knopf auf der Iris-Seite (prüft alle Plugins gegen ihre Hosts: da, ansprechbar, verbindbar; bei Ausfall Plugins markiert und gesperrt) und die Umstellung der einzelnen Plugins: eigene Issues. ## Stand - [x] Kern: Host-Liste mit Fähigkeiten, Sonde, `GET /hosts/targets` mit `needs`, `host_capabilities`, Auflösung `host_id` → Ziel, Installations-Sperre (Plugin-Repo, Linux-Server, Mac-Seite) - [x] Mac-Seite: Picker-Route, `iris_server_hosts.json`, Host-Kern in `Iris/IrisHosts/` - [x] GPU-Plugins auf dem Mac ausgeschaltet (Dateien bleiben) - [x] Verwaltungsfenster: ungeprüfte Hosts werden eingelesen, Anzeige „noch nicht geprüft“ - [x] `GET /hosts/targets` live gegen die Mac-App geprüft (`self` seit Iris PR #84 auch in der Mac-Route) - [ ] Restflächen umbenennen: `scripts/build-gpu-host-bundle.sh`, Referenz-Eintrag für `IrisHosts/`, Store-Material, Gedächtnis, Mutationstests - [ ] Veröffentlichen, nur auf Alfs Wort Betroffen: die fünf genannten Plugins, `iris-server-hosts` selbst, Linux- und Mac-Server. Verwandt: iris-plugins#113 (`iris-forgejo`). Verlauf mit PRs und Messungen steht in den Kommentaren.
alf changed title from SSH-Host und Schlüssel nur noch in gpu-hosts: Plugin-Konfigurationen verlieren die SSH-Felder to iris-server-hosts: gpu-hosts zu allgemeinen Hosts weiterentwickeln, SSH-Felder aus den Plugin-Konfigurationen entfernen 2026-10-16 22:49:51 +00:00
Author
Owner

Präzisierung (2026-10-17)

Auf Alfs Wunsch zugeschnitten: gpu-hosts wird zu iris-server-hosts (allgemeine „Hosts“, GPU ist eine erkannte Eigenschaft). Weitere Plugins bauen darauf auf, zuerst iris-forgejo (#113), danach ein Nextcloud-Einrichtungs-Plugin, das einen Host braucht. Titel und Beschreibung entsprechend angepasst; die Frage der Umbenennung steht neu bei „Noch zu entscheiden“.

## Präzisierung (2026-10-17) Auf Alfs Wunsch zugeschnitten: `gpu-hosts` wird zu `iris-server-hosts` (allgemeine „Hosts“, GPU ist eine erkannte Eigenschaft). Weitere Plugins bauen darauf auf, zuerst `iris-forgejo` (#113), danach ein Nextcloud-Einrichtungs-Plugin, das einen Host braucht. Titel und Beschreibung entsprechend angepasst; die Frage der Umbenennung steht neu bei „Noch zu entscheiden“.
Author
Owner

PR #117 gemergt: docs(iris-forgejo): Hosts über iris-server-hosts (bisher gpu-hosts) (#113, #115)
#117

Commits:

  • docs(iris-forgejo): Hosts über iris-server-hosts (bisher gpu-hosts) (#113, #115)
PR #117 gemergt: docs(iris-forgejo): Hosts über iris-server-hosts (bisher gpu-hosts) (#113, #115) https://forgejo.lewerken.duckdns.org/iris/iris-plugins/pulls/117 Commits: - docs(iris-forgejo): Hosts über iris-server-hosts (bisher gpu-hosts) (#113, #115)
Author
Owner

Entscheidungen (grill-me, 2026-10-18)

Die vier offenen Punkte sind entschieden; die Beschreibung bleibt die Spezifikation.

Laufzeit — wie der Host ins Plugin kommt

  • Ein Plugin speichert nur die Host-Kennung (host_id, self = „Dieser Iris-Server") — nie Adresse, nie Schlüssel. Die Verknüpfungs-Maschinerie von gpu-hosts (Nachziehen, Abweichungen anzeigen, angleichen, GPU_PLUGINS-Tabelle) fällt komplett weg.
  • Der Server löst die Kennung auf (SSH-Ziel plus Schlüssel), byte-genau auf Mac- und Linux-Server; Plugins ohne eigene Server-Route bekommen eine Resolver-Route. Ein Plugin-Skript liest nie die Datei eines fremden Plugins.
  • Fähigkeiten, beim Prüfen erkannt, im Host-Eintrag gespeichert: GPU (mit VRAM), Docker, Betriebssystem/Architektur. „Dieser Iris-Server" ist immer ein Host; die GPU ist eine erkannte Eigenschaft wie jede andere, nicht die Art des Eintrags.
  • Anforderung im Manifest (Feld host_capabilities): der Server prüft bei Picker, Installation und Anwenden. Der Picker-Parameter (needs=…) verfeinert nur je Aufruf (ComfyUI: GPU und Docker).
  • Installations-Sperre: Kein passender Host → das Plugin lässt sich nicht installieren (keine Leiche im System). Künftig prüft ein Check-Knopf in Iris alle Plugins gegen ihre Hosts (da, ansprechbar, verbindbar); Ausfall → Plugins fett markiert mit Begründung, gesperrt. Der Knopf gehört auf die Iris-Seite (eigenes Issue), nicht in dieses Plugin.

Umfang dieses Issues

  • Keine automatische Migration. Die fünf GPU-Plugins (heartmula, whisper, marker, qwen-tts-linux, comfyui-bridge) werden ausgeschaltet, ihre Dateien bleiben — die ssh_target-Felder sind später die Quelle für die Anpassung je Plugin in einem eigenen Issue, eines nach dem anderen, wenn die Basis steht. Der SSH-Zugang pro Host (Adresse, Schlüssel) wird genau einmal geführt: bei host-add/host-probe/setup durch iris-server-hosts; Plugins speichern danach weder Host-Adresse noch Keys.
  • Harter Schnitt, keine Übergangszeit für alte Aufrufer: ID iris-server-hosts, Route GET /hosts/targets, Store iris_server_hosts.json, Python-Module, Tests, Mac-Seite (GPUHostRegistry.swift, IrisRemoteServer.swift, GPUHostPluginKey.swift), Store-Material, Doku, PLAN.md, Gedächtnis — alles im selben Zug, beide Server gleichzeitig.

Bauabschnitte

  1. Kern: Host-Liste mit Fähigkeiten-Feldern, Sonde (nvidia-smi, docker info, uname -s -m), Picker-Route GET /hosts/targets mit needs-Filter, Manifest-Feld host_capabilities, Auflösung host_id → SSH-Ziel plus Schlüssel (beide Server), Installationsprüfung.
  2. Mac-Seite im selben Zug (Picker-Route, gpu_hosts.json → iris_server_hosts.json, GPUHost-Dateien).
  3. GPU-Plugins deaktivieren (HeartMuLa, Whisper, Marker, Qwen-TTS Linux, ComfyUI Bridge), Konfigurationsdateien bleiben unangetastet.
  4. Umbenennung der Restflächen (Store-Material, Doku, PLAN.md, Gedächtnis), Tests und Mutationstests, Veröffentlichen nur auf Alfs Wort.

Folgt in separaten Issues: Plugin für Plugin auf das neue System umstellen (Picker mit needs, host_id statt ssh_target, Panel ohne SSH-Felder); Iris-Seite Check-Knopf.

## Entscheidungen (grill-me, 2026-10-18) Die vier offenen Punkte sind entschieden; die Beschreibung bleibt die Spezifikation. **Laufzeit — wie der Host ins Plugin kommt** - Ein Plugin speichert nur die **Host-Kennung** (host_id, self = „Dieser Iris-Server") — nie Adresse, nie Schlüssel. Die Verknüpfungs-Maschinerie von gpu-hosts (Nachziehen, Abweichungen anzeigen, angleichen, GPU_PLUGINS-Tabelle) fällt komplett weg. - **Der Server löst die Kennung auf** (SSH-Ziel plus Schlüssel), byte-genau auf Mac- und Linux-Server; Plugins ohne eigene Server-Route bekommen eine Resolver-Route. Ein Plugin-Skript liest nie die Datei eines fremden Plugins. - **Fähigkeiten, beim Prüfen erkannt, im Host-Eintrag gespeichert:** GPU (mit VRAM), Docker, Betriebssystem/Architektur. „Dieser Iris-Server" ist immer ein Host; die GPU ist eine erkannte Eigenschaft wie jede andere, nicht die Art des Eintrags. - **Anforderung im Manifest** (Feld host_capabilities): der Server prüft bei Picker, Installation und Anwenden. Der Picker-Parameter (needs=…) verfeinert nur je Aufruf (ComfyUI: GPU und Docker). - **Installations-Sperre:** Kein passender Host → das Plugin lässt sich nicht installieren (keine Leiche im System). Künftig prüft ein Check-Knopf in Iris alle Plugins gegen ihre Hosts (da, ansprechbar, verbindbar); Ausfall → Plugins fett markiert mit Begründung, gesperrt. Der Knopf gehört auf die Iris-Seite (eigenes Issue), nicht in dieses Plugin. **Umfang dieses Issues** - **Keine automatische Migration.** Die fünf GPU-Plugins (heartmula, whisper, marker, qwen-tts-linux, comfyui-bridge) werden **ausgeschaltet, ihre Dateien bleiben** — die ssh_target-Felder sind später die Quelle für die Anpassung **je Plugin in einem eigenen Issue**, eines nach dem anderen, wenn die Basis steht. Der SSH-Zugang pro Host (Adresse, Schlüssel) wird genau einmal geführt: bei host-add/host-probe/setup durch iris-server-hosts; Plugins speichern danach weder Host-Adresse noch Keys. - **Harter Schnitt, keine Übergangszeit für alte Aufrufer:** ID iris-server-hosts, Route GET /hosts/targets, Store iris_server_hosts.json, Python-Module, Tests, Mac-Seite (GPUHostRegistry.swift, IrisRemoteServer.swift, GPUHostPluginKey.swift), Store-Material, Doku, PLAN.md, Gedächtnis — alles im selben Zug, beide Server gleichzeitig. **Bauabschnitte** 1. Kern: Host-Liste mit Fähigkeiten-Feldern, Sonde (nvidia-smi, docker info, uname -s -m), Picker-Route GET /hosts/targets mit needs-Filter, Manifest-Feld host_capabilities, Auflösung host_id → SSH-Ziel plus Schlüssel (beide Server), Installationsprüfung. 2. Mac-Seite im selben Zug (Picker-Route, gpu_hosts.json → iris_server_hosts.json, GPUHost-Dateien). 3. GPU-Plugins deaktivieren (HeartMuLa, Whisper, Marker, Qwen-TTS Linux, ComfyUI Bridge), Konfigurationsdateien bleiben unangetastet. 4. Umbenennung der Restflächen (Store-Material, Doku, PLAN.md, Gedächtnis), Tests und Mutationstests, Veröffentlichen nur auf Alfs Wort. **Folgt in separaten Issues:** Plugin für Plugin auf das neue System umstellen (Picker mit needs, host_id statt ssh_target, Panel ohne SSH-Felder); Iris-Seite Check-Knopf.
Author
Owner

PR #121 gemergt: docs(iris-server-hosts): Grill-me-Entscheidungen zur Weiterentwicklung (#115)
#121

Commits:

  • docs(iris-server-hosts): Grill-me-Entscheidungen zur Weiterentwicklung (#115)
PR #121 gemergt: docs(iris-server-hosts): Grill-me-Entscheidungen zur Weiterentwicklung (#115) https://forgejo.lewerken.duckdns.org/iris/iris-plugins/pulls/121 Commits: - docs(iris-server-hosts): Grill-me-Entscheidungen zur Weiterentwicklung (#115)
Author
Owner

PR #122 gemergt: feat(iris-server-hosts): gpu-hosts umbenannt, Kennung statt SSH-Ziel, Fähigkeiten im Host-Eintrag (#115)
#122

Commits:

  • feat(iris-server-hosts): gpu-hosts umbenannt, Kennung statt SSH-Ziel, Fähigkeiten im Host-Eintrag (#115)
PR #122 gemergt: feat(iris-server-hosts): gpu-hosts umbenannt, Kennung statt SSH-Ziel, Fähigkeiten im Host-Eintrag (#115) https://forgejo.lewerken.duckdns.org/iris/iris-plugins/pulls/122 Commits: - feat(iris-server-hosts): gpu-hosts umbenannt, Kennung statt SSH-Ziel, Fähigkeiten im Host-Eintrag (#115)
Author
Owner

PR #38 gemergt: feat(hosts): gpu_targets umbenannt zu hosts_targets, Kennung statt SSH-Ziel, needs-Filter (iris/iris-plugins#115)
iris/iris-linux-server#38

Commits:

  • feat(hosts): gpu_targets umbenannt zu hosts_targets, Kennung statt SSH-Ziel, needs-Filter (iris/iris-plugins#115)
PR #38 gemergt: feat(hosts): gpu_targets umbenannt zu hosts_targets, Kennung statt SSH-Ziel, needs-Filter (iris/iris-plugins#115) https://forgejo.lewerken.duckdns.org/iris/iris-linux-server/pulls/38 Commits: - feat(hosts): gpu_targets umbenannt zu hosts_targets, Kennung statt SSH-Ziel, needs-Filter (iris/iris-plugins#115)
Author
Owner

Linux-Server-Hälfte von #115 gemergt (PR #38, main = 64493c7).

Was gebaut wurde

  • app/gpu_targets.py → app/hosts_targets.py, app/gpu_targets_routes.py → app/hosts_targets_routes.py; Route GET /gpu-hosts/targets → GET /hosts/targets.
  • resolve()/target_from_body() akzeptieren nur noch die Host-Kennung (host_id, self), nie die Adresse; das alte ssh_target-Feld im Panel-Body wird nicht mehr gelesen.
  • list_targets(needs=…) filtert nach host_capabilities aus der Manifest-Anforderung; self ist immer ein Host, die Anforderungen entscheiden, nie die Hardware des Servers.
  • Aufrufer mitgezogen: plugins_routes.py (start-server, test-connection), heartmula/marker/whisper/qwen-tts-linux-Routen; Fehlermeldung „Kein GPU-Rechner gewählt“ → „Kein Rechner gewählt“.

Was gemessen wurde

  • Unit-Tests tests/test_hosts_targets.py: 7 Tests, lokal und im Container gegen den Deploy-Stand grün.
  • Suite .venv/bin/pytest -m "not slow" lokal gegen den laufenden Server: 414 passed. Die 14 Fehlerschaltungen sind Backup-Timesouts, Qwen-TTS-Backend down (503) und Vault-Git-Umgebung — gegen HEAD ohne diese Änderung identisch, also nicht von ihr.
  • Live gegen alf@iris-server nach docker compose up -d --build --force-recreate: GET /health ok; GET /hosts/targets liefert self mit echter SSH-Sonde (RTX 4090 + 3090 Ti, Docker, Ubuntu 26.04.1); needs=gpu/needs=docker/needs=gpu&needs=docker → self; needs=rechner (unbekannte Fähigkeit) → leer; alte Route /gpu-hosts/targets → 404.
  • tests/test_plugins.py::test_plugin_start_server_reports_ssh_failure_without_crashing auf den neuen Vertrag gestellt: neuer Fixture unreachable_host schreibt einen Host-Eintrag mit unerreichbarer Adresse in iris_server_hosts.json und entfernt ihn danach; neuer Test test_plugin_start_server_requires_a_known_host prüft 400 ohne Kennung und bei unbekannter Kennung.

Grenzen / offen

  • Die fünf Plugin-Panels (heartmula, comfyui-bridge, marker, qwen-tts-linux, whisper) holen weiterhin /gpu-hosts/targets — die Route ist auf dem Linux-Server jetzt 404, der Picker bleibt dort leer (der catch-Pfad), das „Erweitert“-Feld funktioniert. Die Plugin-seitige Picker-Umstellung ist in #115 als separate Schritte vorgesehen.
  • Die Mac-Seite (GPUHostRegistry.swift, IrisRemoteServer.swift, GPUHostPluginKey.swift) und /hosts/targets dort sind die andere Hälfte von #115 und stehen noch aus.
  • Die Unit-Tests brauchen lokal den Import-Stub für app/email_config_store.py (die Datei kopiert erst der Dockerfile-Build aus vendored/ ins Image) — Muster wie tests/test_videowatch_queue_items.py.
**Linux-Server-Hälfte von #115 gemergt (PR #38, main = 64493c7).** **Was gebaut wurde** - `app/gpu_targets.py` → `app/hosts_targets.py`, `app/gpu_targets_routes.py` → `app/hosts_targets_routes.py`; Route `GET /gpu-hosts/targets` → `GET /hosts/targets`. - `resolve()`/`target_from_body()` akzeptieren nur noch die Host-Kennung (`host_id`, `self`), nie die Adresse; das alte `ssh_target`-Feld im Panel-Body wird nicht mehr gelesen. - `list_targets(needs=…)` filtert nach `host_capabilities` aus der Manifest-Anforderung; `self` ist immer ein Host, die Anforderungen entscheiden, nie die Hardware des Servers. - Aufrufer mitgezogen: `plugins_routes.py` (start-server, test-connection), `heartmula`/`marker`/`whisper`/`qwen-tts-linux`-Routen; Fehlermeldung „Kein GPU-Rechner gewählt“ → „Kein Rechner gewählt“. **Was gemessen wurde** - Unit-Tests `tests/test_hosts_targets.py`: 7 Tests, lokal und im Container gegen den Deploy-Stand grün. - Suite `.venv/bin/pytest -m "not slow"` lokal gegen den laufenden Server: 414 passed. Die 14 Fehlerschaltungen sind Backup-Timesouts, Qwen-TTS-Backend down (503) und Vault-Git-Umgebung — gegen HEAD ohne diese Änderung identisch, also nicht von ihr. - Live gegen `alf@iris-server` nach `docker compose up -d --build --force-recreate`: `GET /health` ok; `GET /hosts/targets` liefert `self` mit echter SSH-Sonde (RTX 4090 + 3090 Ti, Docker, Ubuntu 26.04.1); `needs=gpu`/`needs=docker`/`needs=gpu&needs=docker` → `self`; `needs=rechner` (unbekannte Fähigkeit) → leer; alte Route `/gpu-hosts/targets` → 404. - `tests/test_plugins.py::test_plugin_start_server_reports_ssh_failure_without_crashing` auf den neuen Vertrag gestellt: neuer Fixture `unreachable_host` schreibt einen Host-Eintrag mit unerreichbarer Adresse in `iris_server_hosts.json` und entfernt ihn danach; neuer Test `test_plugin_start_server_requires_a_known_host` prüft 400 ohne Kennung und bei unbekannter Kennung. **Grenzen / offen** - Die fünf Plugin-Panels (`heartmula`, `comfyui-bridge`, `marker`, `qwen-tts-linux`, `whisper`) holen weiterhin `/gpu-hosts/targets` — die Route ist auf dem Linux-Server jetzt 404, der Picker bleibt dort leer (der `catch`-Pfad), das „Erweitert“-Feld funktioniert. Die Plugin-seitige Picker-Umstellung ist in #115 als separate Schritte vorgesehen. - Die Mac-Seite (`GPUHostRegistry.swift`, `IrisRemoteServer.swift`, `GPUHostPluginKey.swift`) und `/hosts/targets` dort sind die andere Hälfte von #115 und stehen noch aus. - Die Unit-Tests brauchen lokal den Import-Stub für `app/email_config_store.py` (die Datei kopiert erst der Dockerfile-Build aus `vendored/` ins Image) — Muster wie `tests/test_videowatch_queue_items.py`.
Author
Owner

PR #39 gemergt: docs(hosts): Chronik zum Host-Ziele-Umbau (iris/iris-plugins#115)
iris/iris-linux-server#39

Commits:

PR #39 gemergt: docs(hosts): Chronik zum Host-Ziele-Umbau (iris/iris-plugins#115) https://forgejo.lewerken.duckdns.org/iris/iris-linux-server/pulls/39 Commits: - docs(hosts): Chronik zum Host-Ziele-Umbau (iris/iris-plugins#115)
Author
Owner

PR #77 gemergt: feat(iris-server-hosts): Mac-Seite — Host-Kern, Kennung statt SSH-Ziel, Fähigkeiten (iris/iris-plugins#115)
iris/Iris#77

Commits:

  • test(iris-hosts): Prüfprogramm auf den Host-Kern erweitert, Parität zur Python-Seite (iris/iris-plugins#115)
  • feat(iris-server-hosts): Mac-Seite — Host-Kern, Kennung statt SSH-Ziel, Fähigkeiten (iris/iris-plugins#115)
PR #77 gemergt: feat(iris-server-hosts): Mac-Seite — Host-Kern, Kennung statt SSH-Ziel, Fähigkeiten (iris/iris-plugins#115) https://forgejo.lewerken.duckdns.org/iris/Iris/pulls/77 Commits: - test(iris-hosts): Prüfprogramm auf den Host-Kern erweitert, Parität zur Python-Seite (iris/iris-plugins#115) - feat(iris-server-hosts): Mac-Seite — Host-Kern, Kennung statt SSH-Ziel, Fähigkeiten (iris/iris-plugins#115)
Author
Owner

Stand (2026-10-18): Kern und Mac-Seite gemergt, GPU-Plugins aus

Gemergt

  • Plugin-Repo: PR #122 — iris-server-hosts 0.3.0: Manifest-Feld host_capabilities, panel_api (overview, public-key, host-add, host-probe, host-update, host-remove, setup-start, setup-status), Kern iris_server_hosts_core.py / iris_server_hosts_ssh.py (Sonde PROBE_COMMAND + parse_probe), Tests, Store-Material.
  • Linux-Server: PR #38 (main = 64493c7) + Chronik #39 — gpu_targets*.py → hosts_targets*.py, Route GET /hosts/targets, resolve() / target_from_body() lesen nur noch die Kennung (kein ssh_target im Panel-Body), list_targets(needs=…) nach host_capabilities, Aufrufer mitgezogen; 7 Unit-Tests grün, Suite 414 passed, live auf alf@iris-server verifiziert (echte Sonde: RTX 4090 + 3090 Ti, Docker, Ubuntu 26.04.1), alte Route 404.
  • Iris (Mac): PR #77, zwei Commits — 5e13259 Mac-Seite, cdcd927 Prüfprogramm. Route GET /gpu-hosts/targets → GET /hosts/targets mit needs-Filter; wiederholte Parameter (?needs=gpu&needs=docker, wie die Linux-Route sie als Liste liest) gingen in queryParams vorher verloren, deshalb HTTPRequest.queryValues. Alle zehn Panel-Aufrufstellen (whisper / heartmula / marker / qwen-tts-linux je test-connection + install, comfyui-bridge start-server + test-connection) lösen nur noch host_id auf, nie eine Adresse; „Kein GPU-Rechner gewählt" → „Kein Rechner gewählt". gpu_hosts.json → iris_server_hosts.json (die beiden Host-Einträge mitgezogen, links raus). Eine Sonde fragt jetzt Grafikkarte, Docker und Betriebssystem in einem SSH-Aufruf. Neuer Foundation-Kern Iris/IrisHosts/: IrisHostStore (Iris-Ordner über IRIS_APP_SUPPORT_DIR, host_id → Ziel), IrisHostCapabilities (Sondentext wörtlich wie hosts_targets.py, Anforderungen, Picker-Eintrag), IrisHostRegistry, IrisHostPluginKey (eine Pfaddefinition statt der doppelten).

Prüfprogramm scripts/gpu-host-harness → scripts/iris-hosts-harness: run.sh nimmt jetzt Iris/GPUHost/ und Iris/IrisHosts/, eine neue Datei in einem dieser Ordner läuft automatisch mit, neue Funktionalität bekommt einen MARK-Abschnitt. 26 neue Checks (Sonde auswerten, Anforderungen, Picker-Eintrag, Host-Liste anlegen/lesen/Idempotenz, Picker-Auflösung, Schlüssel idempotent); die Fixtures probe-*.txt sind wörtlich tests/fakes.py, der Programm-Kopf nennt die Paritäts-Referenzen beider Server — ein Check, der dort anders steht, zeigt eine Abweichung zwischen den Servern. Der Lauf setzt IRIS_APP_SUPPORT_DIR auf einen Temp-Ordner und räumt ihn auf: die echten Iris-Dateien bleiben unangetastet. Zwei Funde, die der Xcode-Build durchließ: Crash Index out of range bei leerem Betriebssystem-Abschnitt (Rechner ohne /etc/os-release; Swifts ?? [""] fällt nur bei fehlendem Schlüssel um, Pythons or [""] bei leerer Sammlung) und ein zu strenger eigener Check (URL-Gleichheit schließt das Verzeichnis-Flag ein, appendingPathComponent setzt es nie).

Bauabschnitte

  1. Kern — ✅ auf beiden Servern: Host-Liste mit Fähigkeiten-Feldern, Sonde, Picker-Route GET /hosts/targets mit needs-Filter, Manifest-Feld host_capabilities, Auflösung host_id → SSH-Ziel plus Schlüssel. Offen: die Installations-Sperre (kein passender Host → Plugin nicht installierbar) ist nicht verifiziert; der Mac-Server wertet host_capabilities aus dem Manifest nicht aus — handleHostTargets filtert nur nach dem needs-Query (auf dem Linux-Server kommt die Anforderung als needs an der Route an).
  2. Mac-Seite — ✅ im selben Zug (PR #77): Picker-Route, iris_server_hosts.json, GPUHost-Dateien (GPUHostPluginKey → IrisHostPluginKey, GPUHostSetupModel trägt die Grafikkarte als capabilities ein).
  3. GPU-Plugins deaktivieren — ✅ Mac-Seite: HeartMuLa, Whisper, Marker, Qwen-TTS Linux, ComfyUI Bridge und gpu-hosts sind deinstalliert; ihre *_plugin_config.json und die per-Plugin-Schlüssel in ssh/ bleiben unangetastet — sie sind die Quelle für die Umstellung je Plugin im eigenen Issue.
  4. Restflächen — angefangen: Harness umbenannt, plans/GPU-HOST-SETUP-APP.md und CLAUDE-Key-Files-Referenz.md auf den neuen Pfad gestellt, Iris-PLAN.md um Phase 98 erweitert (mit Lessons Learned). Offen: scripts/build-gpu-host-bundle.sh, Referenz-Eintrag für IrisHosts/, Store-Material, Gedächtnis, Mutationstests.

Noch offen

  • iris-server-hosts auf dem Mac installieren (kein GPU-Plugin ist mehr installiert).
  • GET /hosts/targets gegen die neu gebaute App live verifizieren (needs-Matrix, Sonde auf alf@iris-server).
  • Die fünf Plugin-Panels holen weiterhin /gpu-hosts/targets → 404 auf beiden Servern, Picker bleibt dort leer (der catch-Pfad); gehört in die Plugin-für-Plugin-Folge-Issues.
  • Veröffentlichen nur auf Alfs Wort.
## Stand (2026-10-18): Kern und Mac-Seite gemergt, GPU-Plugins aus **Gemergt** - **Plugin-Repo:** PR #122 — `iris-server-hosts` 0.3.0: Manifest-Feld `host_capabilities`, `panel_api` (`overview`, `public-key`, `host-add`, `host-probe`, `host-update`, `host-remove`, `setup-start`, `setup-status`), Kern `iris_server_hosts_core.py` / `iris_server_hosts_ssh.py` (Sonde `PROBE_COMMAND` + `parse_probe`), Tests, Store-Material. - **Linux-Server:** PR #38 (main = 64493c7) + Chronik #39 — `gpu_targets*.py` → `hosts_targets*.py`, Route `GET /hosts/targets`, `resolve()` / `target_from_body()` lesen nur noch die Kennung (kein `ssh_target` im Panel-Body), `list_targets(needs=…)` nach `host_capabilities`, Aufrufer mitgezogen; 7 Unit-Tests grün, Suite 414 passed, live auf `alf@iris-server` verifiziert (echte Sonde: RTX 4090 + 3090 Ti, Docker, Ubuntu 26.04.1), alte Route 404. - **Iris (Mac):** PR #77, zwei Commits — `5e13259` Mac-Seite, `cdcd927` Prüfprogramm. Route `GET /gpu-hosts/targets` → `GET /hosts/targets` mit `needs`-Filter; wiederholte Parameter (`?needs=gpu&needs=docker`, wie die Linux-Route sie als Liste liest) gingen in `queryParams` vorher verloren, deshalb `HTTPRequest.queryValues`. Alle zehn Panel-Aufrufstellen (whisper / heartmula / marker / qwen-tts-linux je `test-connection` + `install`, comfyui-bridge `start-server` + `test-connection`) lösen nur noch `host_id` auf, nie eine Adresse; „Kein GPU-Rechner gewählt" → „Kein Rechner gewählt". `gpu_hosts.json` → `iris_server_hosts.json` (die beiden Host-Einträge mitgezogen, `links` raus). Eine Sonde fragt jetzt Grafikkarte, Docker **und** Betriebssystem in einem SSH-Aufruf. Neuer Foundation-Kern `Iris/IrisHosts/`: `IrisHostStore` (Iris-Ordner über `IRIS_APP_SUPPORT_DIR`, `host_id` → Ziel), `IrisHostCapabilities` (Sondentext wörtlich wie `hosts_targets.py`, Anforderungen, Picker-Eintrag), `IrisHostRegistry`, `IrisHostPluginKey` (eine Pfaddefinition statt der doppelten). **Prüfprogramm** `scripts/gpu-host-harness` → `scripts/iris-hosts-harness`: `run.sh` nimmt jetzt `Iris/GPUHost/` **und** `Iris/IrisHosts/`, eine neue Datei in einem dieser Ordner läuft automatisch mit, neue Funktionalität bekommt einen `MARK`-Abschnitt. 26 neue Checks (Sonde auswerten, Anforderungen, Picker-Eintrag, Host-Liste anlegen/lesen/Idempotenz, Picker-Auflösung, Schlüssel idempotent); die Fixtures `probe-*.txt` sind wörtlich `tests/fakes.py`, der Programm-Kopf nennt die Paritäts-Referenzen beider Server — ein Check, der dort anders steht, zeigt eine Abweichung zwischen den Servern. Der Lauf setzt `IRIS_APP_SUPPORT_DIR` auf einen Temp-Ordner und räumt ihn auf: die echten Iris-Dateien bleiben unangetastet. **Zwei Funde, die der Xcode-Build durchließ:** Crash `Index out of range` bei leerem Betriebssystem-Abschnitt (Rechner ohne `/etc/os-release`; Swifts `?? [""]` fällt nur bei fehlendem Schlüssel um, Pythons `or [""]` bei leerer Sammlung) und ein zu strenger eigener Check (`URL`-Gleichheit schließt das Verzeichnis-Flag ein, `appendingPathComponent` setzt es nie). **Bauabschnitte** 1. **Kern** — ✅ auf beiden Servern: Host-Liste mit Fähigkeiten-Feldern, Sonde, Picker-Route `GET /hosts/targets` mit needs-Filter, Manifest-Feld `host_capabilities`, Auflösung `host_id` → SSH-Ziel plus Schlüssel. **Offen:** die Installations-Sperre (kein passender Host → Plugin nicht installierbar) ist nicht verifiziert; der Mac-Server wertet `host_capabilities` aus dem Manifest **nicht** aus — `handleHostTargets` filtert nur nach dem `needs`-Query (auf dem Linux-Server kommt die Anforderung als `needs` an der Route an). 2. **Mac-Seite** — ✅ im selben Zug (PR #77): Picker-Route, `iris_server_hosts.json`, GPUHost-Dateien (`GPUHostPluginKey` → `IrisHostPluginKey`, `GPUHostSetupModel` trägt die Grafikkarte als `capabilities` ein). 3. **GPU-Plugins deaktivieren** — ✅ Mac-Seite: HeartMuLa, Whisper, Marker, Qwen-TTS Linux, ComfyUI Bridge und `gpu-hosts` sind deinstalliert; ihre `*_plugin_config.json` und die per-Plugin-Schlüssel in `ssh/` bleiben unangetastet — sie sind die Quelle für die Umstellung je Plugin im eigenen Issue. 4. **Restflächen** — angefangen: Harness umbenannt, `plans/GPU-HOST-SETUP-APP.md` und `CLAUDE-Key-Files-Referenz.md` auf den neuen Pfad gestellt, Iris-`PLAN.md` um Phase 98 erweitert (mit Lessons Learned). Offen: `scripts/build-gpu-host-bundle.sh`, Referenz-Eintrag für `IrisHosts/`, Store-Material, Gedächtnis, Mutationstests. **Noch offen** - `iris-server-hosts` auf dem Mac installieren (kein GPU-Plugin ist mehr installiert). - `GET /hosts/targets` gegen die neu gebaute App live verifizieren (needs-Matrix, Sonde auf `alf@iris-server`). - Die fünf Plugin-Panels holen weiterhin `/gpu-hosts/targets` → 404 auf beiden Servern, Picker bleibt dort leer (der `catch`-Pfad); gehört in die Plugin-für-Plugin-Folge-Issues. - Veröffentlichen nur auf Alfs Wort.
Author
Owner

PR #78 gemergt: feat(hosts): host_capabilities aus dem Manifest wird ausgewertet, needs ergänzt sie (iris/iris-plugins#115)
iris/Iris#78

Commits:

  • test(iris-hosts): Prüfprogramm um die Manifest-Anforderung erweitert
  • feat(iris-hosts): Manifest-Anforderung des Plugins wird im Picker ausgewertet
PR #78 gemergt: feat(hosts): host_capabilities aus dem Manifest wird ausgewertet, needs ergänzt sie (iris/iris-plugins#115) https://forgejo.lewerken.duckdns.org/iris/Iris/pulls/78 Commits: - test(iris-hosts): Prüfprogramm um die Manifest-Anforderung erweitert - feat(iris-hosts): Manifest-Anforderung des Plugins wird im Picker ausgewertet
Author
Owner

PR #40 gemergt: feat(hosts): host_capabilities aus dem Manifest wird ausgewertet, needs ergänzt sie (iris/iris-plugins#115)
iris/iris-linux-server#40

Commits:

  • feat(hosts): host_capabilities aus dem Manifest wird ausgewertet, needs ergänzt sie
PR #40 gemergt: feat(hosts): host_capabilities aus dem Manifest wird ausgewertet, needs ergänzt sie (iris/iris-plugins#115) https://forgejo.lewerken.duckdns.org/iris/iris-linux-server/pulls/40 Commits: - feat(hosts): host_capabilities aus dem Manifest wird ausgewertet, needs ergänzt sie
Author
Owner

PR #126 gemergt: feat(iris-server-hosts): Installations-Sperre — ein Rechner muss alle Anforderungen erfüllen (#115)
#126

Commits:

  • feat(iris-server-hosts): Installations-Sperre — ein Rechner muss alle Anforderungen erfüllen (#115)
PR #126 gemergt: feat(iris-server-hosts): Installations-Sperre — ein Rechner muss alle Anforderungen erfüllen (#115) https://forgejo.lewerken.duckdns.org/iris/iris-plugins/pulls/126 Commits: - feat(iris-server-hosts): Installations-Sperre — ein Rechner muss alle Anforderungen erfüllen (#115)
Author
Owner

PR #41 gemergt: feat(hosts): Installations-Sperre in der Installationsroutine, ein Rechner muss alle Anforderungen erfüllen (iris/iris-plugins#115)
iris/iris-linux-server#41

Commits:

  • feat(hosts): Installations-Sperre in der Installationsroutine, ein Rechner muss alle Anforderungen erfüllen (iris/iris-plugins#115)
PR #41 gemergt: feat(hosts): Installations-Sperre in der Installationsroutine, ein Rechner muss alle Anforderungen erfüllen (iris/iris-plugins#115) https://forgejo.lewerken.duckdns.org/iris/iris-linux-server/pulls/41 Commits: - feat(hosts): Installations-Sperre in der Installationsroutine, ein Rechner muss alle Anforderungen erfüllen (iris/iris-plugins#115)
Author
Owner

PR #79 gemergt: feat(iris-hosts): Installations-Sperre — ein Rechner muss alle Anforderungen erfüllen, Prüfprogramm und Restore-Bericht (iris/iris-plugins#115)
iris/Iris#79

Commits:

  • feat(iris-hosts): Installations-Sperre — ein Rechner muss alle Anforderungen erfüllen, Prüfprogramm und Restore-Bericht (iris/iris-plugins#115)
PR #79 gemergt: feat(iris-hosts): Installations-Sperre — ein Rechner muss alle Anforderungen erfüllen, Prüfprogramm und Restore-Bericht (iris/iris-plugins#115) https://forgejo.lewerken.duckdns.org/iris/Iris/pulls/79 Commits: - feat(iris-hosts): Installations-Sperre — ein Rechner muss alle Anforderungen erfüllen, Prüfprogramm und Restore-Bericht (iris/iris-plugins#115)
Author
Owner

PR #42 gemergt: test(hosts): Gate-Tests der Installations-Sperre (iris/iris-plugins#115)
iris/iris-linux-server#42

Commits:

PR #42 gemergt: test(hosts): Gate-Tests der Installations-Sperre (iris/iris-plugins#115) https://forgejo.lewerken.duckdns.org/iris/iris-linux-server/pulls/42 Commits: - test(hosts): Gate-Tests der Installations-Sperre (iris/iris-plugins#115)
Author
Owner

PR #80 gemergt: test(iris-hosts): IrisHostProbe — die Sperre mit Attrappen-Sonde, ohne sie wäre PR #79 unvollständig (iris/iris-plugins#115)
iris/Iris#80

Commits:

  • test(iris-hosts): IrisHostProbe — die Sperre mit Attrappen-Sonde, ohne sie wäre PR #79 unvollständig (iris/iris-plugins#115)
PR #80 gemergt: test(iris-hosts): IrisHostProbe — die Sperre mit Attrappen-Sonde, ohne sie wäre PR #79 unvollständig (iris/iris-plugins#115) https://forgejo.lewerken.duckdns.org/iris/Iris/pulls/80 Commits: - test(iris-hosts): IrisHostProbe — die Sperre mit Attrappen-Sonde, ohne sie wäre PR #79 unvollständig (iris/iris-plugins#115)
Author
Owner

Statusbericht — Installations-Sperre gebaut (Bauabschnitt 1, Entscheidung 5)

Die Entscheidung: Ein Plugin lässt sich nur installieren, wenn mindestens ein Rechner alle seine Anforderungen erfüllt — nicht jeder Anforderung irgendein Rechner. Zwei Rechner, von denen einer nur eine Grafikkarte hat und der andere nur Docker, erfüllen zusammen kein Plugin, das beides verlangt. Kein passender Host → das Plugin lässt sich nicht installieren (keine Leiche im System). Der Check-Knopf in Iris bleibt ein eigenes Issue.

Gebaut als dieselbe reine Funktion auf allen drei Seiten — die Parität ist der Vertrag, nicht ein Implementierungsdetail:

Seite Entscheidungsteil Sperre sitzt in
Plugin-Kern iris_server_hosts_core.unmet_requirements — (Referenz, gegen die geprüft wird)
Linux-Server hosts_targets.unmet_requirements plugin_installer.install_plugin_from_archive, vor dem ersten Schritt, der etwas anfasst (Treiber-Gruppe, Verzeichnis, Hook)
Mac-Seite IrisHostCapabilities.unmetRequirements PluginManager.importPlugin, ebenso vor dem ersten Schreibschritt

Leere Liste heißt: es gibt so einen Rechner; sonst die Anforderungen, die dem besten fehlen; ohne Rechner alle.

Fähigkeiten über dieselbe Sonde wie der Picker (hosts_with_capabilities → gate_blockers): self per Sonde, die Hosts der Liste ebenfalls, ein Rechner, der nicht antwortet, behält seine gespeicherten Fähigkeiten. list_targets() ist auf dieselbe Basis gestellt — Picker und Sperre sehen jetzt dieselben Rechner. Ohne Anforderung prüft die Sperre nichts und läuft ohne Netzwerkzugriff.

Restore-Bericht: blocked als neues Feld, auf beiden Seiten dasselbe (PluginRestoreSummary in Swift, der Sync-Bericht in plugin_installer.py). Ein gesperrtes Plugin ist nie installiert; ohne das Feld fiele es aus dem Bericht heraus, als wäre der Restore gelungen. importPlugin gibt die Blocker zurück, weil der Restore sie braucht.

Anforderung aus dem Manifest braucht zwei Leser: manifest_capabilities liest sie aus dem installierten Plugin (die Route kennt die ID über den cfg_token). Die Sperre braucht das Manifest des Pakets, das gerade installiert wird — dafür manifest_requirements(manifest) als gemeinsame Basis über dem Dict.

Verifiziert:

  • Plugin-Kern: 74 Tests grün, Mutationstest 64 von 64 erkannt. Drei neue Mutationen, eine davon auf die eigentliche Kante der Entscheidung: „der erste Rechner entscheidet, nicht der beste" (max gegen min).
  • Linux-Server: 22 Tests grün (test_plugin_install_gate.py neu — reine lokale Unit-Tests ohne Server und ohne Netzwerk, jeder Fall prüft, dass vor der Sperre nichts angefasst wurde; test_hosts_targets.py +8).
  • Mac-Seite: Prüfprogramm grün, inklusive der Sperren-Fälle über eine Attrappen-Sonde (jeder Rechner wird genau einmal gefragt, ohne Anforderung läuft kein Sonde-Aufruf).

Commits: 2a9b5a1 (plugins, PR #126) · 0bac9f6 + 32cb78b (linux-server, PR #41, #42) · e25ed80 + 046be00 (Iris, PR #79, #80).

Zwei Stolpersteine, die diese Session gezeigt hat: ship ohne -a nimmt neue Dateien nicht mit — die neue Gate-Testdatei und IrisHostProbe.swift waren im ersten PR ihres Repos nicht enthalten, während der Code, der sie aufruft, schon gemergt war. Build und Prüfprogramm waren lokal grün, weil beide die Datei fanden; das Repo war unvollständig.

Offen in #115: Bauabschnitt 3 (die fünf GPU-Plugins deaktivieren, Dateien bleiben) und Bauabschnitt 4 (Restflächen umbenennen, Veröffentlichen nur auf Alfs Wort). Die Plugin-für-Plugin-Umstellung und der Iris-Check-Knopf bleiben eigene Issues.

## Statusbericht — Installations-Sperre gebaut (Bauabschnitt 1, Entscheidung 5) **Die Entscheidung:** Ein Plugin lässt sich nur installieren, wenn **mindestens ein** Rechner **alle** seine Anforderungen erfüllt — nicht jeder Anforderung irgendein Rechner. Zwei Rechner, von denen einer nur eine Grafikkarte hat und der andere nur Docker, erfüllen zusammen kein Plugin, das beides verlangt. Kein passender Host → das Plugin lässt sich nicht installieren (keine Leiche im System). Der Check-Knopf in Iris bleibt ein eigenes Issue. **Gebaut als dieselbe reine Funktion auf allen drei Seiten** — die Parität ist der Vertrag, nicht ein Implementierungsdetail: | Seite | Entscheidungsteil | Sperre sitzt in | |---|---|---| | Plugin-Kern | `iris_server_hosts_core.unmet_requirements` | — (Referenz, gegen die geprüft wird) | | Linux-Server | `hosts_targets.unmet_requirements` | `plugin_installer.install_plugin_from_archive`, vor dem ersten Schritt, der etwas anfasst (Treiber-Gruppe, Verzeichnis, Hook) | | Mac-Seite | `IrisHostCapabilities.unmetRequirements` | `PluginManager.importPlugin`, ebenso vor dem ersten Schreibschritt | Leere Liste heißt: es gibt so einen Rechner; sonst die Anforderungen, die dem besten fehlen; ohne Rechner alle. **Fähigkeiten über dieselbe Sonde wie der Picker** (`hosts_with_capabilities` → `gate_blockers`): `self` per Sonde, die Hosts der Liste ebenfalls, ein Rechner, der nicht antwortet, behält seine gespeicherten Fähigkeiten. `list_targets()` ist auf dieselbe Basis gestellt — Picker und Sperre sehen jetzt dieselben Rechner. Ohne Anforderung prüft die Sperre nichts und läuft ohne Netzwerkzugriff. **Restore-Bericht:** `blocked` als neues Feld, auf beiden Seiten dasselbe (`PluginRestoreSummary` in Swift, der Sync-Bericht in `plugin_installer.py`). Ein gesperrtes Plugin ist nie installiert; ohne das Feld fiele es aus dem Bericht heraus, als wäre der Restore gelungen. `importPlugin` gibt die Blocker zurück, weil der Restore sie braucht. **Anforderung aus dem Manifest braucht zwei Leser:** `manifest_capabilities` liest sie aus dem *installierten* Plugin (die Route kennt die ID über den cfg_token). Die Sperre braucht das Manifest des Pakets, das *gerade installiert wird* — dafür `manifest_requirements(manifest)` als gemeinsame Basis über dem Dict. **Verifiziert:** - Plugin-Kern: 74 Tests grün, Mutationstest **64 von 64 erkannt**. Drei neue Mutationen, eine davon auf die eigentliche Kante der Entscheidung: „der erste Rechner entscheidet, nicht der beste" (`max` gegen `min`). - Linux-Server: 22 Tests grün (`test_plugin_install_gate.py` neu — reine lokale Unit-Tests ohne Server und ohne Netzwerk, jeder Fall prüft, dass vor der Sperre nichts angefasst wurde; `test_hosts_targets.py` +8). - Mac-Seite: Prüfprogramm grün, inklusive der Sperren-Fälle über eine Attrappen-Sonde (jeder Rechner wird genau einmal gefragt, ohne Anforderung läuft kein Sonde-Aufruf). **Commits:** `2a9b5a1` (plugins, PR #126) · `0bac9f6` + `32cb78b` (linux-server, PR #41, #42) · `e25ed80` + `046be00` (Iris, PR #79, #80). **Zwei Stolpersteine, die diese Session gezeigt hat:** `ship` ohne `-a` nimmt neue Dateien nicht mit — die neue Gate-Testdatei und `IrisHostProbe.swift` waren im ersten PR ihres Repos nicht enthalten, während der Code, der sie aufruft, schon gemergt war. Build und Prüfprogramm waren lokal grün, weil beide die Datei fanden; das Repo war unvollständig. **Offen in #115:** Bauabschnitt 3 (die fünf GPU-Plugins deaktivieren, Dateien bleiben) und Bauabschnitt 4 (Restflächen umbenennen, Veröffentlichen nur auf Alfs Wort). Die Plugin-für-Plugin-Umstellung und der Iris-Check-Knopf bleiben eigene Issues.
Author
Owner

PR #128 gemergt: fix(iris-server-hosts): ungeprüfte Hosts beim Öffnen einlesen, Anzeige „noch nicht geprüft“ (iris/iris-plugins#115)
#128

Commits:

  • fix(iris-server-hosts): ungeprüfte Hosts beim Öffnen einlesen, Anzeige „noch nicht geprüft“ (iris/iris-plugins#115)
PR #128 gemergt: fix(iris-server-hosts): ungeprüfte Hosts beim Öffnen einlesen, Anzeige „noch nicht geprüft“ (iris/iris-plugins#115) https://forgejo.lewerken.duckdns.org/iris/iris-plugins/pulls/128 Commits: - fix(iris-server-hosts): ungeprüfte Hosts beim Öffnen einlesen, Anzeige „noch nicht geprüft“ (iris/iris-plugins#115)
Author
Owner

Fix: ungeprüfte Hosts (PR #128, main = 97fd005)

Befund: Nach der Migration von gpu_hosts.json standen beide Mac-Hosts nur mit capabilities: {gpus: []} im Store (kein docker, os, checked_at) und wurden nie neu eingelesen. Das Panel zeigte „keine Grafikkarte · kein Docker“, obwohl ssh.probe() gegen beide Einträge RTX 4090 + 3090 Ti, Docker und Ubuntu 26.04.1 liefert.

Fix: overview liest Hosts ohne checked_at einmal ein (nicht während einer Einrichtung; unerreichbare bleiben ungeprüft und werden nicht gespeichert). Die Anzeige sagt „noch nicht geprüft“, solange checked_at fehlt.

Geprüft: 76 Tests grün (2 neu), Mutationstest 67 von 67 (3 neu). Installierte Kopie auf dem Mac synchronisiert; der Linux-Server hat das Plugin nicht installiert.

Grenze: Ein dauerhaft unerreichbarer, ungeprüfter Host verzögert jedes Öffnen bis zum SSH-Timeout (40 s). Am echten Panel noch nicht nachgeprüft.

## Fix: ungeprüfte Hosts (PR #128, main = 97fd005) **Befund:** Nach der Migration von `gpu_hosts.json` standen beide Mac-Hosts nur mit `capabilities: {gpus: []}` im Store (kein `docker`, `os`, `checked_at`) und wurden nie neu eingelesen. Das Panel zeigte „keine Grafikkarte · kein Docker“, obwohl `ssh.probe()` gegen beide Einträge RTX 4090 + 3090 Ti, Docker und Ubuntu 26.04.1 liefert. **Fix:** `overview` liest Hosts ohne `checked_at` einmal ein (nicht während einer Einrichtung; unerreichbare bleiben ungeprüft und werden nicht gespeichert). Die Anzeige sagt „noch nicht geprüft“, solange `checked_at` fehlt. **Geprüft:** 76 Tests grün (2 neu), Mutationstest 67 von 67 (3 neu). Installierte Kopie auf dem Mac synchronisiert; der Linux-Server hat das Plugin nicht installiert. **Grenze:** Ein dauerhaft unerreichbarer, ungeprüfter Host verzögert jedes Öffnen bis zum SSH-Timeout (40 s). Am echten Panel noch nicht nachgeprüft.
Author
Owner

PR #129 gemergt: docs(iris-server-hosts): PLAN.md auf den Stand von #115 gebracht (iris/iris-plugins#115)
#129

Commits:

PR #129 gemergt: docs(iris-server-hosts): PLAN.md auf den Stand von #115 gebracht (iris/iris-plugins#115) https://forgejo.lewerken.duckdns.org/iris/iris-plugins/pulls/129 Commits: - docs(iris-server-hosts): PLAN.md auf den Stand von #115 gebracht (iris/iris-plugins#115)
Author
Owner

PR #130 gemergt: docs(iris-server-hosts): Live-Prüfung von /hosts/targets auf dem Mac, Lücke bei self (iris/iris-plugins#115)
#130

Commits:

  • docs(iris-server-hosts): Live-Prüfung von /hosts/targets auf dem Mac, Lücke bei self (iris/iris-plugins#115)
PR #130 gemergt: docs(iris-server-hosts): Live-Prüfung von /hosts/targets auf dem Mac, Lücke bei self (iris/iris-plugins#115) https://forgejo.lewerken.duckdns.org/iris/iris-plugins/pulls/130 Commits: - docs(iris-server-hosts): Live-Prüfung von /hosts/targets auf dem Mac, Lücke bei self (iris/iris-plugins#115)
Author
Owner

Live-Prüfung von GET /hosts/targets auf dem Mac (2026-10-19)

Geprüft: laufende Iris-App (Xcode-Debug-Build von 10:35, Port 8765, Bearer-Token) mit der echten Host-Liste.

Anfrage Ergebnis
ohne needs, needs=gpu, needs=docker, needs=gpu&needs=docker HTTP 200, beide Hosts mit RTX 4090 + 3090 Ti, Docker, Ubuntu 26.04.1
needs=rechner (unbekannte Fähigkeit) HTTP 200, leer
alte Route /gpu-hosts/targets HTTP 404

Die Fähigkeiten kommen aus einer frischen SSH-Sonde je Anfrage, die gespeicherten Werte sind jetzt gefüllt (Fix aus #128 greift).

Lücke: Die Mac-Route liefert keinen Eintrag „Dieser Iris-Server“ (self), der Linux-Server schon. Die Spezifikation sagt, self ist immer ein Host. Offen: entscheiden, ob die Mac-Route self führt (Mac ohne NVIDIA und Docker würde bei needs=… ohnehin herausgefiltert).

Nicht geprüft: der Weg über cfg_token (Manifest-Anforderung eines installierten Plugins); beide Einträge 192.168.178.153 und iris-server sind derselbe Rechner und erscheinen doppelt im Picker.

## Live-Prüfung von `GET /hosts/targets` auf dem Mac (2026-10-19) **Geprüft:** laufende Iris-App (Xcode-Debug-Build von 10:35, Port 8765, Bearer-Token) mit der echten Host-Liste. | Anfrage | Ergebnis | |---|---| | ohne `needs`, `needs=gpu`, `needs=docker`, `needs=gpu&needs=docker` | HTTP 200, beide Hosts mit RTX 4090 + 3090 Ti, Docker, Ubuntu 26.04.1 | | `needs=rechner` (unbekannte Fähigkeit) | HTTP 200, leer | | alte Route `/gpu-hosts/targets` | HTTP 404 | Die Fähigkeiten kommen aus einer frischen SSH-Sonde je Anfrage, die gespeicherten Werte sind jetzt gefüllt (Fix aus #128 greift). **Lücke:** Die Mac-Route liefert keinen Eintrag „Dieser Iris-Server“ (`self`), der Linux-Server schon. Die Spezifikation sagt, `self` ist immer ein Host. Offen: entscheiden, ob die Mac-Route `self` führt (Mac ohne NVIDIA und Docker würde bei `needs=…` ohnehin herausgefiltert). **Nicht geprüft:** der Weg über `cfg_token` (Manifest-Anforderung eines installierten Plugins); beide Einträge `192.168.178.153` und `iris-server` sind derselbe Rechner und erscheinen doppelt im Picker.
Author
Owner

PR #84 gemergt: feat(iris-hosts): Dieser Iris-Server (self) in Picker-Route, Auflösung und Installations-Sperre (iris/iris-plugins#115)
iris/Iris#84

Commits:

  • feat(iris-hosts): Dieser Iris-Server (self) in Picker-Route, Auflösung und Installations-Sperre (iris/iris-plugins#115)
PR #84 gemergt: feat(iris-hosts): Dieser Iris-Server (self) in Picker-Route, Auflösung und Installations-Sperre (iris/iris-plugins#115) https://forgejo.lewerken.duckdns.org/iris/Iris/pulls/84 Commits: - feat(iris-hosts): Dieser Iris-Server (self) in Picker-Route, Auflösung und Installations-Sperre (iris/iris-plugins#115)
Author
Owner

PR #131 gemergt: docs(iris-server-hosts): self in der Mac-Route, Stand im Plan (iris/iris-plugins#115)
#131

Commits:

PR #131 gemergt: docs(iris-server-hosts): self in der Mac-Route, Stand im Plan (iris/iris-plugins#115) https://forgejo.lewerken.duckdns.org/iris/iris-plugins/pulls/131 Commits: - docs(iris-server-hosts): self in der Mac-Route, Stand im Plan (iris/iris-plugins#115)
Author
Owner

„Dieser Iris-Server“ (self) in der Mac-Route (Iris PR #84, main = 49a34bf)

Geändert: Die Mac-Seite führt jetzt wie der Linux-Server den Eintrag self („Dieser Iris-Server“) vor der Host-Liste, in drei Stellen zugleich: Picker-Route GET /hosts/targets, Auflösung (host_id self → benutzer@Adresse) und Installations-Sperre (PluginManager). Gemeinsame Quelle ist IrisHostStore.entriesWithSelf. Das Ziel ist IRIS_SERVER_HOST, sonst <LocalHostName>.local; localhost, 127.… und fehlender Benutzer ergeben kein Ziel, wie self_target() auf dem Linux-Server.

Geprüft: Prüfprogramm scripts/iris-hosts-harness grün, 10 neue Checks (Zielbildung, Vorrang der Umgebungsvariable, Ablehnung von localhost, Reihenfolge, Auflösung, Verhalten ohne Ziel). Iris-Scheme baut (BUILD SUCCEEDED, eigener DerivedData-Ordner, die laufende App blieb unberührt).

Offen / Grenzen:

  • Der gemeinsame Plugin-Schlüssel steht auf diesem Mac nicht in ~/.ssh/authorized_keys (Remote Login ist an). Die Sonde von self findet deshalb nichts: self erscheint ohne Anforderung, erfüllt aber keine (leere Fähigkeiten), bis der Zugang eingerichtet ist. Der Linux-Server trägt den Schlüssel mit einem Hilfscontainer selbst ein; für den Mac ist das nicht entschieden (es ändert die SSH-Zulassung des Nutzers).
  • Live in der laufenden App nicht geprüft (Neustart nötig); IrisClient nicht gebaut (teilt die Datei).
## „Dieser Iris-Server“ (`self`) in der Mac-Route (Iris PR #84, main = 49a34bf) **Geändert:** Die Mac-Seite führt jetzt wie der Linux-Server den Eintrag `self` („Dieser Iris-Server“) vor der Host-Liste, in drei Stellen zugleich: Picker-Route `GET /hosts/targets`, Auflösung (`host_id` `self` → `benutzer@Adresse`) und Installations-Sperre (`PluginManager`). Gemeinsame Quelle ist `IrisHostStore.entriesWithSelf`. Das Ziel ist `IRIS_SERVER_HOST`, sonst `<LocalHostName>.local`; `localhost`, `127.…` und fehlender Benutzer ergeben kein Ziel, wie `self_target()` auf dem Linux-Server. **Geprüft:** Prüfprogramm `scripts/iris-hosts-harness` grün, 10 neue Checks (Zielbildung, Vorrang der Umgebungsvariable, Ablehnung von localhost, Reihenfolge, Auflösung, Verhalten ohne Ziel). Iris-Scheme baut (BUILD SUCCEEDED, eigener DerivedData-Ordner, die laufende App blieb unberührt). **Offen / Grenzen:** - Der gemeinsame Plugin-Schlüssel steht auf diesem Mac nicht in `~/.ssh/authorized_keys` (Remote Login ist an). Die Sonde von `self` findet deshalb nichts: `self` erscheint ohne Anforderung, erfüllt aber keine (leere Fähigkeiten), bis der Zugang eingerichtet ist. Der Linux-Server trägt den Schlüssel mit einem Hilfscontainer selbst ein; für den Mac ist das nicht entschieden (es ändert die SSH-Zulassung des Nutzers). - Live in der laufenden App nicht geprüft (Neustart nötig); `IrisClient` nicht gebaut (teilt die Datei).
Author
Owner

PR #132 gemergt: feat(iris-server-hosts): Zugang zu Dieser Iris-Server im Plugin einrichten (self-authorize) (iris/iris-plugins#115)
#132

Commits:

  • feat(iris-server-hosts): Zugang zu Dieser Iris-Server im Plugin einrichten (self-authorize) (iris/iris-plugins#115)
PR #132 gemergt: feat(iris-server-hosts): Zugang zu Dieser Iris-Server im Plugin einrichten (self-authorize) (iris/iris-plugins#115) https://forgejo.lewerken.duckdns.org/iris/iris-plugins/pulls/132 Commits: - feat(iris-server-hosts): Zugang zu Dieser Iris-Server im Plugin einrichten (self-authorize) (iris/iris-plugins#115)
Author
Owner

Zugang zu „Dieser Iris-Server“ wird im Plugin eingerichtet (PR iris-plugins, main = 7a47742)

Vorgabe (Alf, 2026-10-19): Der SSH-Zugriff ist nur in iris-server-hosts zu konfigurieren, in keinem anderen Plugin. Der Mac-Eintrag self (Iris PR #84) fand mangels Schlüssel in ~/.ssh/authorized_keys nichts; das lässt sich jetzt im Plugin beheben.

Geändert:

  • overview liefert zusätzlich self (Name, Ziel, erreichbar, Fähigkeiten), gelesen bei jedem Öffnen, nichts gespeichert; es steht nie in der Host-Liste.
  • Neuer Befehl self-authorize {password} trägt den gemeinsamen Schlüssel einmalig mit dem Passwort des Benutzers ein (derselbe Weg wie host-add mit Passwort; das Passwort wird nie gespeichert oder zurückgegeben).
  • Das Fenster zeigt „Dieser Iris-Server“ über der Host-Liste: mit Fähigkeiten, wenn der Zugang steht, sonst mit Passwortfeld und „Zugang einrichten“.
  • Die Zielbildung ist core.self_target, dieselbe Regel wie IrisHostStore.selfTarget (Mac) und hosts_targets.self_target (Linux): IRIS_SERVER_HOST, sonst <LocalHostName>.local; localhost/127.… ergeben kein Ziel.

Geprüft: 85 Tests grün (9 neu: erreichbar/unerreichbar/ohne Ziel, Passwort nötig und vorher kein SSH-Aufruf, Schlüssel eintragen und danach erreichbar, falsches Passwort ohne Leck, Zielbildung), Mutationstest 72 von 72 (5 neu, eine überlebte zuerst und führte zu einem stärkeren Test). Echter lesender Lauf von overview gegen eine Kopie der Host-Liste: self = alflewerken@Mac-Studio.local, nicht erreichbar (Schlüssel fehlt, wie erwartet), beide Hosts mit Docker. Installierte Kopie auf dem Mac synchronisiert (vorher identisch mit HEAD).

Offen / Grenzen:

  • Das Passwort-Einrichten selbst ist nicht echt gelaufen (braucht das Mac-Passwort von Alf); nur gegen Attrappen geprüft.
  • Das Plugin wird nach dem Kopieren erst nach einem Neuladen des Panels (und für die neue Befehlsliste evtl. Neustart der Iris-App) wirksam.
  • Auf dem Linux-Server trägt der Hilfscontainer den Schlüssel weiterhin selbst ein; ob das dort entfallen soll, damit der Zugang überall nur im Plugin steht, ist nicht entschieden.
## Zugang zu „Dieser Iris-Server“ wird im Plugin eingerichtet (PR iris-plugins, main = 7a47742) **Vorgabe (Alf, 2026-10-19):** Der SSH-Zugriff ist nur in `iris-server-hosts` zu konfigurieren, in keinem anderen Plugin. Der Mac-Eintrag `self` (Iris PR #84) fand mangels Schlüssel in `~/.ssh/authorized_keys` nichts; das lässt sich jetzt im Plugin beheben. **Geändert:** - `overview` liefert zusätzlich `self` (Name, Ziel, erreichbar, Fähigkeiten), gelesen bei jedem Öffnen, nichts gespeichert; es steht nie in der Host-Liste. - Neuer Befehl `self-authorize {password}` trägt den gemeinsamen Schlüssel einmalig mit dem Passwort des Benutzers ein (derselbe Weg wie `host-add` mit Passwort; das Passwort wird nie gespeichert oder zurückgegeben). - Das Fenster zeigt „Dieser Iris-Server“ über der Host-Liste: mit Fähigkeiten, wenn der Zugang steht, sonst mit Passwortfeld und „Zugang einrichten“. - Die Zielbildung ist `core.self_target`, dieselbe Regel wie `IrisHostStore.selfTarget` (Mac) und `hosts_targets.self_target` (Linux): `IRIS_SERVER_HOST`, sonst `<LocalHostName>.local`; `localhost`/`127.…` ergeben kein Ziel. **Geprüft:** 85 Tests grün (9 neu: erreichbar/unerreichbar/ohne Ziel, Passwort nötig und vorher kein SSH-Aufruf, Schlüssel eintragen und danach erreichbar, falsches Passwort ohne Leck, Zielbildung), Mutationstest 72 von 72 (5 neu, eine überlebte zuerst und führte zu einem stärkeren Test). Echter lesender Lauf von `overview` gegen eine Kopie der Host-Liste: `self` = `alflewerken@Mac-Studio.local`, nicht erreichbar (Schlüssel fehlt, wie erwartet), beide Hosts mit Docker. Installierte Kopie auf dem Mac synchronisiert (vorher identisch mit HEAD). **Offen / Grenzen:** - Das Passwort-Einrichten selbst ist nicht echt gelaufen (braucht das Mac-Passwort von Alf); nur gegen Attrappen geprüft. - Das Plugin wird nach dem Kopieren erst nach einem Neuladen des Panels (und für die neue Befehlsliste evtl. Neustart der Iris-App) wirksam. - Auf dem Linux-Server trägt der Hilfscontainer den Schlüssel weiterhin selbst ein; ob das dort entfallen soll, damit der Zugang überall nur im Plugin steht, ist nicht entschieden.
Author
Owner

PR #133 gemergt: fix(iris-server-hosts): scutil mit absolutem Pfad, sonst fehlt self im Fenster (iris/iris-plugins#115)
#133

Commits:

PR #133 gemergt: fix(iris-server-hosts): scutil mit absolutem Pfad, sonst fehlt self im Fenster (iris/iris-plugins#115) https://forgejo.lewerken.duckdns.org/iris/iris-plugins/pulls/133 Commits: - fix(iris-server-hosts): scutil mit absolutem Pfad, sonst fehlt self im Fenster (iris/iris-plugins#115)
Author
Owner

Fix: „Dieser Iris-Server“ fehlte im Fenster (main = e50a9ff)

Befund: Alfs Screenshot zeigte nach dem vorigen PR keine Karte „Dieser Iris-Server“. Die echte Route POST /plugins/iris-server-hosts/api/overview lieferte kein self. Ursache: Die App startet Panel-Skripte mit PATH=/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin, scutil liegt aber in /usr/sbin. Der Aufruf scheiterte lautlos, der Bonjour-Name blieb leer, die Zielbildung ergab kein Ziel. Mit genau diesem PATH nachgestellt: self fehlt; nach dem Fix vorhanden.

Fix: scutil mit absolutem Pfad. Neuer Test (der Aufruf nutzt /usr/sbin/scutil), 86 Tests grün, Mutationstest 73 von 73. Installierte Kopie synchronisiert; die laufende App liefert jetzt self = alflewerken@Mac-Studio.local, nicht erreichbar (Schlüssel fehlt).

Offen: Das Passwort-Einrichten selbst ist weiter nicht echt gelaufen. Die Mac-App selbst (Swift) nutzt die SystemConfiguration-API und ist von dem PATH-Problem nicht betroffen.

## Fix: „Dieser Iris-Server“ fehlte im Fenster (main = e50a9ff) **Befund:** Alfs Screenshot zeigte nach dem vorigen PR keine Karte „Dieser Iris-Server“. Die echte Route `POST /plugins/iris-server-hosts/api/overview` lieferte kein `self`. Ursache: Die App startet Panel-Skripte mit `PATH=/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin`, `scutil` liegt aber in `/usr/sbin`. Der Aufruf scheiterte lautlos, der Bonjour-Name blieb leer, die Zielbildung ergab kein Ziel. Mit genau diesem PATH nachgestellt: `self` fehlt; nach dem Fix vorhanden. **Fix:** `scutil` mit absolutem Pfad. Neuer Test (der Aufruf nutzt `/usr/sbin/scutil`), 86 Tests grün, Mutationstest 73 von 73. Installierte Kopie synchronisiert; die laufende App liefert jetzt `self` = `alflewerken@Mac-Studio.local`, nicht erreichbar (Schlüssel fehlt). **Offen:** Das Passwort-Einrichten selbst ist weiter nicht echt gelaufen. Die Mac-App selbst (Swift) nutzt die SystemConfiguration-API und ist von dem PATH-Problem nicht betroffen.
Author
Owner

PR #134 gemergt: docs(iris-server-hosts): Live-Prüfung mit self auf dem Mac, Befund zu macOS-Betriebssystem (iris/iris-plugins#115)
#134

Commits:

  • docs(iris-server-hosts): Live-Prüfung mit self auf dem Mac, Befund zu macOS-Betriebssystem (iris/iris-plugins#115)
PR #134 gemergt: docs(iris-server-hosts): Live-Prüfung mit self auf dem Mac, Befund zu macOS-Betriebssystem (iris/iris-plugins#115) https://forgejo.lewerken.duckdns.org/iris/iris-plugins/pulls/134 Commits: - docs(iris-server-hosts): Live-Prüfung mit self auf dem Mac, Befund zu macOS-Betriebssystem (iris/iris-plugins#115)
Author
Owner

Live-Prüfung nach dem Einrichten des Zugangs (2026-10-19)

Alf hat im Fenster „Hosts“ bei „Dieser Iris-Server“ das Passwort eingetragen. Danach (laufende App, Bearer-Token):

Anfrage Ergebnis
overview (Plugin) self erreichbar, ~/.ssh/authorized_keys enthält den Plugin-Schlüssel (1 Zeile)
GET /hosts/targets HTTP 200: self, 192.168.178.153, iris-server
?needs=gpu, ?needs=docker, ?needs=gpu&needs=docker HTTP 200: nur die zwei Linux-Hosts (RTX 4090 + 3090 Ti, Docker, Ubuntu 26.04.1)
?needs=rechner HTTP 200, leer
/gpu-hosts/targets HTTP 404

self führt die Liste an und fällt bei GPU- und Docker-Anforderung heraus, wie vorgesehen: der Mac hat keine NVIDIA-Karte, und docker ist im PATH der SSH-Sitzung nicht erreichbar (/Applications/Docker.app ist installiert, es gibt aber kein docker unter /usr/local/bin oder /opt/homebrew/bin).

Befund: Die Sonde meldet für den Mac kein Betriebssystem. Sie liest /etc/os-release, das macOS nicht hat; sw_vers liefert „macOS 26.6.2“. Der Sondentext ist auf allen drei Seiten wörtlich gleich (Plugin PROBE_COMMAND, Linux hosts_targets.PROBE_COMMAND, Mac IrisHostCapabilities.probeCommand) und müsste überall zugleich geändert werden. Nicht entschieden. Auswirkung heute gering, weil kein Plugin os verlangt.

Nicht geprüft: der Weg über ein cfg_token (Manifest-Anforderung eines installierten Plugins).

## Live-Prüfung nach dem Einrichten des Zugangs (2026-10-19) Alf hat im Fenster „Hosts“ bei „Dieser Iris-Server“ das Passwort eingetragen. Danach (laufende App, Bearer-Token): | Anfrage | Ergebnis | |---|---| | `overview` (Plugin) | `self` erreichbar, `~/.ssh/authorized_keys` enthält den Plugin-Schlüssel (1 Zeile) | | `GET /hosts/targets` | HTTP 200: `self`, `192.168.178.153`, `iris-server` | | `?needs=gpu`, `?needs=docker`, `?needs=gpu&needs=docker` | HTTP 200: nur die zwei Linux-Hosts (RTX 4090 + 3090 Ti, Docker, Ubuntu 26.04.1) | | `?needs=rechner` | HTTP 200, leer | | `/gpu-hosts/targets` | HTTP 404 | `self` führt die Liste an und fällt bei GPU- und Docker-Anforderung heraus, wie vorgesehen: der Mac hat keine NVIDIA-Karte, und `docker` ist im PATH der SSH-Sitzung nicht erreichbar (`/Applications/Docker.app` ist installiert, es gibt aber kein `docker` unter `/usr/local/bin` oder `/opt/homebrew/bin`). **Befund:** Die Sonde meldet für den Mac kein Betriebssystem. Sie liest `/etc/os-release`, das macOS nicht hat; `sw_vers` liefert „macOS 26.6.2“. Der Sondentext ist auf allen drei Seiten wörtlich gleich (Plugin `PROBE_COMMAND`, Linux `hosts_targets.PROBE_COMMAND`, Mac `IrisHostCapabilities.probeCommand`) und müsste überall zugleich geändert werden. Nicht entschieden. Auswirkung heute gering, weil kein Plugin `os` verlangt. **Nicht geprüft:** der Weg über ein `cfg_token` (Manifest-Anforderung eines installierten Plugins).
Author
Owner

Folge-Issue: Zustandsanzeige im Marktplatz und Rechnerwahl bei „Laden“ → iris/Iris#85

Beim Testen von Marker (iris-plugins#135) zeigte sich, dass der Marktplatz die Erstinstallation ablehnt („braucht Einrichtungsfragen“) und die Rechnerwahl nirgends bei „Laden“ stattfindet. Daraus ist in einer Grill-me-Runde ein eigenes Feature entstanden, das die Plugin-Umstellung hier trägt:

iris/Iris#85

  • Jedes Plugin meldet seinen Zustand per config-status (Grün konfiguriert, Gelb muss konfiguriert werden, Rot Fehler bei der Prüfung); der Marktplatz zeigt ihn am „Konfigurieren“-Knopf der Kachel und in Einstellungen → Plugins.
  • Bei „Laden“ prüft der Server die Hosts: kein passender Host → lokal installieren (Plugins mit neuem Manifest-Feld local_mode, zum Beispiel Marker), mindestens ein passender Host → Plugin installieren und das Konfigurationsfenster mit dem Picker öffnen.
  • Reihenfolge: erst diese Infrastruktur, dann die Plugin-Umstellungen (je ein Issue, Marker ist #135). Marker und iris-server-hosts bekommen config-status zuerst.
  • iOS wird nachgeholt (eigener Punkt im Issue und im Plan, damit nichts offen bleibt).
  • iris-server-hosts wird im Marktplatz veröffentlicht, das veraltete gpu-hosts 0.2.3 entfernt.

Plan: obsidian-docs/plans/PLUGIN-KONFIGURATION.md (Iris-Vault).

## Folge-Issue: Zustandsanzeige im Marktplatz und Rechnerwahl bei „Laden“ → iris/Iris#85 Beim Testen von Marker (iris-plugins#135) zeigte sich, dass der Marktplatz die Erstinstallation ablehnt („braucht Einrichtungsfragen“) und die Rechnerwahl nirgends bei „Laden“ stattfindet. Daraus ist in einer Grill-me-Runde ein eigenes Feature entstanden, das die Plugin-Umstellung hier trägt: **https://forgejo.lewerken.duckdns.org/iris/Iris/issues/85** - Jedes Plugin meldet seinen Zustand per `config-status` (Grün konfiguriert, Gelb muss konfiguriert werden, Rot Fehler bei der Prüfung); der Marktplatz zeigt ihn am „Konfigurieren“-Knopf der Kachel und in Einstellungen → Plugins. - Bei „Laden“ prüft der Server die Hosts: kein passender Host → lokal installieren (Plugins mit neuem Manifest-Feld `local_mode`, zum Beispiel Marker), mindestens ein passender Host → Plugin installieren und das Konfigurationsfenster mit dem Picker öffnen. - Reihenfolge: erst diese Infrastruktur, dann die Plugin-Umstellungen (je ein Issue, Marker ist #135). Marker und iris-server-hosts bekommen `config-status` zuerst. - iOS wird nachgeholt (eigener Punkt im Issue und im Plan, damit nichts offen bleibt). - iris-server-hosts wird im Marktplatz veröffentlicht, das veraltete `gpu-hosts 0.2.3` entfernt. Plan: `obsidian-docs/plans/PLUGIN-KONFIGURATION.md` (Iris-Vault).
alf closed this issue 2026-10-21 23:35:46 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
iris/iris-plugins#115
No description provided.