From 2ce7ebafe727d7efd3fce00ee573fe10acbb830b Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Mon, 17 Aug 2026 23:52:48 +0200 Subject: [PATCH] f-29: watchdog: add specific config #29 Signed-off-by: GnomeZworc --- conf/agent/config.exemple.yml | 7 +++ internal/config/agent/config_test.go | 65 ++++++++++++++++++++++++++++ internal/config/agent/struct.go | 6 +++ 3 files changed, 78 insertions(+) diff --git a/conf/agent/config.exemple.yml b/conf/agent/config.exemple.yml index 0517eac..72e88f8 100644 --- a/conf/agent/config.exemple.yml +++ b/conf/agent/config.exemple.yml @@ -51,6 +51,13 @@ qemu: monitor_dir: "/run/two/vms/monitor" qmp_dir: "/run/two/vms/qmp" +# Consistency watchdog: periodically checks that resources marked running in the +# database still exist on the system, and reports the gaps. Read-only, never repairs. +# A persisting gap is reported at every tick (no deduplication). +watchdog: + enabled: true + interval_seconds: 60 + # Admin API (read-only DB inspection, loopback only) admin: enabled: false diff --git a/internal/config/agent/config_test.go b/internal/config/agent/config_test.go index d0f3d31..a4d5b22 100644 --- a/internal/config/agent/config_test.go +++ b/internal/config/agent/config_test.go @@ -81,3 +81,68 @@ database: t.Errorf("attendu %q, obtenu %q", "/opt/two/data", cfg.Database.Path) } } + +func TestLoadConfig_WatchdogDefauts(t *testing.T) { + path := writeYAML(t, "") + cfg, err := LoadConfig(path) + if err != nil { + t.Fatalf("LoadConfig a échoué : %v", err) + } + if cfg.Watchdog.Enabled { + t.Error("watchdog.enabled devrait être false par défaut") + } + if cfg.Watchdog.IntervalSeconds != 60 { + t.Errorf("watchdog.interval_seconds attendu 60, obtenu %d", cfg.Watchdog.IntervalSeconds) + } +} + +func TestLoadConfig_WatchdogValeursExplicites(t *testing.T) { + path := writeYAML(t, ` +watchdog: + enabled: true + interval_seconds: 30 +`) + cfg, err := LoadConfig(path) + if err != nil { + t.Fatalf("LoadConfig a échoué : %v", err) + } + if !cfg.Watchdog.Enabled { + t.Error("watchdog.enabled attendu true") + } + if cfg.Watchdog.IntervalSeconds != 30 { + t.Errorf("watchdog.interval_seconds attendu 30, obtenu %d", cfg.Watchdog.IntervalSeconds) + } +} + +func TestLoadConfig_WatchdogActiveSansIntervalle(t *testing.T) { + path := writeYAML(t, ` +watchdog: + enabled: true +`) + cfg, err := LoadConfig(path) + if err != nil { + t.Fatalf("LoadConfig a échoué : %v", err) + } + if !cfg.Watchdog.Enabled { + t.Error("watchdog.enabled attendu true") + } + if cfg.Watchdog.IntervalSeconds != 60 { + t.Errorf("watchdog.interval_seconds attendu 60 (défaut viper), obtenu %d", cfg.Watchdog.IntervalSeconds) + } +} + +func TestLoadConfig_ExempleFourniEstValide(t *testing.T) { + cfg, err := LoadConfig("../../../conf/agent/config.exemple.yml") + if err != nil { + t.Fatalf("config.exemple.yml illisible : %v", err) + } + if !cfg.Watchdog.Enabled { + t.Error("config.exemple.yml devrait activer le watchdog") + } + if cfg.Watchdog.IntervalSeconds != 60 { + t.Errorf("config.exemple.yml : interval_seconds attendu 60, obtenu %d", cfg.Watchdog.IntervalSeconds) + } + if cfg.QEMU.QMPDir == "" { + t.Error("config.exemple.yml devrait définir qemu.qmp_dir") + } +} diff --git a/internal/config/agent/struct.go b/internal/config/agent/struct.go index 8b5d406..92a8677 100644 --- a/internal/config/agent/struct.go +++ b/internal/config/agent/struct.go @@ -44,6 +44,10 @@ type Config struct { MonitorDir string `mapstructure:"monitor_dir"` QMPDir string `mapstructure:"qmp_dir"` } `mapstructure:"qemu"` + Watchdog struct { + Enabled bool `mapstructure:"enabled"` + IntervalSeconds int `mapstructure:"interval_seconds"` + } `mapstructure:"watchdog"` DefaultInterface string `mapstructure:"default_interface"` Interfaces map[string]string `mapstructure:"interfaces"` } @@ -69,6 +73,8 @@ func LoadConfig(path string) (*Config, error) { v.SetDefault("qemu.serial_dir", "/run/two/vms/serial") v.SetDefault("qemu.monitor_dir", "/run/two/vms/monitor") v.SetDefault("qemu.qmp_dir", "/run/two/vms/qmp") + v.SetDefault("watchdog.enabled", false) + v.SetDefault("watchdog.interval_seconds", 60) v.SetDefault("admin.enabled", false) v.SetDefault("admin.address", "127.0.0.1") v.SetDefault("admin.port", 9091)