code: func (a *Agent) setupNodeID(config *config.RuntimeConfig) error {
  	// If they've configured a node ID manually then just use that, as
  	// long as it's valid.
  	if config.NodeID != "" {
  		config.NodeID = types.NodeID(strings.ToLower(string(config.NodeID)))
  		if _, err := uuid.ParseUUID(string(config.NodeID)); err != nil {
  			return err
  		}
  
  		return nil
  	}
  
  	// For dev mode we have no filesystem access so just make one.
  	if a.config.DataDir == "" {
  		id, err := a.makeNodeID()
  		if err != nil {
  			return err
  		}
  
  		config.NodeID = types.NodeID(id)
  		return nil
  	}
  
  	// Load saved state, if any. Since a user could edit this, we also
  	// validate it.
  	fileID := filepath.Join(config.DataDir, "node-id")
  	if _, err := os.Stat(fileID); err == nil {
  		rawID, err := ioutil.ReadFile(fileID)
  		if err != nil {
  			return err
  		}
  
  		nodeID := strings.TrimSpace(string(rawID))
  		nodeID = strings.ToLower(nodeID)
  		if _, err := uuid.ParseUUID(nodeID); err != nil {
  			return err
  		}
  
  		config.NodeID = types.NodeID(nodeID)
  	}
  
  	// If we still don't have a valid node ID, make one.
  	if config.NodeID == "" {
  		id, err := a.makeNodeID()
  		if err != nil {
  			return err
  		}
  		if err := lib.EnsurePath(fileID, false); err != nil {
  			return err
  		}
  		if err := ioutil.WriteFile(fileID, []byte(id), 0600); err != nil {
  			return err
  		}
  
  		config.NodeID = types.NodeID(id)
  	}
  	return nil
  }
docs: // setupNodeID will pull the persisted node ID, if any, or create a random one
  // and persist it.