func autoUpgrade(cfg *config.Wrapper) { timer := time.NewTimer(0) sub := events.Default.Subscribe(events.DeviceConnected) for { select { case event := <-sub.C(): data, ok := event.Data.(map[string]string) if !ok || data["clientName"] != "syncthing" || upgrade.CompareVersions(data["clientVersion"], Version) != upgrade.Newer { continue } l.Infof("Connected to device %s with a newer version (current %q < remote %q). Checking for upgrades.", data["id"], Version, data["clientVersion"]) case <-timer.C: } rel, err := upgrade.LatestRelease(cfg.Options().ReleasesURL, Version) if err == upgrade.ErrUpgradeUnsupported { events.Default.Unsubscribe(sub) return } if err != nil { // Don't complain too loudly here; we might simply not have // internet connectivity, or the upgrade server might be down. l.Infoln("Automatic upgrade:", err) timer.Reset(time.Duration(cfg.Options().AutoUpgradeIntervalH) * time.Hour) continue } if upgrade.CompareVersions(rel.Tag, Version) != upgrade.Newer { // Skip equal, older or majorly newer (incompatible) versions timer.Reset(time.Duration(cfg.Options().AutoUpgradeIntervalH) * time.Hour) continue } l.Infof("Automatic upgrade (current %q < latest %q)", Version, rel.Tag) err = upgrade.To(rel) if err != nil { l.Warnln("Automatic upgrade:", err) timer.Reset(time.Duration(cfg.Options().AutoUpgradeIntervalH) * time.Hour) continue } events.Default.Unsubscribe(sub) l.Warnf("Automatically upgraded to version %q. Restarting in 1 minute.", rel.Tag) time.Sleep(time.Minute) stop <- exitUpgrading return } }
func performUpgrade(release upgrade.Release) { // Use leveldb database locks to protect against concurrent upgrades _, err := db.Open(locations[locDatabase]) if err == nil { err = upgrade.To(release) if err != nil { l.Fatalln("Upgrade:", err) } l.Infof("Upgraded to %q", release.Tag) } else { l.Infoln("Attempting upgrade through running Syncthing...") err = upgradeViaRest() if err != nil { l.Fatalln("Upgrade:", err) } l.Infoln("Syncthing upgrading") os.Exit(exitUpgrading) } }
func (s *apiService) postSystemUpgrade(w http.ResponseWriter, r *http.Request) { rel, err := upgrade.LatestRelease(s.cfg.Options().ReleasesURL, Version) if err != nil { l.Warnln("getting latest release:", err) http.Error(w, err.Error(), 500) return } if upgrade.CompareVersions(rel.Tag, Version) > upgrade.Equal { err = upgrade.To(rel) if err != nil { l.Warnln("upgrading:", err) http.Error(w, err.Error(), 500) return } s.flushResponse(`{"ok": "restarting"}`, w) l.Infoln("Upgrading") stop <- exitUpgrading } }