2022-02-10 09:17:49 -05:00
|
|
|
package cli
|
|
|
|
|
|
|
|
import (
|
2022-03-24 07:49:51 -05:00
|
|
|
"context"
|
|
|
|
|
2022-02-10 09:17:49 -05:00
|
|
|
"github.com/fsnotify/fsnotify"
|
|
|
|
"github.com/rs/zerolog/log"
|
2022-10-20 11:39:20 -05:00
|
|
|
|
2022-02-10 09:17:49 -05:00
|
|
|
"zotregistry.io/zot/pkg/api"
|
|
|
|
"zotregistry.io/zot/pkg/api/config"
|
|
|
|
)
|
|
|
|
|
|
|
|
type HotReloader struct {
|
|
|
|
watcher *fsnotify.Watcher
|
|
|
|
filePath string
|
|
|
|
ctlr *api.Controller
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewHotReloader(ctlr *api.Controller, filePath string) (*HotReloader, error) {
|
|
|
|
// creates a new file watcher
|
|
|
|
watcher, err := fsnotify.NewWatcher()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
hotReloader := &HotReloader{
|
|
|
|
watcher: watcher,
|
|
|
|
filePath: filePath,
|
|
|
|
ctlr: ctlr,
|
|
|
|
}
|
|
|
|
|
|
|
|
return hotReloader, nil
|
|
|
|
}
|
|
|
|
|
2022-03-24 07:49:51 -05:00
|
|
|
func (hr *HotReloader) Start() context.Context {
|
2022-02-10 09:17:49 -05:00
|
|
|
done := make(chan bool)
|
2022-03-24 07:49:51 -05:00
|
|
|
|
|
|
|
reloadCtx, cancelOnReloadFunc := context.WithCancel(context.Background())
|
2022-02-10 09:17:49 -05:00
|
|
|
// run watcher
|
|
|
|
go func() {
|
|
|
|
defer hr.watcher.Close()
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
// watch for events
|
|
|
|
case event := <-hr.watcher.Events:
|
|
|
|
if event.Op == fsnotify.Write {
|
|
|
|
log.Info().Msg("config file changed, trying to reload config")
|
|
|
|
|
|
|
|
newConfig := config.New()
|
|
|
|
|
|
|
|
err := LoadConfiguration(newConfig, hr.filePath)
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Err(err).Msg("couldn't reload config, retry writing it.")
|
|
|
|
|
|
|
|
continue
|
|
|
|
}
|
2022-03-24 07:49:51 -05:00
|
|
|
// if valid config then reload
|
|
|
|
cancelOnReloadFunc()
|
2022-02-10 09:17:49 -05:00
|
|
|
|
2022-03-24 07:49:51 -05:00
|
|
|
// create new context
|
|
|
|
reloadCtx, cancelOnReloadFunc = context.WithCancel(context.Background())
|
|
|
|
hr.ctlr.LoadNewConfig(reloadCtx, newConfig)
|
2022-02-10 09:17:49 -05:00
|
|
|
}
|
|
|
|
// watch for errors
|
|
|
|
case err := <-hr.watcher.Errors:
|
|
|
|
log.Error().Err(err).Msgf("fsnotfy error while watching config %s", hr.filePath)
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
if err := hr.watcher.Add(hr.filePath); err != nil {
|
|
|
|
log.Error().Err(err).Msgf("error adding config file %s to FsNotify watcher", hr.filePath)
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
<-done
|
|
|
|
}()
|
2022-03-24 07:49:51 -05:00
|
|
|
|
|
|
|
return reloadCtx
|
2022-02-10 09:17:49 -05:00
|
|
|
}
|