Example #1
0
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()
}
Example #2
0
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
}
Example #3
0
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")
}
Example #4
0
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()
	}
}
Example #6
0
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
}
Example #7
0
// 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
}
Example #8
0
func (d *device) CommitUpdate() error {
	log.Info("Commiting update")
	// For now set only appropriate boot flags
	return d.WriteEnv(BootVars{"upgrade_available": "0"})
}