github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/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/charm/v12/hooks"
    10  	"github.com/juju/errors"
    11  	"github.com/juju/names/v5"
    12  
    13  	"github.com/juju/juju/core/model"
    14  	"github.com/juju/juju/core/status"
    15  	"github.com/juju/juju/rpc/params"
    16  	"github.com/juju/juju/worker/uniter/charm"
    17  	"github.com/juju/juju/worker/uniter/hook"
    18  	"github.com/juju/juju/worker/uniter/remotestate"
    19  	"github.com/juju/juju/worker/uniter/runner/context"
    20  )
    21  
    22  // operationCallbacks implements operation.Callbacks, and exists entirely to
    23  // keep those methods off the Uniter itself.
    24  type operationCallbacks struct {
    25  	u *Uniter
    26  }
    27  
    28  // PrepareHook is part of the operation.Callbacks interface.
    29  func (opc *operationCallbacks) PrepareHook(hi hook.Info) (string, error) {
    30  	name := string(hi.Kind)
    31  	switch {
    32  	case hi.Kind.IsWorkload():
    33  		name = fmt.Sprintf("%s-%s", hi.WorkloadName, hi.Kind)
    34  	case hi.Kind.IsRelation():
    35  		var err error
    36  		name, err = opc.u.relationStateTracker.PrepareHook(hi)
    37  		if err != nil {
    38  			return "", err
    39  		}
    40  	case hi.Kind.IsStorage():
    41  		if err := opc.u.storage.ValidateHook(hi); err != nil {
    42  			return "", err
    43  		}
    44  		storageName, err := names.StorageName(hi.StorageId)
    45  		if err != nil {
    46  			return "", err
    47  		}
    48  		name = fmt.Sprintf("%s-%s", storageName, hi.Kind)
    49  		// TODO(axw) if the agent is not installed yet,
    50  		// set the status to "preparing storage".
    51  	case hi.Kind.IsSecret():
    52  		err := opc.u.secretsTracker.PrepareHook(hi)
    53  		if err != nil {
    54  			return "", err
    55  		}
    56  	case hi.Kind == hooks.ConfigChanged:
    57  		// TODO(axw)
    58  		//opc.u.f.DiscardConfigEvent()
    59  	case hi.Kind == hooks.LeaderSettingsChanged:
    60  		// TODO(axw)
    61  		//opc.u.f.DiscardLeaderSettingsEvent()
    62  	}
    63  	return name, nil
    64  }
    65  
    66  // CommitHook is part of the operation.Callbacks interface.
    67  func (opc *operationCallbacks) CommitHook(hi hook.Info) error {
    68  	switch {
    69  	case hi.Kind == hooks.Start:
    70  		opc.u.Probe.SetHasStarted(true)
    71  	case hi.Kind == hooks.Stop:
    72  		opc.u.Probe.SetHasStarted(false)
    73  	case hi.Kind.IsWorkload():
    74  	case hi.Kind.IsRelation():
    75  		return opc.u.relationStateTracker.CommitHook(hi)
    76  	case hi.Kind.IsStorage():
    77  		return opc.u.storage.CommitHook(hi)
    78  	case hi.Kind.IsSecret():
    79  		return opc.u.secretsTracker.CommitHook(hi)
    80  	}
    81  	return nil
    82  }
    83  
    84  func notifyHook(hook string, ctx context.Context, method func(string)) {
    85  	if r, err := ctx.HookRelation(); err == nil {
    86  		remote, _ := ctx.RemoteUnitName()
    87  		if remote == "" {
    88  			remote, _ = ctx.RemoteApplicationName()
    89  		}
    90  		if remote != "" {
    91  			remote = " " + remote
    92  		}
    93  		hook = hook + remote + " " + r.FakeId()
    94  	}
    95  	method(hook)
    96  }
    97  
    98  // NotifyHookCompleted is part of the operation.Callbacks interface.
    99  func (opc *operationCallbacks) NotifyHookCompleted(hook string, ctx context.Context) {
   100  	if opc.u.observer != nil {
   101  		notifyHook(hook, ctx, opc.u.observer.HookCompleted)
   102  	}
   103  }
   104  
   105  // NotifyHookFailed is part of the operation.Callbacks interface.
   106  func (opc *operationCallbacks) NotifyHookFailed(hook string, ctx context.Context) {
   107  	if opc.u.observer != nil {
   108  		notifyHook(hook, ctx, opc.u.observer.HookFailed)
   109  	}
   110  }
   111  
   112  // FailAction is part of the operation.Callbacks interface.
   113  func (opc *operationCallbacks) FailAction(actionId, message string) error {
   114  	if !names.IsValidAction(actionId) {
   115  		return errors.Errorf("invalid action id %q", actionId)
   116  	}
   117  	tag := names.NewActionTag(actionId)
   118  	err := opc.u.st.ActionFinish(tag, params.ActionFailed, nil, message)
   119  	if params.IsCodeNotFoundOrCodeUnauthorized(err) || params.IsCodeAlreadyExists(err) {
   120  		err = nil
   121  	}
   122  	return err
   123  }
   124  
   125  func (opc *operationCallbacks) ActionStatus(actionId string) (string, error) {
   126  	if !names.IsValidAction(actionId) {
   127  		return "", errors.NotValidf("invalid action id %q", actionId)
   128  	}
   129  	tag := names.NewActionTag(actionId)
   130  	return opc.u.st.ActionStatus(tag)
   131  }
   132  
   133  // GetArchiveInfo is part of the operation.Callbacks interface.
   134  func (opc *operationCallbacks) GetArchiveInfo(url string) (charm.BundleInfo, error) {
   135  	ch, err := opc.u.st.Charm(url)
   136  	if err != nil {
   137  		return nil, errors.Trace(err)
   138  	}
   139  	return ch, nil
   140  }
   141  
   142  // SetCurrentCharm is part of the operation.Callbacks interface.
   143  func (opc *operationCallbacks) SetCurrentCharm(charmURL string) error {
   144  	return opc.u.unit.SetCharmURL(charmURL)
   145  }
   146  
   147  // SetExecutingStatus is part of the operation.Callbacks interface.
   148  func (opc *operationCallbacks) SetExecutingStatus(message string) error {
   149  	return setAgentStatus(opc.u, status.Executing, message, nil)
   150  }
   151  
   152  // SetUpgradeSeriesStatus is part of the operation.Callbacks interface.
   153  func (opc *operationCallbacks) SetUpgradeSeriesStatus(upgradeSeriesStatus model.UpgradeSeriesStatus, reason string) error {
   154  	return setUpgradeSeriesStatus(opc.u, upgradeSeriesStatus, reason)
   155  }
   156  
   157  // RemoteInit is part of the operation.Callbacks interface.
   158  func (opc *operationCallbacks) RemoteInit(runningStatus remotestate.ContainerRunningStatus, abort <-chan struct{}) error {
   159  	if opc.u.modelType != model.CAAS || opc.u.sidecar {
   160  		// Non CAAS model or sidecar CAAS model do not have remote init process.
   161  		return nil
   162  	}
   163  	if opc.u.remoteInitFunc == nil {
   164  		return nil
   165  	}
   166  	return opc.u.remoteInitFunc(runningStatus, abort)
   167  }
   168  
   169  // SetSecretRotated is part of the operation.Callbacks interface.
   170  func (opc *operationCallbacks) SetSecretRotated(uri string, oldRevision int) error {
   171  	return opc.u.secretsClient.SecretRotated(uri, oldRevision)
   172  }
   173  
   174  // SecretsRemoved is part of the operation.Callbacks interface.
   175  func (opc *operationCallbacks) SecretsRemoved(uris []string) error {
   176  	return opc.u.secretsTracker.SecretsRemoved(uris)
   177  }