func (m *mender) Authorize() menderError { if m.authMgr.IsAuthorized() { log.Info("authorization data present and valid, skipping authorization attempt") return m.loadAuth() } m.authToken = noAuthToken rsp, err := m.authReq.Request(m.api, m.config.ServerURL, m.authMgr) if err != nil { if err == client.AuthErrorUnauthorized { // make sure to remove auth token once device is rejected if remErr := m.authMgr.RemoveAuthToken(); remErr != nil { log.Warn("can not remove rejected authentication token") } } return NewTransientError(errors.Wrap(err, "authorization request failed")) } err = m.authMgr.RecvAuthResponse(rsp) if err != nil { return NewTransientError(errors.Wrap(err, "failed to parse authorization response")) } log.Info("successfuly received new authorization data") return m.loadAuth() }
func (e *RebootState) Handle(ctx *StateContext, c Controller) (State, bool) { // start deployment logging if err := DeploymentLogger.Enable(e.update.ID); err != nil { return NewUpdateErrorState(NewTransientError(err), e.update), false } if err := StoreStateData(ctx.store, StateData{ Id: e.Id(), UpdateInfo: e.update, }); err != nil { // too late to do anything now, update is installed and enabled, let's play // along and reboot log.Errorf("failed to store state data in reboot state: %v, "+ "continuing with reboot", err) } c.ReportUpdateStatus(e.update, client.StatusRebooting) log.Info("rebooting device") if err := c.Reboot(); err != nil { log.Errorf("error rebooting device: %v", err) return NewErrorState(NewFatalError(err)), false } // we can not reach this point // stop deployment logging DeploymentLogger.Disable() return doneState, false }
func validateGetUpdate(update UpdateResponse) error { // check if we have JSON data correctky decoded if update.ID != "" && update.Image.ID != "" && update.Image.URI != "" && update.Image.YoctoID != "" { log.Info("Correct request for getting image from: " + update.Image.URI) return nil } return errors.New("Missing parameters in encoded JSON response") }
func (rs *RollbackState) Handle(ctx *StateContext, c Controller) (State, bool) { DeploymentLogger.Enable(rs.update.ID) log.Info("performing rollback") // swap active and inactive partitions if err := c.Rollback(); err != nil { log.Errorf("swapping active and inactive partitions failed: %s", err) // TODO: what can we do here return NewErrorState(NewFatalError(err)), false } DeploymentLogger.Disable() return NewRebootState(rs.update), false }
func TestDeploymentLoggingHook(t *testing.T) { tempDir, _ := ioutil.TempDir("", "logs") defer os.RemoveAll(tempDir) deploymentLogger := NewDeploymentLogManager(tempDir) log.AddHook(NewDeploymentLogHook(deploymentLogger)) log.Info("test1") deploymentLogger.Enable("1111-2222") logFile := fmt.Sprintf(logFileNameScheme, 1, "1111-2222") fileLocation := path.Join(tempDir, logFile) log.Debug("test2") deploymentLogger.Disable() log.Info("test3") // test correct format of log messages if !logFileContains(fileLocation, `{"level":"debug","message":"test2","timestamp":"`) { t.FailNow() } }
func (d *device) EnableUpdatedPartition() error { inactivePartition, err := d.getInactivePartition() if err != nil { return err } log.Info("Enabling partition with new image installed to be a boot candidate: ", string(inactivePartition)) // For now we are only setting boot variables err = d.WriteEnv(BootVars{"upgrade_available": "1", "mender_boot_part": inactivePartition, "bootcount": "0"}) if err != nil { return err } log.Debug("Marking inactive partition as a boot candidate successful.") return nil }
// Check if new update is available. In case of errors, returns nil and error // that occurred. If no update is available *UpdateResponse is nil, otherwise it // contains update information. func (m *mender) CheckUpdate() (*client.UpdateResponse, menderError) { currentImageID := m.GetCurrentImageID() //TODO: if currentImageID == "" { // return errors.New("") // } haveUpdate, err := m.updater.GetScheduledUpdate(m.api.Request(m.authToken), m.config.ServerURL) if err != nil { // remove authentication token if device is not authorized if err == client.ErrNotAuthorized { if remErr := m.authMgr.RemoveAuthToken(); remErr != nil { log.Warn("can not remove rejected authentication token") } } log.Error("Error receiving scheduled update data: ", err) return nil, NewTransientError(err) } if haveUpdate == nil { log.Debug("no updates available") return nil, nil } update, ok := haveUpdate.(client.UpdateResponse) if !ok { return nil, NewTransientError(errors.Errorf("not an update response?")) } log.Debugf("received update response: %v", update) if update.Image.YoctoID == currentImageID { log.Info("Attempting to upgrade to currently installed image ID, not performing upgrade.") return &update, NewTransientError(os.ErrExist) } return &update, nil }
func (d *device) CommitUpdate() error { log.Info("Commiting update") // For now set only appropriate boot flags return d.WriteEnv(BootVars{"upgrade_available": "0"}) }