@@ -26,6 +26,7 @@ import (
2626
2727 "k8s.io/klog/v2"
2828
29+ "github.com/fsnotify/fsnotify"
2930 nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
3031 "sigs.k8s.io/node-feature-discovery/pkg/utils"
3132 "sigs.k8s.io/node-feature-discovery/source"
@@ -65,10 +66,11 @@ var (
6566 featureFilesDir = "/etc/kubernetes/node-feature-discovery/features.d/"
6667)
6768
68- // localSource implements the FeatureSource and LabelSource interfaces.
69+ // localSource implements the FeatureSource, LabelSource, EventSource interfaces.
6970type localSource struct {
70- features * nfdv1alpha1.Features
71- config * Config
71+ features * nfdv1alpha1.Features
72+ config * Config
73+ fsWatcher * fsnotify.Watcher
7274}
7375
7476type Config struct {
8789 _ source.FeatureSource = & src
8890 _ source.LabelSource = & src
8991 _ source.ConfigurableSource = & src
92+ _ source.EventSource = & src
9093)
9194
9295// Name method of the LabelSource interface
@@ -318,6 +321,47 @@ func getFileContent(fileName string) ([][]byte, error) {
318321 return lines , nil
319322}
320323
324+ func (s * localSource ) runNotifier (ch chan struct {}) {
325+ for {
326+ select {
327+ case event := <- s .fsWatcher .Events :
328+ if event .Op & fsnotify .Create == fsnotify .Create || event .Op & fsnotify .Write == fsnotify .Write || event .Op & fsnotify .Remove == fsnotify .Remove || event .Op & fsnotify .Rename == fsnotify .Rename || event .Op & fsnotify .Chmod == fsnotify .Chmod {
329+ klog .InfoS ("fsnotify event" , event )
330+ ch <- struct {}{}
331+ }
332+ case err := <- s .fsWatcher .Errors :
333+ klog .ErrorS (err , "failed to to watch features.d changes" )
334+ }
335+ }
336+ }
337+
338+ // SetChannel method of the EventSource Interface
339+ func (s * localSource ) SetChannel (ch chan struct {}) error {
340+ info , err := os .Stat (featureFilesDir )
341+ if err != nil {
342+ if ! os .IsNotExist (err ) {
343+ return err
344+ }
345+ }
346+
347+ if info != nil && info .IsDir () {
348+ watcher , err := fsnotify .NewWatcher ()
349+ if err != nil {
350+ return err
351+ }
352+
353+ err = watcher .Add (featureFilesDir )
354+ if err != nil {
355+ return fmt .Errorf ("unable to access %v: %w" , featureFilesDir , err )
356+ }
357+ s .fsWatcher = watcher
358+ }
359+
360+ go s .runNotifier (ch )
361+
362+ return nil
363+ }
364+
321365func init () {
322366 source .Register (& src )
323367}
0 commit comments