github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/worker/uniter/operation/factory.go (about)

     1  // Copyright 2014-2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package operation
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/names"
     9  	corecharm "gopkg.in/juju/charm.v5"
    10  
    11  	"github.com/juju/juju/worker/uniter/charm"
    12  	"github.com/juju/juju/worker/uniter/hook"
    13  	"github.com/juju/juju/worker/uniter/runner"
    14  )
    15  
    16  // NewFactory returns a Factory that creates Operations backed by the supplied
    17  // parameters.
    18  func NewFactory(
    19  	deployer charm.Deployer,
    20  	runnerFactory runner.Factory,
    21  	callbacks Callbacks,
    22  	storageUpdater StorageUpdater,
    23  	abort <-chan struct{},
    24  ) Factory {
    25  	return &factory{
    26  		deployer:       deployer,
    27  		runnerFactory:  runnerFactory,
    28  		callbacks:      callbacks,
    29  		storageUpdater: storageUpdater,
    30  		abort:          abort,
    31  	}
    32  }
    33  
    34  type factory struct {
    35  	deployer       charm.Deployer
    36  	runnerFactory  runner.Factory
    37  	callbacks      Callbacks
    38  	storageUpdater StorageUpdater
    39  	abort          <-chan struct{}
    40  }
    41  
    42  // newResolved wraps the supplied operation such that it will clear the uniter
    43  // resolve flag before executing.
    44  func (f *factory) newResolved(wrapped Operation) (Operation, error) {
    45  	if wrapped == nil {
    46  		return nil, errors.New("operation required")
    47  	}
    48  	return &resolvedOperation{
    49  		Operation: wrapped,
    50  		callbacks: f.callbacks,
    51  	}, nil
    52  }
    53  
    54  // newDeploy is the common code for creating arbitrary deploy operations.
    55  func (f *factory) newDeploy(kind Kind, charmURL *corecharm.URL, revert, resolved bool) (Operation, error) {
    56  	if charmURL == nil {
    57  		return nil, errors.New("charm url required")
    58  	} else if kind != Install && kind != Upgrade {
    59  		return nil, errors.Errorf("unknown deploy kind: %s", kind)
    60  	}
    61  	return &deploy{
    62  		kind:      kind,
    63  		charmURL:  charmURL,
    64  		revert:    revert,
    65  		resolved:  resolved,
    66  		callbacks: f.callbacks,
    67  		deployer:  f.deployer,
    68  		abort:     f.abort,
    69  	}, nil
    70  }
    71  
    72  // NewInstall is part of the Factory interface.
    73  func (f *factory) NewInstall(charmURL *corecharm.URL) (Operation, error) {
    74  	return f.newDeploy(Install, charmURL, false, false)
    75  }
    76  
    77  // NewUpgrade is part of the Factory interface.
    78  func (f *factory) NewUpgrade(charmURL *corecharm.URL) (Operation, error) {
    79  	return f.newDeploy(Upgrade, charmURL, false, false)
    80  }
    81  
    82  // NewRevertUpgrade is part of the Factory interface.
    83  func (f *factory) NewRevertUpgrade(charmURL *corecharm.URL) (Operation, error) {
    84  	charmOp, err := f.newDeploy(Upgrade, charmURL, true, false)
    85  	if err != nil {
    86  		return nil, err
    87  	}
    88  	return f.newResolved(charmOp)
    89  }
    90  
    91  // NewResolvedUpgrade is part of the Factory interface.
    92  func (f *factory) NewResolvedUpgrade(charmURL *corecharm.URL) (Operation, error) {
    93  	charmOp, err := f.newDeploy(Upgrade, charmURL, false, true)
    94  	if err != nil {
    95  		return nil, err
    96  	}
    97  	return f.newResolved(charmOp)
    98  }
    99  
   100  // NewRunHook is part of the Factory interface.
   101  func (f *factory) NewRunHook(hookInfo hook.Info) (Operation, error) {
   102  	if err := hookInfo.Validate(); err != nil {
   103  		return nil, err
   104  	}
   105  	return &runHook{
   106  		info:          hookInfo,
   107  		callbacks:     f.callbacks,
   108  		runnerFactory: f.runnerFactory,
   109  	}, nil
   110  }
   111  
   112  // NewRetryHook is part of the Factory interface.
   113  func (f *factory) NewRetryHook(hookInfo hook.Info) (Operation, error) {
   114  	hookOp, err := f.NewRunHook(hookInfo)
   115  	if err != nil {
   116  		return nil, err
   117  	}
   118  	return f.newResolved(hookOp)
   119  }
   120  
   121  // NewSkipHook is part of the Factory interface.
   122  func (f *factory) NewSkipHook(hookInfo hook.Info) (Operation, error) {
   123  	hookOp, err := f.NewRunHook(hookInfo)
   124  	if err != nil {
   125  		return nil, err
   126  	}
   127  	return f.newResolved(&skipOperation{hookOp})
   128  }
   129  
   130  // NewAction is part of the Factory interface.
   131  func (f *factory) NewAction(actionId string) (Operation, error) {
   132  	if !names.IsValidAction(actionId) {
   133  		return nil, errors.Errorf("invalid action id %q", actionId)
   134  	}
   135  	return &runAction{
   136  		actionId:      actionId,
   137  		callbacks:     f.callbacks,
   138  		runnerFactory: f.runnerFactory,
   139  	}, nil
   140  }
   141  
   142  // NewCommands is part of the Factory interface.
   143  func (f *factory) NewCommands(args CommandArgs, sendResponse CommandResponseFunc) (Operation, error) {
   144  	if args.Commands == "" {
   145  		return nil, errors.New("commands required")
   146  	} else if sendResponse == nil {
   147  		return nil, errors.New("response sender required")
   148  	}
   149  	if args.RemoteUnitName != "" {
   150  		if args.RelationId == -1 {
   151  			return nil, errors.New("remote unit not valid without relation")
   152  		} else if !names.IsValidUnit(args.RemoteUnitName) {
   153  			return nil, errors.Errorf("invalid remote unit name %q", args.RemoteUnitName)
   154  		}
   155  	}
   156  	return &runCommands{
   157  		args:          args,
   158  		sendResponse:  sendResponse,
   159  		callbacks:     f.callbacks,
   160  		runnerFactory: f.runnerFactory,
   161  	}, nil
   162  }
   163  
   164  // NewUpdateRelations is part of the Factory interface.
   165  func (f *factory) NewUpdateRelations(ids []int) (Operation, error) {
   166  	return &updateRelations{
   167  		ids:       ids,
   168  		callbacks: f.callbacks,
   169  	}, nil
   170  }
   171  
   172  // NewUpdateStorage is part of the Factory interface.
   173  func (f *factory) NewUpdateStorage(tags []names.StorageTag) (Operation, error) {
   174  	return &updateStorage{
   175  		tags:           tags,
   176  		storageUpdater: f.storageUpdater,
   177  	}, nil
   178  }
   179  
   180  // NewResignLeadership is part of the Factory interface.
   181  func (f *factory) NewResignLeadership() (Operation, error) {
   182  	return &resignLeadership{}, nil
   183  }
   184  
   185  // NewAcceptLeadership is part of the Factory interface.
   186  func (f *factory) NewAcceptLeadership() (Operation, error) {
   187  	return &acceptLeadership{}, nil
   188  }