本文整理汇总了Golang中github.com/juju/errors.DeferredAnnotatef函数的典型用法代码示例。如果您正苦于以下问题:Golang DeferredAnnotatef函数的具体用法?Golang DeferredAnnotatef怎么用?Golang DeferredAnnotatef使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了DeferredAnnotatef函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: Destroy
// Destroy ensures that the service and all its relations will be removed at
// some point; if the service has no units, and no relation involving the
// service has any units in scope, they are all removed immediately.
func (s *Service) Destroy() (err error) {
defer errors.DeferredAnnotatef(&err, "cannot destroy service %q", s)
defer func() {
if err == nil {
// This is a white lie; the document might actually be removed.
s.doc.Life = Dying
}
}()
svc := &Service{st: s.st, doc: s.doc}
buildTxn := func(attempt int) ([]txn.Op, error) {
if attempt > 0 {
if err := svc.Refresh(); errors.IsNotFound(err) {
return nil, jujutxn.ErrNoOperations
} else if err != nil {
return nil, err
}
}
switch ops, err := svc.destroyOps(); err {
case errRefresh:
case errAlreadyDying:
return nil, jujutxn.ErrNoOperations
case nil:
return ops, nil
default:
return nil, err
}
return nil, jujutxn.ErrTransientFailure
}
return s.st.run(buildTxn)
}
示例2: validate
// validate returns an error if the state violates expectations.
func (st State) validate() (err error) {
defer errors.DeferredAnnotatef(&err, "invalid operation state")
hasHook := st.Hook != nil
hasActionId := st.ActionId != nil
hasCharm := st.CharmURL != nil
switch st.Kind {
case Install:
if st.Installed {
return errors.New("unexpected hook info with Kind Install")
}
fallthrough
case Upgrade:
switch {
case !hasCharm:
return errors.New("missing charm URL")
case hasActionId:
return errors.New("unexpected action id")
}
case RunAction:
switch {
case !hasActionId:
return errors.New("missing action id")
case hasCharm:
return errors.New("unexpected charm URL")
}
case RunHook:
switch {
case !hasHook:
return errors.New("missing hook info with Kind RunHook")
case hasCharm:
return errors.New("unexpected charm URL")
case hasActionId:
return errors.New("unexpected action id")
}
case Continue:
// TODO(jw4) LP-1438489
// ModeContinue should no longer have a Hook, but until the upgrade is
// fixed we can't fail the validation if it does.
if hasHook {
logger.Errorf("unexpected hook info with Kind Continue")
}
switch {
case hasCharm:
return errors.New("unexpected charm URL")
case hasActionId:
return errors.New("unexpected action id")
}
default:
return errors.Errorf("unknown operation %q", st.Kind)
}
switch st.Step {
case Queued, Pending, Done:
default:
return errors.Errorf("unknown operation step %q", st.Step)
}
if hasHook {
return st.Hook.Validate()
}
return nil
}
示例3: Write
// Write atomically writes to disk the relation state change in hi.
// It must be called after the respective hook was executed successfully.
// Write doesn't validate hi but guarantees that successive writes of
// the same hi are idempotent.
func (d *StateDir) Write(hi hook.Info) (err error) {
defer errors.DeferredAnnotatef(&err, "failed to write %q hook info for %q on state directory", hi.Kind, hi.RemoteUnit)
if hi.Kind == hooks.RelationBroken {
return d.Remove()
}
name := strings.Replace(hi.RemoteUnit, "/", "-", 1)
path := filepath.Join(d.path, name)
if hi.Kind == hooks.RelationDeparted {
if err = os.Remove(path); err != nil && !os.IsNotExist(err) {
return err
}
// If atomic delete succeeded, update own state.
delete(d.state.Members, hi.RemoteUnit)
return nil
}
di := diskInfo{&hi.ChangeVersion, hi.Kind == hooks.RelationJoined}
if err := utils.WriteYaml(path, &di); err != nil {
return err
}
// If write was successful, update own state.
d.state.Members[hi.RemoteUnit] = hi.ChangeVersion
if hi.Kind == hooks.RelationJoined {
d.state.ChangedPending = hi.RemoteUnit
} else {
d.state.ChangedPending = ""
}
return nil
}
示例4: Validate
// Validate returns an error if the supplied hook.Info does not represent
// a valid change to the relation state. Hooks must always be validated
// against the current state before they are run, to ensure that the system
// meets its guarantees about hook execution order.
func (s *State) Validate(hi hook.Info) (err error) {
defer errors.DeferredAnnotatef(&err, "inappropriate %q for %q", hi.Kind, hi.RemoteUnit)
if hi.RelationId != s.RelationId {
return fmt.Errorf("expected relation %d, got relation %d", s.RelationId, hi.RelationId)
}
if s.Members == nil {
return fmt.Errorf(`relation is broken and cannot be changed further`)
}
unit, kind := hi.RemoteUnit, hi.Kind
if kind == hooks.RelationBroken {
if len(s.Members) == 0 {
return nil
}
return fmt.Errorf(`cannot run "relation-broken" while units still present`)
}
if s.ChangedPending != "" {
if unit != s.ChangedPending || kind != hooks.RelationChanged {
return fmt.Errorf(`expected "relation-changed" for %q`, s.ChangedPending)
}
} else if _, joined := s.Members[unit]; joined && kind == hooks.RelationJoined {
return fmt.Errorf("unit already joined")
} else if !joined && kind != hooks.RelationJoined {
return fmt.Errorf("unit has not joined")
}
return nil
}
示例5: AddMachines
// AddMachines adds new machines configured according to the
// given templates.
func (st *State) AddMachines(templates ...MachineTemplate) (_ []*Machine, err error) {
defer errors.DeferredAnnotatef(&err, "cannot add a new machine")
var ms []*Machine
var ops []txn.Op
var mdocs []*machineDoc
for _, template := range templates {
mdoc, addOps, err := st.addMachineOps(template)
if err != nil {
return nil, errors.Trace(err)
}
mdocs = append(mdocs, mdoc)
ms = append(ms, newMachine(st, mdoc))
ops = append(ops, addOps...)
}
ssOps, err := st.maintainControllersOps(mdocs, nil)
if err != nil {
return nil, errors.Trace(err)
}
ops = append(ops, ssOps...)
ops = append(ops, assertModelActiveOp(st.ModelUUID()))
if err := st.runTransaction(ops); err != nil {
if errors.Cause(err) == txn.ErrAborted {
if err := checkModelActive(st); err != nil {
return nil, errors.Trace(err)
}
}
return nil, errors.Trace(err)
}
return ms, nil
}
示例6: ReadAllStateDirs
// ReadAllStateDirs loads and returns every StateDir persisted directly inside
// the supplied dirPath. If dirPath does not exist, no error is returned.
func ReadAllStateDirs(dirPath string) (dirs map[int]*StateDir, err error) {
defer errors.DeferredAnnotatef(&err, "cannot load relations state from %q", dirPath)
if _, err := os.Stat(dirPath); os.IsNotExist(err) {
return nil, nil
} else if err != nil {
return nil, err
}
fis, err := ioutil.ReadDir(dirPath)
if err != nil {
return nil, err
}
dirs = map[int]*StateDir{}
for _, fi := range fis {
// Entries with integer names must be directories containing StateDir
// data; all other names will be ignored.
relationId, err := strconv.Atoi(fi.Name())
if err != nil {
// This doesn't look like a relation.
continue
}
dir, err := ReadStateDir(dirPath, relationId)
if err != nil {
return nil, err
}
dirs[relationId] = dir
}
return dirs, nil
}
示例7: Destroy
// Destroy sets the environment's lifecycle to Dying, preventing
// addition of services or machines to state.
func (e *Environment) Destroy() (err error) {
defer errors.DeferredAnnotatef(&err, "failed to destroy environment")
buildTxn := func(attempt int) ([]txn.Op, error) {
// On the first attempt, we assume memory state is recent
// enough to try using...
if attempt != 0 {
// ...but on subsequent attempts, we read fresh environ
// state from the DB. Note that we do *not* refresh `e`
// itself, as detailed in doc/hacking-state.txt
if e, err = e.st.Environment(); err != nil {
return nil, errors.Trace(err)
}
}
ops, err := e.destroyOps()
if err == errEnvironNotAlive {
return nil, jujutxn.ErrNoOperations
} else if err != nil {
return nil, errors.Trace(err)
}
return ops, nil
}
return e.st.run(buildTxn)
}
示例8: destroy
func (m *Model) destroy(ensureNoHostedModels bool) (err error) {
defer errors.DeferredAnnotatef(&err, "failed to destroy model")
st, closeState, err := m.getState()
if err != nil {
return errors.Trace(err)
}
defer closeState()
buildTxn := func(attempt int) ([]txn.Op, error) {
// On the first attempt, we assume memory state is recent
// enough to try using...
if attempt != 0 {
// ...but on subsequent attempts, we read fresh environ
// state from the DB. Note that we do *not* refresh `e`
// itself, as detailed in doc/hacking-state.txt
if m, err = st.Model(); err != nil {
return nil, errors.Trace(err)
}
}
ops, err := m.destroyOps(ensureNoHostedModels, false)
if err == errModelNotAlive {
return nil, jujutxn.ErrNoOperations
} else if err != nil {
return nil, errors.Trace(err)
}
return ops, nil
}
return st.run(buildTxn)
}
示例9: Remove
// Remove removes a dead subnet. If the subnet is not dead it returns an error.
// It also removes any IP addresses associated with the subnet.
func (s *Subnet) Remove() (err error) {
defer errors.DeferredAnnotatef(&err, "cannot remove subnet %q", s)
if s.doc.Life != Dead {
return errors.New("subnet is not dead")
}
addresses, closer := s.st.getCollection(ipaddressesC)
defer closer()
ops := []txn.Op{}
id := s.ID()
var doc struct {
DocID string `bson:"_id"`
}
iter := addresses.Find(bson.D{{"subnetid", id}}).Iter()
for iter.Next(&doc) {
ops = append(ops, txn.Op{
C: ipaddressesC,
Id: doc.DocID,
Remove: true,
})
}
if err = iter.Close(); err != nil {
return errors.Annotate(err, "cannot read addresses")
}
ops = append(ops, txn.Op{
C: subnetsC,
Id: s.doc.DocID,
Remove: true,
})
return s.st.runTransaction(ops)
}
示例10: SetMinUnits
// SetMinUnits changes the number of minimum units required by the service.
func (s *Application) SetMinUnits(minUnits int) (err error) {
defer errors.DeferredAnnotatef(&err, "cannot set minimum units for application %q", s)
defer func() {
if err == nil {
s.doc.MinUnits = minUnits
}
}()
if minUnits < 0 {
return errors.New("cannot set a negative minimum number of units")
}
service := &Application{st: s.st, doc: s.doc}
// Removing the document never fails. Racing clients trying to create the
// document generate one failure, but the second attempt should succeed.
// If one client tries to update the document, and a racing client removes
// it, the former should be able to re-create the document in the second
// attempt. If the referred-to service advanced its life cycle to a not
// alive state, an error is returned after the first failing attempt.
buildTxn := func(attempt int) ([]txn.Op, error) {
if attempt > 0 {
if err := service.Refresh(); err != nil {
return nil, err
}
}
if service.doc.Life != Alive {
return nil, errors.New("application is no longer alive")
}
if minUnits == service.doc.MinUnits {
return nil, jujutxn.ErrNoOperations
}
return setMinUnitsOps(service, minUnits), nil
}
return s.st.run(buildTxn)
}
示例11: SetConstraints
// SetConstraints replaces the current service constraints.
func (s *Service) SetConstraints(cons constraints.Value) (err error) {
unsupported, err := s.st.validateConstraints(cons)
if len(unsupported) > 0 {
logger.Warningf(
"setting constraints on service %q: unsupported constraints: %v", s.Name(), strings.Join(unsupported, ","))
} else if err != nil {
return err
}
if s.doc.Subordinate {
return ErrSubordinateConstraints
}
defer errors.DeferredAnnotatef(&err, "cannot set constraints")
if s.doc.Life != Alive {
return errNotAlive
}
ops := []txn.Op{
{
C: servicesC,
Id: s.doc.DocID,
Assert: isAliveDoc,
},
setConstraintsOp(s.st, s.globalKey(), cons),
}
return onAbort(s.st.runTransaction(ops), errNotAlive)
}
示例12: download
// download fetches the supplied charm and checks that it has the correct sha256
// hash, then copies it into the directory. If a value is received on abort, the
// download will be stopped.
func (d *BundlesDir) download(info BundleInfo, target string, abort <-chan struct{}) (err error) {
// First download...
curl, err := url.Parse(info.URL().String())
if err != nil {
return errors.Annotate(err, "could not parse charm URL")
}
expectedSha256, err := info.ArchiveSha256()
req := downloader.Request{
URL: curl,
TargetDir: d.downloadsPath(),
Verify: downloader.NewSha256Verifier(expectedSha256),
}
logger.Infof("downloading %s from API server", info.URL())
filename, err := d.downloader.Download(req, abort)
if err != nil {
return errors.Annotatef(err, "failed to download charm %q from API server", info.URL())
}
defer errors.DeferredAnnotatef(&err, "downloaded but failed to copy charm to %q from %q", target, filename)
// ...then move the right location.
if err := os.MkdirAll(d.path, 0755); err != nil {
return errors.Trace(err)
}
if err := os.Rename(filename, target); err != nil {
return errors.Trace(err)
}
return nil
}
示例13: RemoveStorageAttachment
// Remove removes the storage attachment from state, and may remove its storage
// instance as well, if the storage instance is Dying and no other references to
// it exist. It will fail if the storage attachment is not Dead.
func (st *State) RemoveStorageAttachment(storage names.StorageTag, unit names.UnitTag) (err error) {
defer errors.DeferredAnnotatef(&err, "cannot remove storage attachment %s:%s", storage.Id(), unit.Id())
buildTxn := func(attempt int) ([]txn.Op, error) {
s, err := st.storageAttachment(storage, unit)
if errors.IsNotFound(err) {
return nil, jujutxn.ErrNoOperations
} else if err != nil {
return nil, errors.Trace(err)
}
inst, err := st.storageInstance(storage)
if errors.IsNotFound(err) {
// This implies that the attachment was removed
// after the call to st.storageAttachment.
return nil, jujutxn.ErrNoOperations
} else if err != nil {
return nil, errors.Trace(err)
}
ops, err := removeStorageAttachmentOps(st, s, inst)
if err != nil {
return nil, errors.Trace(err)
}
return ops, nil
}
return st.run(buildTxn)
}
示例14: setStatus
// setStatus inteprets the supplied params as documented on the type.
func setStatus(st *State, params setStatusParams) (err error) {
defer errors.DeferredAnnotatef(&err, "cannot set status")
// TODO(fwereade): this can/should probably be recording the time the
// status was *set*, not the time it happened to arrive in state.
// We should almost certainly be accepting StatusInfo in the exposed
// SetStatus methods, for symetry with the Status methods.
now := time.Now().UnixNano()
doc := statusDoc{
Status: params.status,
StatusInfo: params.message,
StatusData: escapeKeys(params.rawData),
Updated: now,
}
probablyUpdateStatusHistory(st, params.globalKey, doc)
// Set the authoritative status document, or fail trying.
buildTxn := updateStatusSource(st, params.globalKey, doc)
if params.token != nil {
buildTxn = buildTxnWithLeadership(buildTxn, params.token)
}
err = st.run(buildTxn)
if cause := errors.Cause(err); cause == mgo.ErrNotFound {
return errors.NotFoundf(params.badge)
}
return errors.Trace(err)
}
示例15: Close
func (st *State) Close() (err error) {
defer errors.DeferredAnnotatef(&err, "closing state failed")
err1 := st.watcher.Stop()
var err2 error
if st.pwatcher != nil {
err2 = st.pwatcher.Stop()
}
st.mu.Lock()
var err3 error
if st.allManager != nil {
err3 = st.allManager.Stop()
}
st.mu.Unlock()
st.db.Session.Close()
var i int
for i, err = range []error{err1, err2, err3} {
if err != nil {
switch i {
case 0:
err = errors.Annotatef(err, "failed to stop state watcher")
case 1:
err = errors.Annotatef(err, "failed to stop presence watcher")
case 2:
err = errors.Annotatef(err, "failed to stop all manager")
}
return err
}
}
return nil
}