From 32075dcb7ba761773654d95b7b2057b81d456554 Mon Sep 17 00:00:00 2001 From: Maximilian Hafer Date: Wed, 11 Sep 2024 11:02:45 +0200 Subject: [PATCH] implement inotify support --- .gitignore | 1 + go.mod | 1 + go.sum | 2 ++ main.go | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 62 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 559f9e1..2fff045 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ supercronic vendor dist/* +.idea \ No newline at end of file diff --git a/go.mod b/go.mod index 660dbd6..4407503 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.23.0 require ( github.com/evalphobia/logrus_sentry v0.8.2 + github.com/fsnotify/fsnotify v1.7.0 github.com/prometheus/client_golang v1.20.2 github.com/ramr/go-reaper v0.2.1 github.com/sirupsen/logrus v1.9.3 diff --git a/go.sum b/go.sum index c31c7d1..2e05da5 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/evalphobia/logrus_sentry v0.8.2 h1:dotxHq+YLZsT1Bb45bB5UQbfCh3gM/nFFetyN46VoDQ= github.com/evalphobia/logrus_sentry v0.8.2/go.mod h1:pKcp+vriitUqu9KiWj/VRFbRfFNUwz95/UkgG8a6MNc= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= diff --git a/main.go b/main.go index d83033f..7b224d3 100644 --- a/main.go +++ b/main.go @@ -15,6 +15,7 @@ import ( "github.com/aptible/supercronic/log/hook" "github.com/aptible/supercronic/prometheus_metrics" "github.com/evalphobia/logrus_sentry" + "github.com/fsnotify/fsnotify" reaper "github.com/ramr/go-reaper" "github.com/sirupsen/logrus" ) @@ -29,6 +30,7 @@ func main() { quiet := flag.Bool("quiet", false, "do not log informational messages (takes precedence over debug)") json := flag.Bool("json", false, "enable JSON logging") test := flag.Bool("test", false, "test crontab (does not run jobs)") + inotify := flag.Bool("inotify", false, "use inotify to detect crontab file changes") prometheusListen := flag.String( "prometheus-listen-address", "", @@ -102,6 +104,24 @@ func main() { crontabFileName := flag.Args()[0] + var watcher *fsnotify.Watcher + if *inotify { + logrus.Info("using inotify to detect crontab file changes") + var err error + watcher, err = fsnotify.NewWatcher() + if err != nil { + logrus.Fatal(err) + return + } + defer watcher.Close() + + logrus.Infof("adding file watch for '%s'", crontabFileName) + if err := watcher.Add(crontabFileName); err != nil { + logrus.Fatal(err) + return + } + } + var sentryHook *logrus_sentry.SentryHook if sentryDsn != "" { sentryLevels := []logrus.Level{ @@ -149,6 +169,44 @@ func main() { go reaper.Reap() // _ = reaper.Reap + termChan := make(chan os.Signal, 1) + signal.Notify(termChan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGUSR2) + + if *inotify { + go func() { + for { + select { + case event, ok := <-watcher.Events: + if !ok { + return + } + logrus.Debugf("event: %v, watch-list: %v", event, watcher.WatchList()) + + switch event.Op { + case event.Op & fsnotify.Write: + logrus.Debug("watched file changed") + termChan <- syscall.SIGUSR2 + + // workaround for k8s configmap and secret mounts + case event.Op & fsnotify.Remove: + logrus.Debug("watched file changed") + if err := watcher.Add(event.Name); err != nil { + logrus.Fatal(err) + return + } + termChan <- syscall.SIGUSR2 + } + + case err, ok := <-watcher.Errors: + if !ok { + return + } + logrus.Error("error:", err) + } + } + }() + } + for { promMetrics.Reset() @@ -179,9 +237,6 @@ func main() { cron.StartJob(&wg, tab.Context, job, exitCtx, cronLogger, *overlapping, *passthroughLogs, &promMetrics) } - termChan := make(chan os.Signal, 1) - signal.Notify(termChan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGUSR2) - termSig := <-termChan if termSig == syscall.SIGUSR2 {