Fix: 'host-name'-Option kollidierte mit dem nativen Reservierungs-Hostname

Der Nutzer fragte zu Recht nach, ob eine Reservierung mit gleichzeitig
gesetztem hostname-Feld (aus dem Namen abgeleitet, z.B. 'unraid') UND
einem option-data-Override fuer 'host-name' (Code 12, z.B. 'test') so
beabsichtigt ist. Laut Kea-Dokumentation beantwortet Kea die Host-Name-
Anfrage eines Clients bei einer Reservierung automatisch mit deren
eigenem hostname-Feld -- der zusaetzliche Options-Override fuer dieselbe
Option war eine unbeabsichtigte Dopplung/Quelle fuer Widersprueche, keine
zusaetzliche Funktion.

'host-name' aus den 56 verbleibenden Standard-Optionen entfernt (war eine
von 57), neue Migration v3 loescht eine bereits geseedete/gesetzte
host-name-Zeile samt Wert aus bestehenden Installationen nach. Live auf
der Test-VM verifiziert: Option ist verschwunden, die 'unraid'-Reservierung
enthaelt jetzt nur noch hw-address/ip-address/hostname ohne option-data,
kea-dhcp4 -t weiterhin erfolgreich.
This commit is contained in:
2026-08-11 16:53:33 +02:00
parent 255308f81b
commit d3cf78592f
2 changed files with 52 additions and 26 deletions
+24 -18
View File
@@ -271,27 +271,33 @@ der aktiv weiterentwickelte Nachfolger und bildet „globaler Wert, pro Client
kein "ungültig", da das Fehlen des Netzes hier Absicht ist), statt es
jedes Mal neu anlegen zu müssen.
- **DHCP-Options** (`dhcp_option_defs`/`dhcp_option_values`): eine kuratierte
Auswahl an **57 Standard-Optionen** (analog den „Vordefinierten Optionen“
eines Windows-DHCP-Servers — u.a. Hostname erzwingen, NTP-/WINS-/TFTP-/
SMTP-Server, Boot-Datei, Domain-Search, IP-Forwarding) ist automatisch
vorbefüllt und **nicht löschbar** (Backend lehnt es ab, UI zeigt statt
eines Löschen-Buttons ein Schloss-Symbol) — Router/DNS-Server/Domain-Name/
Lease-Zeiten sind bewusst ausgenommen, da dafür bereits eigene, dedizierte
Felder existieren (Subnetze bzw. globale Einstellungen oben); ebenso
client-/protokollinterne Optionen (message-type, parameter-request-list,
Auswahl an **56 Standard-Optionen** (analog den „Vordefinierten Optionen“
eines Windows-DHCP-Servers — u.a. NTP-/WINS-/TFTP-/SMTP-Server, Boot-Datei,
Domain-Search, IP-Forwarding) ist automatisch vorbefüllt und **nicht
löschbar** (Backend lehnt es ab, UI zeigt statt eines Löschen-Buttons ein
Schloss-Symbol) — Router/DNS-Server/Domain-Name/Lease-Zeiten sind bewusst
ausgenommen, da dafür bereits eigene, dedizierte Felder existieren
(Subnetze bzw. globale Einstellungen oben); ebenso client-/
protokollinterne Optionen (message-type, parameter-request-list,
requested-address, ...), die serverseitig nicht sinnvoll setzbar sind.
Alle 57 Namen sind live gegen eine echte Kea-2.4.1-Instanz verifiziert
(`kea-dhcp4 -t`, jede Option einzeln getestet — u.a. „host-name“ mit
Bindestrich statt „hostname“ als Kea-Name richtiggestellt). Standard-
Optionen bekommen bewusst **kein eigenes `option-def`** in der generierten
Konfiguration — Kea kennt sie bereits nativ, eine Neudefinition würde die
eingebaute duplizieren; nur zusätzlich angelegte, wirklich eigene/
herstellerspezifische Options (z.B. eine Terminal-Boot-URL) bekommen eines
und bleiben frei löschbar.
„host-name“ (12) ist ebenfalls bewusst **nicht** enthalten (war es
zwischenzeitlich, wurde aber wieder entfernt): Kea beantwortet die
Host-Name-Anfrage eines Clients bei einer Reservierung bereits automatisch
über deren eigenes `hostname`-Feld (aus dem Namen der Reservierung
abgeleitet) — ein zusätzlicher `option-data`-Override für dieselbe Option
wäre laut Kea-Dokumentation eine Dopplung und Quelle für Widersprüche,
live an einer echten Reservierung mit beiden gleichzeitig gesetzten
Werten nachvollzogen. Alle verbleibenden Namen sind live gegen eine echte
Kea-2.4.1-Instanz verifiziert (`kea-dhcp4 -t`, jede Option einzeln
getestet). Standard-Optionen bekommen bewusst **kein eigenes
`option-def`** in der generierten Konfiguration — Kea kennt sie bereits
nativ, eine Neudefinition würde die eingebaute duplizieren; nur
zusätzlich angelegte, wirklich eigene/herstellerspezifische Options (z.B.
eine Terminal-Boot-URL) bekommen eines und bleiben frei löschbar.
In der Tabelle sind grundsätzlich nur **tatsächlich genutzte** Options
sichtbar (eigene immer, Standard-Optionen nur mit gesetztem globalen Wert)
— weitere Standard-Optionen kommen über ein Dropdown „+ Standard-Option
hinzufügen“ dazu, statt alle 57 dauerhaft als leere Zeilen anzuzeigen.
hinzufügen“ dazu, statt alle 56 dauerhaft als leere Zeilen anzuzeigen.
Jede Option hat einen **globalen** Wert sowie optional einen **Wert pro
Client** — ein Client-Override überschreibt den globalen Wert
ausschließlich für dieses eine Gerät (technisch: globale Werte landen im
@@ -301,7 +307,7 @@ der aktiv weiterentwickelte Nachfolger und bildet „globaler Wert, pro Client
gesetztem Override sind sichtbar, weitere kommen über ein Dropdown dazu.
Das ausgewählte Feld wird dabei direkt unter das Dropdown verschoben und
fokussiert, statt an seiner ursprünglichen Stelle irgendwo in der u.U.
langen Liste (bis zu 57 mögliche Options) zu erscheinen — sonst lag es
langen Liste (bis zu 56 mögliche Options) zu erscheinen — sonst lag es
oft außerhalb des sichtbaren Modal-Ausschnitts und wirkte, als wäre nichts
passiert (live genau so reproduziert und behoben).
- **Reservierungen aus zwei Quellen**: automatisch für jedes aktive Gerät mit
+28 -8
View File
@@ -516,9 +516,15 @@ def get_db_connection():
# Optionen (message-type, parameter-request-list, requested-address,
# client-identifier, server-identifier, ...) ebenfalls bewusst nicht
# enthalten — die sind serverseitig nicht sinnvoll setzbar (auch Windows
# Server listet sie nicht unter "Predefined Options"). Alle 57 Namen live
# gegen eine echte Kea-2.4.1-Instanz verifiziert (kea-dhcp4 -t je Option
# einzeln) — u.a. "host-name" (Kea-Name mit Bindestrich, NICHT "hostname").
# Server listet sie nicht unter "Predefined Options"). "host-name" (12)
# ebenfalls bewusst NICHT enthalten: Kea beantwortet die Host-Name-Anfrage
# eines Clients bei einer Reservierung bereits automatisch mit deren
# eigenem "hostname"-Feld (aus dem Namen der Reservierung abgeleitet, siehe
# _dhcp_safe_hostname) — ein zusätzlicher option-data-Override für dieselbe
# Option in derselben Reservierung wäre eine mit der Kea-Doku belegte
# Dopplung/Quelle für Widersprüche, kein zusätzlicher Nutzen. Alle
# restlichen Namen live gegen eine echte Kea-2.4.1-Instanz verifiziert
# (kea-dhcp4 -t je Option einzeln).
DHCP_STANDARD_OPTIONS = [
(4, "time-servers", "ipv4-address", "Zeitserver (RFC 868)"),
(7, "log-servers", "ipv4-address", "Log-Server (MIT-LCS UDP)"),
@@ -526,7 +532,6 @@ DHCP_STANDARD_OPTIONS = [
(9, "lpr-servers", "ipv4-address", "LPR-Druckserver"),
(10, "impress-servers", "ipv4-address", "Impress-Server"),
(11, "resource-location-servers", "ipv4-address", "Resource Location Server"),
(12, "host-name", "string", "Hostname (für Reservierung erzwingbar)"),
(13, "boot-size", "uint16", "Boot-Image-Größe (Blöcke)"),
(14, "merit-dump", "string", "Crash-Dump-Datei"),
(16, "swap-server", "ipv4-address", "Swap-Server"),
@@ -718,10 +723,10 @@ def _ensure_schema():
(code, name, opt_type, description),
)
conn.execute("INSERT OR IGNORE INTO settings (key, value) VALUES (?, '1')", (_migration_key_std_opts,))
# v2: Liste um weitere verifizierte Standard-Optionen erweitert (u.a.
# host-name/12) — eigener Guard, damit bereits auf v1 migrierte
# Installationen die neu hinzugekommenen Optionen ebenfalls bekommen,
# ohne die gesamte Seed-Logik erneut über alle Zeilen laufen zu lassen.
# v2: Liste um weitere verifizierte Standard-Optionen erweitert — eigener
# Guard, damit bereits auf v1 migrierte Installationen die neu
# hinzugekommenen Optionen ebenfalls bekommen, ohne die gesamte
# Seed-Logik erneut über alle Zeilen laufen zu lassen.
_migration_key_std_opts_v2 = "_seeded_dhcp_standard_options_v2"
if not conn.execute("SELECT 1 FROM settings WHERE key=?", (_migration_key_std_opts_v2,)).fetchone():
for code, name, opt_type, description in DHCP_STANDARD_OPTIONS:
@@ -731,6 +736,21 @@ def _ensure_schema():
(code, name, opt_type, description),
)
conn.execute("INSERT OR IGNORE INTO settings (key, value) VALUES (?, '1')", (_migration_key_std_opts_v2,))
# v3: "host-name" (12) als Standard-Option wieder entfernt — Kea
# beantwortet die Host-Name-Anfrage eines Clients bei einer Reservierung
# bereits automatisch über deren eigenes "hostname"-Feld; ein
# zusätzlicher option-data-Override dafür ist laut Kea-Doku eine
# Dopplung/Quelle für Widersprüche (live an einer echten Reservierung
# nachvollzogen, wo beide gleichzeitig gesetzt waren). Löscht auch
# bereits gesetzte Werte für diese Option mit, da sie ohnehin nie
# sinnvoll gewirkt hätten.
_migration_key_std_opts_v3 = "_removed_dhcp_standard_option_hostname_v3"
if not conn.execute("SELECT 1 FROM settings WHERE key=?", (_migration_key_std_opts_v3,)).fetchone():
stale = conn.execute("SELECT id FROM dhcp_option_defs WHERE name='host-name' AND is_standard=1").fetchone()
if stale:
conn.execute("DELETE FROM dhcp_option_values WHERE option_def_id=?", (stale["id"],))
conn.execute("DELETE FROM dhcp_option_defs WHERE id=?", (stale["id"],))
conn.execute("INSERT OR IGNORE INTO settings (key, value) VALUES (?, '1')", (_migration_key_std_opts_v3,))
# DHCP: manuelle Reservierungen — im Unterschied zu den automatisch aus
# den Clients (devices-Tabelle) erzeugten Reservierungen für Geräte, die