diff --git a/pkg/acquisition/modules/file/config.go b/pkg/acquisition/modules/file/config.go index 25e9b02e961..682f9e2c451 100644 --- a/pkg/acquisition/modules/file/config.go +++ b/pkg/acquisition/modules/file/config.go @@ -85,9 +85,23 @@ func (s *Source) Configure(_ context.Context, yamlConfig []byte, logger *log.Ent s.tailMapMutex = &sync.RWMutex{} s.tails = make(map[string]bool) - s.watcher, err = fsnotify.NewWatcher() - if err != nil { - return fmt.Errorf("could not create fsnotify watcher: %w", err) + if s.config.Mode == configuration.TAIL_MODE { + s.watcher, err = fsnotify.NewWatcher() + if err != nil { + return fmt.Errorf("could not create fsnotify watcher: %w", err) + } + + defer func() { + if err == nil || s.watcher == nil { + return + } + + if closeErr := s.watcher.Close(); closeErr != nil { + s.logger.Errorf("could not close fsnotify watcher after configure failure: %s", closeErr) + } + + s.watcher = nil + }() } s.logger.Tracef("Actual FileAcquisition Configuration %+v", s.config) diff --git a/pkg/acquisition/modules/file/config_internal_test.go b/pkg/acquisition/modules/file/config_internal_test.go new file mode 100644 index 00000000000..562c40f7af2 --- /dev/null +++ b/pkg/acquisition/modules/file/config_internal_test.go @@ -0,0 +1,45 @@ +package fileacquisition + +import ( + "testing" + + "github.com/fsnotify/fsnotify" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/crowdsecurity/crowdsec/pkg/metrics" +) + +func TestConfigureCatModeDoesNotCreateWatcher(t *testing.T) { + ctx := t.Context() + f := &Source{} + + err := f.Configure(ctx, []byte(` +mode: cat +filename: testdata/test.log +`), log.NewEntry(log.New()), metrics.AcquisitionMetricsLevelNone) + require.NoError(t, err) + + assert.Nil(t, f.watcher) +} + +func TestConfigureClosesWatcherOnTailModeError(t *testing.T) { + ctx := t.Context() + f := &Source{} + + probe, err := fsnotify.NewWatcher() + if err != nil { + t.Skipf("cannot allocate fsnotify watcher in this environment: %v", err) + } + + require.NoError(t, probe.Close()) + + err = f.Configure(ctx, []byte(` +mode: tail +filename: "[*-.log" +`), log.NewEntry(log.New()), metrics.AcquisitionMetricsLevelNone) + require.ErrorContains(t, err, "glob failure: syntax error in pattern") + + assert.Nil(t, f.watcher) +}