github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/worker/uniter/op_callbacks.go (about) 1 // Copyright 2012-2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package uniter 5 6 import ( 7 "fmt" 8 9 "github.com/juju/errors" 10 "github.com/juju/names" 11 corecharm "gopkg.in/juju/charm.v4" 12 "gopkg.in/juju/charm.v4/hooks" 13 "launchpad.net/tomb" 14 15 "github.com/juju/juju/apiserver/params" 16 "github.com/juju/juju/worker/uniter/charm" 17 "github.com/juju/juju/worker/uniter/hook" 18 "github.com/juju/juju/worker/uniter/runner" 19 ) 20 21 // operationCallbacks implements operation.Callbacks, and exists entirely to 22 // keep those methods off the Uniter itself. 23 type operationCallbacks struct { 24 u *Uniter 25 } 26 27 // AcquireExecutionLock is part of the operation.Callbacks interface. 28 func (opc *operationCallbacks) AcquireExecutionLock(message string) (func(), error) { 29 // We want to make sure we don't block forever when locking, but take the 30 // Uniter's tomb into account. 31 checkTomb := func() error { 32 select { 33 case <-opc.u.tomb.Dying(): 34 return tomb.ErrDying 35 default: 36 // no-op to fall through to return. 37 } 38 return nil 39 } 40 message = fmt.Sprintf("%s: %s", opc.u.unit.Name(), message) 41 if err := opc.u.hookLock.LockWithFunc(message, checkTomb); err != nil { 42 return nil, err 43 } 44 return func() { opc.u.hookLock.Unlock() }, nil 45 } 46 47 // PrepareHook is part of the operation.Callbacks interface. 48 func (opc *operationCallbacks) PrepareHook(hi hook.Info) (string, error) { 49 name := string(hi.Kind) 50 status := params.StatusActive 51 52 switch { 53 case hi.Kind.IsRelation(): 54 var err error 55 name, err = opc.u.relations.PrepareHook(hi) 56 if err != nil { 57 return "", err 58 } 59 case hi.Kind == hooks.Stop: 60 status = params.StatusStopping 61 case hi.Kind == hooks.ConfigChanged: 62 opc.u.f.DiscardConfigEvent() 63 fallthrough 64 default: 65 if !opc.u.operationState().Started { 66 status = params.StatusInstalling 67 } 68 } 69 err := opc.u.unit.SetStatus(status, "", nil) 70 if err != nil { 71 return "", err 72 } 73 return name, nil 74 } 75 76 // CommitHook is part of the operation.Callbacks interface. 77 func (opc *operationCallbacks) CommitHook(hi hook.Info) error { 78 if hi.Kind.IsRelation() { 79 return opc.u.relations.CommitHook(hi) 80 } 81 if hi.Kind == hooks.ConfigChanged { 82 opc.u.ranConfigChanged = true 83 } 84 return nil 85 } 86 87 // UpdateRelations is part of the operation.Callbacks interface. 88 func (opc *operationCallbacks) UpdateRelations(ids []int) error { 89 return opc.u.relations.Update(ids) 90 } 91 92 func notifyHook(hook string, ctx runner.Context, method func(string)) { 93 if r, ok := ctx.HookRelation(); ok { 94 remote, _ := ctx.RemoteUnitName() 95 if remote != "" { 96 remote = " " + remote 97 } 98 hook = hook + remote + " " + r.FakeId() 99 } 100 method(hook) 101 } 102 103 // NotifyHookCompleted is part of the operation.Callbacks interface. 104 func (opc *operationCallbacks) NotifyHookCompleted(hook string, ctx runner.Context) { 105 if opc.u.observer != nil { 106 notifyHook(hook, ctx, opc.u.observer.HookCompleted) 107 } 108 } 109 110 // NotifyHookFailed is part of the operation.Callbacks interface. 111 func (opc *operationCallbacks) NotifyHookFailed(hook string, ctx runner.Context) { 112 if opc.u.observer != nil { 113 notifyHook(hook, ctx, opc.u.observer.HookFailed) 114 } 115 } 116 117 // FailAction is part of the operation.Callbacks interface. 118 func (opc *operationCallbacks) FailAction(actionId, message string) error { 119 if !names.IsValidAction(actionId) { 120 return errors.Errorf("invalid action id %q", actionId) 121 } 122 tag := names.NewActionTag(actionId) 123 err := opc.u.st.ActionFinish(tag, params.ActionFailed, nil, message) 124 if params.IsCodeNotFoundOrCodeUnauthorized(err) { 125 err = nil 126 } 127 return err 128 } 129 130 // GetArchiveInfo is part of the operation.Callbacks interface. 131 func (opc *operationCallbacks) GetArchiveInfo(charmURL *corecharm.URL) (charm.BundleInfo, error) { 132 ch, err := opc.u.st.Charm(charmURL) 133 if err != nil { 134 return nil, errors.Trace(err) 135 } 136 return ch, nil 137 } 138 139 // SetCurrentCharm is part of the operation.Callbacks interface. 140 func (opc *operationCallbacks) SetCurrentCharm(charmURL *corecharm.URL) error { 141 return opc.u.f.SetCharm(charmURL) 142 } 143 144 // ClearResolvedFlag is part of the operation.Callbacks interface. 145 func (opc *operationCallbacks) ClearResolvedFlag() error { 146 return opc.u.f.ClearResolved() 147 } 148 149 // InitializeMetricsCollector is part of the operation.Callbacks interface. 150 func (opc *operationCallbacks) InitializeMetricsCollector() error { 151 return opc.u.initializeMetricsCollector() 152 }