github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/apiserver/action/run.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package action 5 6 import ( 7 "time" 8 9 "github.com/juju/errors" 10 "github.com/juju/names" 11 "github.com/juju/utils/set" 12 13 "github.com/juju/juju/apiserver/params" 14 "github.com/juju/juju/core/actions" 15 "github.com/juju/juju/state" 16 ) 17 18 // getAllUnitNames returns a sequence of valid Unit objects from state. If any 19 // of the service names or unit names are not found, an error is returned. 20 func getAllUnitNames(st *state.State, units, services []string) (result []names.Tag, err error) { 21 unitsSet := set.NewStrings(units...) 22 for _, name := range services { 23 service, err := st.Service(name) 24 if err != nil { 25 return nil, err 26 } 27 units, err := service.AllUnits() 28 if err != nil { 29 return nil, err 30 } 31 for _, unit := range units { 32 unitsSet.Add(unit.Name()) 33 } 34 } 35 for _, unitName := range unitsSet.SortedValues() { 36 result = append(result, names.NewUnitTag(unitName)) 37 } 38 return result, nil 39 } 40 41 // Run the commands specified on the machines identified through the 42 // list of machines, units and services. 43 func (a *ActionAPI) Run(run params.RunParams) (results params.ActionResults, err error) { 44 if err := a.check.ChangeAllowed(); err != nil { 45 return results, errors.Trace(err) 46 } 47 48 units, err := getAllUnitNames(a.state, run.Units, run.Services) 49 if err != nil { 50 return results, errors.Trace(err) 51 } 52 53 machines := make([]names.Tag, len(run.Machines)) 54 for i, machineId := range run.Machines { 55 if !names.IsValidMachine(machineId) { 56 return results, errors.Errorf("invalid machine id %q", machineId) 57 } 58 machines[i] = names.NewMachineTag(machineId) 59 } 60 61 actionParams := a.createActionsParams(append(units, machines...), run.Commands, run.Timeout) 62 63 return queueActions(a, actionParams) 64 } 65 66 // RunOnAllMachines attempts to run the specified command on all the machines. 67 func (a *ActionAPI) RunOnAllMachines(run params.RunParams) (results params.ActionResults, err error) { 68 if err := a.check.ChangeAllowed(); err != nil { 69 return results, errors.Trace(err) 70 } 71 72 machines, err := a.state.AllMachines() 73 if err != nil { 74 return results, err 75 } 76 machineTags := make([]names.Tag, len(machines)) 77 for i, machine := range machines { 78 machineTags[i] = machine.Tag() 79 } 80 81 actionParams := a.createActionsParams(machineTags, run.Commands, run.Timeout) 82 83 return queueActions(a, actionParams) 84 } 85 86 func (a *ActionAPI) createActionsParams(actionReceiverTags []names.Tag, quotedCommands string, timeout time.Duration) params.Actions { 87 88 apiActionParams := params.Actions{Actions: []params.Action{}} 89 90 actionParams := map[string]interface{}{} 91 actionParams["command"] = quotedCommands 92 actionParams["timeout"] = timeout.Nanoseconds() 93 94 for _, tag := range actionReceiverTags { 95 apiActionParams.Actions = append(apiActionParams.Actions, params.Action{ 96 Receiver: tag.String(), 97 Name: actions.JujuRunActionName, 98 Parameters: actionParams, 99 }) 100 } 101 102 return apiActionParams 103 } 104 105 var queueActions = func(a *ActionAPI, args params.Actions) (results params.ActionResults, err error) { 106 return a.Enqueue(args) 107 }