From 108adab9c7d336558e8b55c645327bba6478eab1 Mon Sep 17 00:00:00 2001 From: AAdIprog Date: Sat, 10 Jan 2026 18:12:38 +0530 Subject: [PATCH] feat(cni): add file watcher for CNI config file Add WatchCNIConfigFile() function to monitor the CNI config file for external modifications and re-apply Kmesh CNI configuration when changes are detected. This ensures Kmesh CNI plugin remains installed even if other CNI plugins modify the config file. - Remove TODO comment for cniConfigFile watcher in chained.go - Add WatchCNIConfigFile() function in install.go - Integrate watcher in Start() function Signed-off-by: Aadi Shah Signed-off-by: AAdIprog --- pkg/cni/chained.go | 4 ---- pkg/cni/install.go | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/pkg/cni/chained.go b/pkg/cni/chained.go index 0ed09a91c..bcb536454 100644 --- a/pkg/cni/chained.go +++ b/pkg/cni/chained.go @@ -210,10 +210,6 @@ func (i *Installer) chainedKmeshCniPlugin(mode string, cniMountNetEtcDIR string) } log.Infof("cni config file: %s", cniConfigFilePath) - /* - TODO: add watcher for cniConfigFile - */ - existCNIConfig, err := os.ReadFile(cniConfigFilePath) if err != nil { err = fmt.Errorf("failed to read cni config file %v : %v", cniConfigFilePath, err) diff --git a/pkg/cni/install.go b/pkg/cni/install.go index c57a69b5c..543b05985 100644 --- a/pkg/cni/install.go +++ b/pkg/cni/install.go @@ -121,6 +121,54 @@ func (i *Installer) WatchServiceAccountToken() error { return nil } +// WatchCNIConfigFile watches the CNI config file for external modifications +// and re-applies Kmesh CNI configuration when changes are detected. +// This ensures Kmesh CNI plugin remains installed even if other CNI plugins +// modify the config file. +func (i *Installer) WatchCNIConfigFile() error { + cniConfigPath, err := i.getCniConfigPath() + if err != nil { + return fmt.Errorf("failed to get CNI config path: %v", err) + } + + if err := i.Watcher.Add(cniConfigPath); err != nil { + return fmt.Errorf("failed to add %s to file watcher: %v", cniConfigPath, err) + } + + // Start listening for events. + go func() { + log.Infof("start watching CNI config file %s", cniConfigPath) + + var timerC <-chan time.Time + for { + select { + case <-timerC: + timerC = nil + log.Infof("CNI config file changed, re-applying Kmesh CNI configuration") + if err := i.chainedKmeshCniPlugin(i.Mode, i.CniMountNetEtcDIR); err != nil { + log.Errorf("failed to re-apply Kmesh CNI config: %v", err) + } + + case event := <-i.Watcher.Events(cniConfigPath): + log.Debugf("got CNI config event %s", event.String()) + if event.Has(fsnotify.Write) || event.Has(fsnotify.Create) { + if timerC == nil { + timerC = time.After(100 * time.Millisecond) + } + } + + case err := <-i.Watcher.Errors(cniConfigPath): + if err != nil { + log.Errorf("error from CNI config file watcher: %v", err) + return + } + } + } + }() + + return nil +} + func (i *Installer) Start() error { if i.Mode == constants.KernelNativeMode || i.Mode == constants.DualEngineMode { log.Info("start write CNI config") @@ -133,6 +181,10 @@ func (i *Installer) Start() error { if err := i.WatchServiceAccountToken(); err != nil { return err } + + if err := i.WatchCNIConfigFile(); err != nil { + return err + } } return nil