// applyPatch reads the latest version of the object, writes it to version, then attempts to merge // the changes onto it without conflict. If a conflict occurs jsonmerge.IsConflicting(err) is // true. The info object is mutated func applyPatch(delta *jsonmerge.Delta, info *resource.Info, version string) error { if err := info.Get(); err != nil { return patchError{err} } obj, err := resource.AsVersionedObject([]*resource.Info{info}, false, version) if err != nil { return patchError{err} } data, err := info.Mapping.Codec.Encode(obj) if err != nil { return patchError{err} } merged, err := delta.Apply(data) if err != nil { return patchError{err} } mergedObj, err := info.Mapping.Codec.Decode(merged) if err != nil { return patchError{err} } updated, err := resource.NewHelper(info.Client, info.Mapping).Replace(info.Namespace, info.Name, false, mergedObj) if err != nil { return err } info.Refresh(updated, true) return nil }
// waitForObjectDeletion refreshes the object, waiting until it is deleted, a timeout is reached, or // an error is encountered. It checks once a second. func waitForObjectDeletion(info *resource.Info, timeout time.Duration) error { copied := *info info = &copied // TODO: refactor Reaper so that we can pass the "wait" option into it, and then check for UID change. return wait.PollImmediate(objectDeletionWaitInterval, timeout, func() (bool, error) { switch err := info.Get(); { case err == nil: return false, nil case errors.IsNotFound(err): return true, nil default: return false, err } }) }
// DefaultRetriable adds retry information to the provided error, and will refresh the // info if the client info is stale. If the refresh fails the error is made fatal. // All other errors are left in their natural state - they will not be retried unless // they define a Temporary() method that returns true. func DefaultRetriable(info *resource.Info, err error) error { if err == nil { return nil } switch { case errors.IsMethodNotSupported(err): return ErrNotRetriable{err} case errors.IsConflict(err): if refreshErr := info.Get(); refreshErr != nil { return ErrNotRetriable{err} } return ErrRetriable{err} case errors.IsServerTimeout(err): return ErrRetriable{err} } return err }