Files
zot/pkg/cli/server/config_reloader.go
T
Luca Muscariello 2402296e9a fix: migrate to Go module v2 for proper semantic versioning (#3462)
* fix: migrate to Go module v2 for proper semantic versioning

This change updates the module path from 'zotregistry.dev/zot' to
'zotregistry.dev/zot/v2' to comply with Go's semantic versioning rules.

According to Go's module versioning requirements, major version v2+
must include the major version in the module path. The current
module path 'zotregistry.dev/zot' only supports v0.x.x and v1.x.x
versions, making existing v2.x.x tags (like v2.1.8) unusable.

Changes:
- Updated go.mod module path to zotregistry.dev/zot/v2
- Updated all internal import paths across 280+ Go source files
- Updated configuration files (golangcilint.yaml, gqlgen.yml)
- Updated README.md Go reference badge

This fix enables proper use of existing v2.x.x Git tags and allows
external packages to import zot v2+ versions without compatibility
errors.

Resolves: Go module import compatibility for v2+ versions
Fixes: #3071
Signed-off-by: Luca Muscariello <muscariello@ieee.org>

* fix: regenerate GraphQL files with updated v2 import paths

The gqlgen tool needs to regenerate the GraphQL schema files after
the module path change to use the new v2 imports.

Signed-off-by: Luca Muscariello <muscariello@ieee.org>

---------

Signed-off-by: Luca Muscariello <muscariello@ieee.org>
2025-10-16 22:43:47 -07:00

132 lines
3.5 KiB
Go

package server
import (
"errors"
"os"
"os/signal"
"syscall"
"github.com/fsnotify/fsnotify"
"zotregistry.dev/zot/v2/pkg/api"
"zotregistry.dev/zot/v2/pkg/api/config"
"zotregistry.dev/zot/v2/pkg/log"
)
type HotReloader struct {
watcher *fsnotify.Watcher
configPath string
ldapCredentialsPath string
ctlr *api.Controller
logger log.Logger
}
func NewHotReloader(ctlr *api.Controller, filePath, ldapCredentialsPath string) (*HotReloader, error) {
// creates a new file watcher
watcher, err := fsnotify.NewWatcher()
if err != nil {
return nil, err
}
hotReloader := &HotReloader{
watcher: watcher,
configPath: filePath,
ldapCredentialsPath: ldapCredentialsPath,
ctlr: ctlr,
logger: log.NewLogger("info", ""),
}
return hotReloader, nil
}
func signalHandler(ctlr *api.Controller, sigCh chan os.Signal) {
// if signal then shutdown
if sig, ok := <-sigCh; ok {
ctlr.Log.Info().Interface("signal", sig).Msg("received signal")
// gracefully shutdown http server
ctlr.Shutdown() //nolint: contextcheck
}
}
func initShutDownRoutine(ctlr *api.Controller) {
sigCh := make(chan os.Signal, 1)
go signalHandler(ctlr, sigCh)
// block all async signals to this server
signal.Ignore()
// handle SIGINT and SIGHUP.
signal.Notify(sigCh, syscall.SIGTERM, syscall.SIGINT, syscall.SIGHUP)
}
func (hr *HotReloader) Start() {
done := make(chan bool)
// 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 {
hr.logger.Info().Msg("config file changed, trying to reload config")
newConfig := config.New()
err := LoadConfiguration(newConfig, hr.configPath)
if err != nil {
hr.logger.Error().Err(err).Msg("failed to reload config, retry writing it.")
continue
}
if hr.ctlr.Config.HTTP.Auth != nil && hr.ctlr.Config.HTTP.Auth.LDAP != nil &&
hr.ctlr.Config.HTTP.Auth.LDAP.CredentialsFile != newConfig.HTTP.Auth.LDAP.CredentialsFile {
err = hr.watcher.Remove(hr.ctlr.Config.HTTP.Auth.LDAP.CredentialsFile)
if err != nil && !errors.Is(err, fsnotify.ErrNonExistentWatch) {
hr.logger.Error().Err(err).Msg("failed to remove old watch for the credentials file")
}
err = hr.watcher.Add(newConfig.HTTP.Auth.LDAP.CredentialsFile)
if err != nil {
hr.logger.Panic().Err(err).Str("ldap-credentials-file", newConfig.HTTP.Auth.LDAP.CredentialsFile).
Msg("failed to watch ldap credentials file")
}
}
// stop background tasks gracefully
hr.ctlr.StopBackgroundTasks()
// load new config
hr.ctlr.LoadNewConfig(newConfig)
// start background tasks based on new loaded config
hr.ctlr.StartBackgroundTasks()
}
// watch for errors
case err := <-hr.watcher.Errors:
hr.logger.Panic().Err(err).Str("config", hr.configPath).Msg("fsnotfy error while watching config")
}
}
}()
if err := hr.watcher.Add(hr.configPath); err != nil {
hr.logger.Panic().Err(err).Str("config", hr.configPath).Msg("failed to add config file to fsnotity watcher")
}
if hr.ldapCredentialsPath != "" {
if err := hr.watcher.Add(hr.ldapCredentialsPath); err != nil {
hr.logger.Panic().Err(err).Str("ldap-credentials", hr.ldapCredentialsPath).
Msg("failed to add ldap-credentials to fsnotity watcher")
}
}
<-done
}()
}