// updateRcWithRetries retries updating the given rc on conflict with the following steps: // 1. Get latest resource // 2. applyUpdate // 3. Update the resource func updateRcWithRetries(c client.Interface, namespace string, rc *api.ReplicationController, applyUpdate updateRcFunc) (*api.ReplicationController, error) { // Deep copy the rc in case we failed on Get during retry loop obj, err := api.Scheme.Copy(rc) if err != nil { return nil, fmt.Errorf("failed to deep copy rc before updating it: %v", err) } oldRc := obj.(*api.ReplicationController) err = client.RetryOnConflict(client.DefaultBackoff, func() (e error) { // Apply the update, then attempt to push it to the apiserver. applyUpdate(rc) if rc, e = c.ReplicationControllers(namespace).Update(rc); e == nil { // rc contains the latest controller post update return } updateErr := e // Update the controller with the latest resource version, if the update failed we // can't trust rc so use oldRc.Name. if rc, e = c.ReplicationControllers(namespace).Get(oldRc.Name); e != nil { // The Get failed: Value in rc cannot be trusted. rc = oldRc } // Only return the error from update return updateErr }) // If the error is non-nil the returned controller cannot be trusted, if it is nil, the returned // controller contains the applied update. return rc, err }
// updatePodWithRetries retries updating the given pod on conflict with the following steps: // 1. Get latest resource // 2. applyUpdate // 3. Update the resource func updatePodWithRetries(c client.Interface, namespace string, pod *api.Pod, applyUpdate updatePodFunc) (*api.Pod, error) { // Deep copy the pod in case we failed on Get during retry loop obj, err := api.Scheme.Copy(pod) if err != nil { return nil, fmt.Errorf("failed to deep copy pod before updating it: %v", err) } oldPod := obj.(*api.Pod) err = client.RetryOnConflict(client.DefaultBackoff, func() (e error) { // Apply the update, then attempt to push it to the apiserver. applyUpdate(pod) if pod, e = c.Pods(namespace).Update(pod); e == nil { return } updateErr := e if pod, e = c.Pods(namespace).Get(oldPod.Name); e != nil { pod = oldPod } // Only return the error from update return updateErr }) // If the error is non-nil the returned pod cannot be trusted, if it is nil, the returned // controller contains the applied update. return pod, err }