github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/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  	logger.Tracef("run commands: %s", rc)
    65  	if err := rc.callbacks.SetExecutingStatus("running commands"); err != nil {
    66  		return nil, errors.Trace(err)
    67  	}
    68  
    69  	response, err := rc.runner.RunCommands(rc.args.Commands)
    70  	switch err {
    71  	case context.ErrRequeueAndReboot:
    72  		logger.Warningf("cannot requeue external commands")
    73  		fallthrough
    74  	case context.ErrReboot:
    75  		rc.sendResponse(response, nil)
    76  		err = ErrNeedsReboot
    77  	default:
    78  		rc.sendResponse(response, err)
    79  	}
    80  	return nil, err
    81  }
    82  
    83  // Commit does nothing.
    84  // Commit is part of the Operation interface.
    85  func (rc *runCommands) Commit(state State) (*State, error) {
    86  	return nil, nil
    87  }