github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/worker/uniter/operation/runcommands.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package operation
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/juju/errors"
    10  
    11  	"github.com/juju/juju/worker/uniter/runner"
    12  	"github.com/juju/juju/worker/uniter/runner/context"
    13  )
    14  
    15  type runCommands struct {
    16  	args         CommandArgs
    17  	sendResponse CommandResponseFunc
    18  
    19  	callbacks     Callbacks
    20  	runnerFactory runner.Factory
    21  
    22  	runner runner.Runner
    23  
    24  	RequiresMachineLock
    25  }
    26  
    27  // String is part of the Operation interface.
    28  func (rc *runCommands) String() string {
    29  	suffix := ""
    30  	if rc.args.RelationId != -1 {
    31  		infix := ""
    32  		if rc.args.RemoteUnitName != "" {
    33  			infix = "; " + rc.args.RemoteUnitName
    34  		}
    35  		suffix = fmt.Sprintf(" (%d%s)", rc.args.RelationId, infix)
    36  	}
    37  	return "run commands" + suffix
    38  }
    39  
    40  // Prepare ensures the commands can be run. It never returns a state change.
    41  // Prepare is part of the Operation interface.
    42  func (rc *runCommands) Prepare(state State) (*State, error) {
    43  	rnr, err := rc.runnerFactory.NewCommandRunner(context.CommandInfo{
    44  		RelationId:      rc.args.RelationId,
    45  		RemoteUnitName:  rc.args.RemoteUnitName,
    46  		ForceRemoteUnit: rc.args.ForceRemoteUnit,
    47  	})
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  	err = rnr.Context().Prepare()
    52  	if err != nil {
    53  		return nil, errors.Trace(err)
    54  	}
    55  	rc.runner = rnr
    56  
    57  	return nil, nil
    58  }
    59  
    60  // Execute runs the commands and dispatches their results. It never returns a
    61  // state change.
    62  // Execute is part of the Operation interface.
    63  func (rc *runCommands) Execute(state State) (*State, error) {
    64  	if err := rc.callbacks.SetExecutingStatus("running commands"); err != nil {
    65  		return nil, errors.Trace(err)
    66  	}
    67  
    68  	response, err := rc.runner.RunCommands(rc.args.Commands)
    69  	switch err {
    70  	case context.ErrRequeueAndReboot:
    71  		logger.Warningf("cannot requeue external commands")
    72  		fallthrough
    73  	case context.ErrReboot:
    74  		rc.sendResponse(response, nil)
    75  		err = ErrNeedsReboot
    76  	default:
    77  		rc.sendResponse(response, err)
    78  	}
    79  	return nil, err
    80  }
    81  
    82  // Commit does nothing.
    83  // Commit is part of the Operation interface.
    84  func (rc *runCommands) Commit(state State) (*State, error) {
    85  	return nil, nil
    86  }