diff --git a/cmd/syncthing/gui.go b/cmd/syncthing/gui.go index 6d5a204a..93aa0614 100644 --- a/cmd/syncthing/gui.go +++ b/cmd/syncthing/gui.go @@ -332,34 +332,7 @@ func restPostConfig(m *model.Model, w http.ResponseWriter, r *http.Request) { } } - // Figure out if any changes require a restart - - if len(cfg.Repositories) != len(newCfg.Repositories) { - configInSync = false - } else { - om := cfg.RepoMap() - nm := newCfg.RepoMap() - for id := range om { - if !reflect.DeepEqual(om[id], nm[id]) { - configInSync = false - break - } - } - } - - if len(cfg.Nodes) != len(newCfg.Nodes) { - configInSync = false - } else { - om := cfg.NodeMap() - nm := newCfg.NodeMap() - for k := range om { - if _, ok := nm[k]; !ok { - // A node was removed and another added - configInSync = false - break - } - } - } + // Start or stop usage reporting as appropriate if newCfg.Options.URAccepted > cfg.Options.URAccepted { // UR was enabled @@ -375,12 +348,9 @@ func restPostConfig(m *model.Model, w http.ResponseWriter, r *http.Request) { stopUsageReporting() } - if !reflect.DeepEqual(cfg.Options, newCfg.Options) || !reflect.DeepEqual(cfg.GUI, newCfg.GUI) { - configInSync = false - } - // Activate and save + configInSync = !config.ChangeRequiresRestart(cfg, newCfg) newCfg.Location = cfg.Location newCfg.Save() cfg = newCfg diff --git a/config/config.go b/config/config.go index 40d85ddc..01448862 100644 --- a/config/config.go +++ b/config/config.go @@ -423,6 +423,39 @@ func Load(location string, myID protocol.NodeID) (Configuration, error) { return cfg, err } +// ChangeRequiresRestart returns true if updating the configuration requires a +// complete restart. +func ChangeRequiresRestart(from, to Configuration) bool { + // Adding, removing or changing repos requires restart + if len(from.Repositories) != len(to.Repositories) { + return true + } + fromRepos := from.RepoMap() + toRepos := to.RepoMap() + for id := range fromRepos { + if !reflect.DeepEqual(fromRepos[id], toRepos[id]) { + return true + } + } + + // Removing a node requires a restart. Adding one does not. Changing + // address or name does not. + fromNodes := from.NodeMap() + toNodes := to.NodeMap() + for nodeID := range fromNodes { + if _, ok := toNodes[nodeID]; !ok { + return true + } + } + + // All of the generic options require restart + if !reflect.DeepEqual(from.Options, to.Options) || !reflect.DeepEqual(from.GUI, to.GUI) { + return true + } + + return false +} + func convertV3V4(cfg *Configuration) { // In previous versions, rescan interval was common for each repository. // From now, it can be set independently. We have to make sure, that after upgrade