agent/statemanager/state_manager.go
func (manager *basicStateManager) Load() error {
	s := manager.state
	log.Info("Loading state!")
	data, err := manager.readFile()
	if err != nil {
		log.Error("Error reading existing state file", "err", err)
		return err
	}
	if data == nil {
		return nil
	}
	// Dry-run to make sure this is a version we can understand
	err = manager.dryRun(data)
	if err != nil {
		return err
	}
	// Now load it into the actual state. The reason we do this with the
	// intermediate state is that we *must* unmarshal directly into the
	// "saveable" pointers we were given in AddSaveable; if we unmarshal
	// directly into a map with values of pointers, those pointers are lost.
	// We *must* unmarshal this way because the existing pointers could have
	// semi-initialized data (and are actually expected to)

	var intermediate intermediateState
	err = json.Unmarshal(data, &intermediate)
	if err != nil {
		log.Debug("Could not unmarshal into intermediate")
		return err
	}

	for key, rawJSON := range intermediate.Data {
		actualPointer, ok := manager.state.Data[key]
		if !ok {
			log.Error("Loading state: potentially malformed json key of " + key)
			continue
		}
		err = json.Unmarshal(rawJSON, actualPointer)
		if err != nil {
			log.Debug("Could not unmarshal into actual")
			return err
		}
	}

	log.Debug("Loaded state!", "state", s)
	return nil
}
func (manager *basicStateManager) Load() error {
	s := manager.state
	log.Info("Loading state!")
	data, err := manager.readFile()
	if err != nil {
		log.Error("Error reading existing state file", "err", err)
		return err
	}
	if data == nil {
		return nil
	}
	// Dry-run to make sure this is a version we can understand
	err = manager.dryRun(data)
	if err != nil {
		return err
	}
	// Now load it into the actual state. The reason we do this with the
	// intermediate state is that we *must* unmarshal directly into the
	// "saveable" pointers we were given in AddSaveable; if we unmarshal
	// directly into a map with values of pointers, those pointers are lost.
	// We *must* unmarshal this way because the existing pointers could have
	// semi-initialized data (and are actually expected to)

	var intermediate intermediateState
	err = json.Unmarshal(data, &intermediate)
	if err != nil {
		log.Debug("Could not unmarshal into intermediate")
		return err
	}

	for key, rawJSON := range intermediate.Data {
		actualPointer, ok := manager.state.Data[key]
		if !ok {
			log.Error("Loading state: potentially malformed json key of " + key)
			continue
		}
		err = json.Unmarshal(rawJSON, actualPointer)
		if err != nil {
			log.Debug("Could not unmarshal into actual")
			return err
		}
	}

	log.Debug("Loaded state!", "state", s)
	return nil
}
// Load reads state off the disk from the well-known filepath and loads it into
// the passed State object.