diff --git a/cmd/multus-daemon/main.go b/cmd/multus-daemon/main.go index 9d17cac8d..2c7e443b8 100644 --- a/cmd/multus-daemon/main.go +++ b/cmd/multus-daemon/main.go @@ -57,8 +57,6 @@ func main() { os.Exit(4) } - configWatcherDoneChannel := make(chan struct{}) - multusConfigFile := "" ctx := context.Background() ctx, cancel := context.WithCancel(ctx) @@ -111,29 +109,6 @@ func main() { _ = logging.Errorf("failed to create the configuration manager for the primary CNI plugin: %v", err) os.Exit(2) } - - if multusConf.OverrideNetworkName { - if err := configManager.OverrideNetworkName(); err != nil { - _ = logging.Errorf("could not override the network name: %v", err) - } - } - - generatedMultusConfig, err := configManager.GenerateConfig() - if err != nil { - _ = logging.Errorf("failed to generated the multus configuration: %v", err) - } - logging.Verbosef("Generated MultusCNI config: %s", generatedMultusConfig) - - multusConfigFile, err = configManager.PersistMultusConfig(generatedMultusConfig) - if err != nil { - _ = logging.Errorf("failed to persist the multus configuration: %v", err) - } - - go func(ctx context.Context, doneChannel chan<- struct{}) { - if err := configManager.MonitorPluginConfiguration(ctx, doneChannel); err != nil { - _ = logging.Errorf("error watching file: %v", err) - } - }(ctx, configWatcherDoneChannel) } else { if err := copyUserProvidedConfig(multusConf.MultusConfigFile, multusConf.CniConfigDir); err != nil { logging.Errorf("failed to copy the user provided configuration %s: %v", multusConf.MultusConfigFile, err) @@ -151,14 +126,10 @@ func main() { var wg sync.WaitGroup if configManager != nil { - wg.Add(1) - go func() { - <-configWatcherDoneChannel - logging.Verbosef("ConfigWatcher done") - logging.Verbosef("Delete old config @ %v", multusConfigFile) - os.Remove(multusConfigFile) - wg.Done() - }() + if err := configManager.Start(ctx, &wg); err != nil { + _ = logging.Errorf("failed to start config manager: %v", err) + os.Exit(3) + } } wg.Wait() diff --git a/pkg/server/config/manager.go b/pkg/server/config/manager.go index 2082a5bd1..027252827 100644 --- a/pkg/server/config/manager.go +++ b/pkg/server/config/manager.go @@ -20,6 +20,7 @@ import ( "fmt" "os" "path/filepath" + "sync" "github.com/fsnotify/fsnotify" @@ -123,9 +124,43 @@ func newManager(config MultusConf, defaultCNIPluginName string) (*Manager, error return nil, fmt.Errorf("failed to load the primary CNI configuration as a multus delegate with error '%v'", err) } + if config.OverrideNetworkName { + if err := configManager.OverrideNetworkName(); err != nil { + return nil, logging.Errorf("could not override the network name: %v", err) + } + } + return configManager, nil } +// Start generates an updated Multus config, writes it, and begins watching +// the config directory and readiness indicator files for changes +func (m *Manager) Start(ctx context.Context, wg *sync.WaitGroup) error { + generatedMultusConfig, err := m.GenerateConfig() + if err != nil { + return logging.Errorf("failed to generated the multus configuration: %v", err) + } + logging.Verbosef("Generated MultusCNI config: %s", generatedMultusConfig) + + multusConfigFile, err := m.PersistMultusConfig(generatedMultusConfig) + if err != nil { + return logging.Errorf("failed to persist the multus configuration: %v", err) + } + + wg.Add(1) + go func() { + defer wg.Done() + if err := m.MonitorPluginConfiguration(ctx); err != nil { + _ = logging.Errorf("error watching file: %v", err) + } + logging.Verbosef("ConfigWatcher done") + logging.Verbosef("Delete old config @ %v", multusConfigFile) + os.Remove(multusConfigFile) + }() + + return nil +} + func (m *Manager) loadPrimaryCNIConfigFromFile() error { primaryCNIConfigData, err := primaryCNIData(m.primaryCNIConfigPath) if err != nil { @@ -175,7 +210,7 @@ func (m *Manager) GenerateConfig() (string, error) { // MonitorPluginConfiguration monitors the configuration file pointed // to by the primaryCNIPluginName attribute, and re-generates the multus // configuration whenever the primary CNI config is updated. -func (m *Manager) MonitorPluginConfiguration(ctx context.Context, done chan<- struct{}) error { +func (m *Manager) MonitorPluginConfiguration(ctx context.Context) error { logging.Verbosef("started to watch file %s", m.primaryCNIConfigPath) for { @@ -215,7 +250,6 @@ func (m *Manager) MonitorPluginConfiguration(ctx context.Context, done chan<- st case <-ctx.Done(): logging.Verbosef("Stopped monitoring, closing channel ...") _ = m.configWatcher.Close() - close(done) return nil } } diff --git a/pkg/server/config/manager_test.go b/pkg/server/config/manager_test.go index 105f50843..ab3efadb8 100644 --- a/pkg/server/config/manager_test.go +++ b/pkg/server/config/manager_test.go @@ -19,6 +19,7 @@ import ( "encoding/json" "fmt" "os" + "sync" "time" . "github.com/onsi/ginkgo/v2" @@ -42,6 +43,7 @@ var _ = Describe("Configuration Manager", func() { var configManager *Manager var multusConfigDir string var defaultCniConfig string + var wg *sync.WaitGroup BeforeEach(func() { var err error @@ -67,9 +69,12 @@ var _ = Describe("Configuration Manager", func() { configManager, err = NewManager(*multusConf) Expect(err).NotTo(HaveOccurred()) + + wg = &sync.WaitGroup{} }) AfterEach(func() { + wg.Wait() Expect(os.RemoveAll(multusConfigDir)).To(Succeed()) }) @@ -102,15 +107,10 @@ var _ = Describe("Configuration Manager", func() { config, err := configManager.GenerateConfig() Expect(err).NotTo(HaveOccurred()) - _, err = configManager.PersistMultusConfig(config) - Expect(err).NotTo(HaveOccurred()) - ctx, cancel := context.WithCancel(context.Background()) - configWatcherDoneChannel := make(chan struct{}) - go func(ctx context.Context, doneChannel chan struct{}) { - err := configManager.MonitorPluginConfiguration(ctx, doneChannel) - Expect(err).NotTo(HaveOccurred()) - }(ctx, configWatcherDoneChannel) + defer cancel() + err = configManager.Start(ctx, wg) + Expect(err).NotTo(HaveOccurred()) updatedCNIConfig := ` { @@ -129,9 +129,6 @@ var _ = Describe("Configuration Manager", func() { file, err := os.ReadFile(configManager.multusConfigFilePath) Expect(err).NotTo(HaveOccurred()) Expect(string(file)).To(Equal(config)) - - // stop groutine - cancel() }) When("the user requests the name of the multus configuration to be overridden", func() {