func autoUpdate(s mvc.State, token string) { up, err := update.New().VerifySignatureWithPEM([]byte(publicKey)) if err != nil { log.Error("Failed to create update with signature: %v", err) return } update := func() (tryAgain bool) { log.Info("Checking for update") params := check.Params{ AppId: appId, AppVersion: version.MajorMinor(), UserId: token, } result, err := params.CheckForUpdate(updateEndpoint, up) if err == check.NoUpdateAvailable { log.Info("No update available") return true } else if err != nil { log.Error("Error while checking for update: %v", err) return true } if result.Initiative == check.INITIATIVE_AUTO { if err := up.CanUpdate(); err != nil { log.Error("Can't update: insufficient permissions: %v", err) // tell the user to update manually s.SetUpdateStatus(mvc.UpdateAvailable) } else { applyUpdate(s, result) } } else if result.Initiative == check.INITIATIVE_MANUAL { // this is the way the server tells us to update manually log.Info("Server wants us to update manually") s.SetUpdateStatus(mvc.UpdateAvailable) } else { log.Info("Update available, but ignoring") } // stop trying after a single download attempt // XXX: improve this so the we can: // 1. safely update multiple times // 2. only retry after temporary errors return false } // try to update immediately and then at a set interval for { if tryAgain := update(); !tryAgain { break } time.Sleep(updateCheckInterval) } }
func (cmd *Updater) Check(channel, version string) (*update.Update, *check.Result, error) { if cmd.EquinoxAppId == "" || cmd.PublicKeyPEM == "" { return nil, nil, fmt.Errorf("Application must be built with a public key and equinox.io app id to enable updating") } up, err := update.New().VerifySignatureWithPEM([]byte(cmd.PublicKeyPEM)) if err != nil { return nil, nil, err } params := check.Params{ AppVersion: version, AppId: cmd.EquinoxAppId, Channel: channel, } result, err := params.CheckForUpdate("https://api.equinox.io/1/Updates", up) return up, result, err }