func()

in pkg/agent/agent.go [300:394]


func (a *Agent) realize(in *intent.Intent) error {
	log := a.log.WithFields(logrus.Fields{
		"worker": "handler",
		"intent": in.DisplayString(),
	})

	log.Debug("handling intent")

	var err error

	// TODO: Run a quick check of the Nodes posted progress before proceeding

	// ACK the wanted action.
	in.Active = in.Wanted
	in.State = marker.NodeStateBusy
	err = a.postIntent(in)
	if err != nil {
		return err
	}

	// TODO: Propagate status from realization and periodically
	switch in.Wanted {
	case marker.NodeActionReset:
		a.progress.Reset()

	case marker.NodeActionPrepareUpdate:
		var ups platform.Available
		ups, err = a.platform.ListAvailable()
		if err != nil {
			break
		}
		if len(ups.Updates()) == 0 {
			err = errInvalidProgress
			break
		}
		a.progress.SetTarget(ups.Updates()[0])
		log.Debug("preparing update")
		err = a.platform.Prepare(a.progress.GetTarget())

	case marker.NodeActionPerformUpdate:
		if !a.progress.Valid() {
			err = errInvalidProgress
			break
		}
		log.Debug("updating")
		err = a.platform.Update(a.progress.GetTarget())

	case marker.NodeActionUnknown, marker.NodeActionStabilize:
		log.Debug("sitrep")
		err = platform.Ping(a.platform)
		if err != nil {
			break
		}
		hasUpdate, err := a.checkUpdate()
		if err != nil {
			log.WithError(err).Error("update check failed")
		}
		in.SetUpdateAvailable(hasUpdate)

	case marker.NodeActionRebootUpdate:
		if !a.progress.Valid() {
			err = errInvalidProgress
			break
		}
		log.Debug("rebooting")
		log.Info("Rebooting Node to complete update")
		// TODO: ensure Node is setup to be validated on boot (ie: kubelet will
		// run agent again before we let other Pods get scheduled)
		err = a.platform.BootUpdate(a.progress.GetTarget(), true)
		// Shortcircuit to terminate.

		// TODO: actually handle shutdown.
		if err == nil {
			if a.proc != nil {
				defer a.proc.KillProcess()
			}
			return err
		}
	}

	if err != nil {
		log.WithError(err).Error("could not realize intent")
		in.State = marker.NodeStateError
	} else {
		log.Debug("realized intent")
		in.State = marker.NodeStateReady
	}

	postErr := a.postIntent(in)
	if postErr != nil {
		log.WithError(postErr).Error("could not update intent")
	}

	return err
}