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  }