code: func (nim *nodeInfoManager) tryUpdateNode(updateFuncs ...nodeUpdateFunc) error {
  	// Retrieve the latest version of Node before attempting update, so that
  	// existing changes are not overwritten.
  
  	kubeClient := nim.volumeHost.GetKubeClient()
  	if kubeClient == nil {
  		return fmt.Errorf("error getting kube client")
  	}
  
  	nodeClient := kubeClient.CoreV1().Nodes()
  	originalNode, err := nodeClient.Get(string(nim.nodeName), metav1.GetOptions{})
  	if err != nil {
  		return err
  	}
  	node := originalNode.DeepCopy()
  
  	needUpdate := false
  	for _, update := range updateFuncs {
  		newNode, updated, err := update(node)
  		if err != nil {
  			return err
  		}
  		node = newNode
  		needUpdate = needUpdate || updated
  	}
  
  	if needUpdate {
  		// PatchNodeStatus can update both node's status and labels or annotations
  		// Updating status by directly updating node does not work
  		_, _, updateErr := nodeutil.PatchNodeStatus(kubeClient.CoreV1(), types.NodeName(node.Name), originalNode, node)
  		return updateErr
  	}
  
  	return nil
  }
docs: // updateNode repeatedly attempts to update the corresponding node object
  // which is modified by applying the given update functions sequentially.
  // Because updateFuncs are applied sequentially, later updateFuncs should take into account
  // the effects of previous updateFuncs to avoid potential conflicts. For example, if multiple
  // functions update the same field, updates in the last function are persisted.