// extendMaster attempts to extend ownership of a master lock for TTL seconds. // returns "", nil if extension failed // returns id, nil if extension succeeded // returns "", err if an error occurred func (e *etcdMasterElector) extendMaster(path, id string, ttl uint64, res *etcd.Response) (string, error) { // If it matches the passed in id, extend the lease by writing a new entry. // Uses compare and swap, so that if we TTL out in the meantime, the write will fail. // We don't handle the TTL delete w/o a write case here, it's handled in the next loop // iteration. _, err := e.etcd.CompareAndSwap(path, id, ttl, "", res.Node.ModifiedIndex) if err != nil && !tools.IsEtcdTestFailed(err) { return "", err } if err != nil && tools.IsEtcdTestFailed(err) { return "", nil } return id, nil }
// InterpretUpdateError converts a generic etcd error on a update // operation into the appropriate API error. func InterpretUpdateError(err error, kind, name string) error { switch { case tools.IsEtcdTestFailed(err), tools.IsEtcdNodeExist(err): return errors.NewConflict(kind, name, err) default: return err } }
// errToAPIStatus converts an error to an api.Status object. func errToAPIStatus(err error) *api.Status { switch t := err.(type) { case statusError: status := t.Status() if len(status.Status) == 0 { status.Status = api.StatusFailure } if status.Code == 0 { switch status.Status { case api.StatusSuccess: status.Code = http.StatusOK case api.StatusFailure: status.Code = http.StatusInternalServerError } } //TODO: check for invalid responses return &status default: status := http.StatusInternalServerError switch { //TODO: replace me with NewConflictErr case tools.IsEtcdTestFailed(err): status = http.StatusConflict } // Log errors that were not converted to an error status // by REST storage - these typically indicate programmer // error by not using pkg/api/errors, or unexpected failure // cases. util.HandleError(fmt.Errorf("apiserver received an error that is not an api.Status: %v", err)) return &api.Status{ Status: api.StatusFailure, Code: status, Reason: api.StatusReasonUnknown, Message: err.Error(), } } }