From 1b8be63d05296f5c7cac58e709f9c6fb512c1a40 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Thu, 6 Aug 2026 23:38:55 +1000 Subject: [PATCH] Render kea unix socket paths under /var/run/kea Kea 2.6.5 restricts control/HA unix socket paths to its compiled runstatedir and rejects any other path by exact string match ("invalid path specified: '/run/kea', supported path is '/var/run/kea'"), even though /var/run is a symlink to /run. The operator rendered sockets under /run/kea, so kea-dhcp4 and kea-ctrl-agent crash-looped on startup. - Point RunDir at /var/run/kea so all derived config/socket paths match. - Pre-create /var/run/kea in the kea image. - Assert rendered socket paths live under /var/run/kea. Claude-Session: https://claude.ai/code/session_01JUoARVdmhxKQHyyyp1pxeT --- Dockerfile.kea | 2 +- internal/kea/config_test.go | 17 +++++++++++++++++ internal/kea/consts.go | 7 +++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Dockerfile.kea b/Dockerfile.kea index d22717d..ce08c50 100644 --- a/Dockerfile.kea +++ b/Dockerfile.kea @@ -13,7 +13,7 @@ RUN dnf -y install epel-release \ && dnf -y install kea kea-hooks \ && dnf clean all \ && rm -rf /var/cache/dnf \ - && mkdir -p /run/kea + && mkdir -p /var/run/kea EXPOSE 67/udp 8000/tcp # Command is supplied by the operator (per-container entrypoint scripts). diff --git a/internal/kea/config_test.go b/internal/kea/config_test.go index d6c29cc..8090cb6 100644 --- a/internal/kea/config_test.go +++ b/internal/kea/config_test.go @@ -231,4 +231,21 @@ func TestRenderCtrlAgent(t *testing.T) { t.Errorf("ctrl-agent config missing %q", m) } } + // Kea 2.6+ only accepts unix socket paths under /var/run/kea (exact string). + if !strings.Contains(out, `"socket-name": "/var/run/kea/`) { + t.Errorf("ctrl-agent socket-name must be under /var/run/kea, got: %s", out) + } +} + +func TestControlSocketPathAllowedByKea(t *testing.T) { + if !strings.HasPrefix(CtrlSocketPath, "/var/run/kea/") { + t.Errorf("CtrlSocketPath %q must live under /var/run/kea (kea 2.6+ restriction)", CtrlSocketPath) + } + out, err := RenderDHCP4(referenceInput()) + if err != nil { + t.Fatal(err) + } + if !strings.Contains(out, `"socket-name": "/var/run/kea/`) { + t.Errorf("dhcp4 control-socket must be under /var/run/kea, got: %s", out) + } } diff --git a/internal/kea/consts.go b/internal/kea/consts.go index 29d3852..cb48b9b 100644 --- a/internal/kea/consts.go +++ b/internal/kea/consts.go @@ -10,8 +10,11 @@ const ( // ConfigDir is where projected config is mounted read-only. ConfigDir = "/etc/kea-operator" - // RunDir is a shared emptyDir for the config copy and control socket. - RunDir = "/run/kea" + // RunDir is a shared emptyDir for the config copy and control socket. Kea + // 2.6+ restricts unix socket paths to its compiled runstatedir and rejects + // anything else by exact string ("supported path is '/var/run/kea'"), even + // though /var/run symlinks to /run, so this must be the literal /var/run/kea. + RunDir = "/var/run/kea" // DHCP4ConfPath is the runtime kea-dhcp4 config. DHCP4ConfPath = RunDir + "/kea-dhcp4.conf"