cdcb249449
* add config watcher to the config package * add logging to watcher * add test and refactor to add WatcherEvent. * add all API calls and fix a bug with recreated files * add tests for watcher * remove the unnecessary use of context * Add debug log and a test for file rename * use inode to detect if the file is recreated/replaced and only listen to create events. * tidy ups (#1535) * tidy ups * Add tests for inode reconcile * fix linux vs windows syscall * fix linux vs windows syscall * fix windows compile error * increase timeout * use ctime ID * remove remove/creation test as it's a use case that fail in linux * fix linux/windows to use Ino/CreationTime * fix the watcher to only overwrite current file id * fix linter error * fix remove/create test * set reconcile loop to 200 Milliseconds * fix watcher to not trigger event on remove, add more tests * on a remove event try to add the file back to the watcher and trigger the handler if success * fix race condition * fix flaky test * fix race conditions * set level to info * fix when file is removed and get an event for it after * fix to trigger handler when we get a remove but re-add fail * fix error message * add tests for directory watch and fixes * detect if a file is a symlink and return an error on Add * rename Watcher to FileWatcher and remove symlink deref * add fsnotify@v1.5.1 * fix go mod * do not reset timer on errors, rename OS specific files * rename New func * events trigger on write and rename * add missing test * fix flaking tests * fix flaky test * check reconcile when removed * delete invalid file * fix test to create files with different mod time. * back date file instead of sleeping * add watching file in agent command. * fix watcher call to use new API * add configuration and stop watcher when server stop * add certs as watched files * move FileWatcher to the agent start instead of the command code * stop watcher before replacing it * save watched files in agent * add add and remove interfaces to the file watcher * fix remove to not return an error * use `Add` and `Remove` to update certs files * fix tests * close events channel on the file watcher even when the context is done * extract `NotAutoReloadableRuntimeConfig` is a separate struct * fix linter errors * add Ca configs and outgoing verify to the not auto reloadable config * add some logs and fix to use background context * add tests to auto-config reload * remove stale test * add tests to changes to config files * add check to see if old cert files still trigger updates * rename `NotAutoReloadableRuntimeConfig` to `StaticRuntimeConfig` * fix to re add both key and cert file. Add test to cover this case. * review suggestion Co-authored-by: R.B. Boyer <4903+rboyer@users.noreply.github.com> * add check to static runtime config changes * fix test * add changelog file * fix review comments * Apply suggestions from code review Co-authored-by: R.B. Boyer <4903+rboyer@users.noreply.github.com> * update flag description Co-authored-by: FFMMM <FFMMM@users.noreply.github.com> * fix compilation error * add static runtime config support * fix test * fix review comments * fix log test * Update .changelog/12329.txt Co-authored-by: Dan Upton <daniel@floppy.co> * transfer tests to runtime_test.go * fix filewatcher Replace to not deadlock. * avoid having lingering locks Co-authored-by: R.B. Boyer <4903+rboyer@users.noreply.github.com> * split ReloadConfig func * fix warning message Co-authored-by: R.B. Boyer <4903+rboyer@users.noreply.github.com> * convert `FileWatcher` into an interface * fix compilation errors * fix tests * extract func for adding and removing files * add a coalesceTimer with a very small timer * extract coaelsce Timer and add a shim for testing * add tests to coalesceTimer fix to send remaining events * set `coalesceTimer` to 1 Second * support symlink, fix a nil deref. * fix compile error * fix compile error * refactor file watcher rate limiting to be a Watcher implementation * fix linter issue * fix runtime config * fix runtime test * fix flaky tests * fix compile error * Apply suggestions from code review Co-authored-by: R.B. Boyer <4903+rboyer@users.noreply.github.com> * fix agent New to return an error if File watcher New return an error * quit timer loop if ctx is canceled * Apply suggestions from code review Co-authored-by: Chris S. Kim <ckim@hashicorp.com> Co-authored-by: Ashwin Venkatesh <ashwin@hashicorp.com> Co-authored-by: R.B. Boyer <4903+rboyer@users.noreply.github.com> Co-authored-by: FFMMM <FFMMM@users.noreply.github.com> Co-authored-by: Daniel Upton <daniel@floppy.co> Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
91 lines
2.2 KiB
Go
91 lines
2.2 KiB
Go
package config
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/hashicorp/go-hclog"
|
|
)
|
|
|
|
type rateLimitedFileWatcher struct {
|
|
watcher Watcher
|
|
eventCh chan *FileWatcherEvent
|
|
coalesceInterval time.Duration
|
|
}
|
|
|
|
func (r *rateLimitedFileWatcher) Start(ctx context.Context) {
|
|
r.watcher.Start(ctx)
|
|
r.coalesceTimer(ctx, r.watcher.EventsCh(), r.coalesceInterval)
|
|
}
|
|
|
|
func (r rateLimitedFileWatcher) Stop() error {
|
|
return r.watcher.Stop()
|
|
}
|
|
|
|
func (r rateLimitedFileWatcher) Add(filename string) error {
|
|
return r.watcher.Add(filename)
|
|
}
|
|
|
|
func (r rateLimitedFileWatcher) Remove(filename string) {
|
|
r.watcher.Remove(filename)
|
|
}
|
|
|
|
func (r rateLimitedFileWatcher) Replace(oldFile, newFile string) error {
|
|
return r.watcher.Replace(oldFile, newFile)
|
|
}
|
|
|
|
func (r rateLimitedFileWatcher) EventsCh() chan *FileWatcherEvent {
|
|
return r.eventCh
|
|
}
|
|
|
|
func NewRateLimitedFileWatcher(configFiles []string, logger hclog.Logger, coalesceInterval time.Duration) (Watcher, error) {
|
|
|
|
watcher, err := NewFileWatcher(configFiles, logger)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &rateLimitedFileWatcher{
|
|
watcher: watcher,
|
|
coalesceInterval: coalesceInterval,
|
|
eventCh: make(chan *FileWatcherEvent),
|
|
}, nil
|
|
}
|
|
|
|
func (r rateLimitedFileWatcher) coalesceTimer(ctx context.Context, inputCh chan *FileWatcherEvent, coalesceDuration time.Duration) {
|
|
var (
|
|
coalesceTimer *time.Timer
|
|
sendCh = make(chan struct{})
|
|
fileWatcherEvents []string
|
|
)
|
|
|
|
go func() {
|
|
for {
|
|
select {
|
|
case event, ok := <-inputCh:
|
|
if !ok {
|
|
if len(fileWatcherEvents) > 0 {
|
|
r.eventCh <- &FileWatcherEvent{Filenames: fileWatcherEvents}
|
|
}
|
|
close(r.eventCh)
|
|
return
|
|
}
|
|
fileWatcherEvents = append(fileWatcherEvents, event.Filenames...)
|
|
if coalesceTimer == nil {
|
|
coalesceTimer = time.AfterFunc(coalesceDuration, func() {
|
|
// This runs in another goroutine so we can't just do the send
|
|
// directly here as access to fileWatcherEvents is racy. Instead,
|
|
// signal the main loop above.
|
|
sendCh <- struct{}{}
|
|
})
|
|
}
|
|
case <-sendCh:
|
|
coalesceTimer = nil
|
|
r.eventCh <- &FileWatcherEvent{Filenames: fileWatcherEvents}
|
|
fileWatcherEvents = make([]string, 0)
|
|
case <-ctx.Done():
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
}
|