in pkg/client/client_v2.go [899:974]
func (c *clientV2) tryPerformAction(actionResults chan *proto.ActionResponse, action *proto.ActionRequest) {
// find the unit
c.unitsMu.RLock()
unit := c.findUnit(action.UnitId, UnitType(action.UnitType))
c.unitsMu.RUnlock()
if unit == nil {
actionResults <- &proto.ActionResponse{
Token: c.token,
Id: action.Id,
Status: proto.ActionResponse_FAILED,
Result: ActionErrUnitNotFound,
}
return
}
// find the action registered with the unit
unit.amx.RLock()
actionImpl, ok := unit.actions[action.Name]
unit.amx.RUnlock()
if !ok {
actionResults <- &proto.ActionResponse{
Token: c.token,
Id: action.Id,
Status: proto.ActionResponse_FAILED,
Result: ActionErrUndefined,
}
return
}
// ensure that the parameters can be unmarshalled
var params map[string]interface{}
err := json.Unmarshal(action.Params, ¶ms)
if err != nil {
actionResults <- &proto.ActionResponse{
Token: c.token,
Id: action.Id,
Status: proto.ActionResponse_FAILED,
Result: ActionErrUnmarshableParams,
}
return
}
// perform the action (in goroutine)
go func() {
res, err := actionImpl.Execute(c.ctx, params)
if err != nil {
actionResults <- &proto.ActionResponse{
Token: c.token,
Id: action.Id,
Status: proto.ActionResponse_FAILED,
Result: utils.JSONMustMarshal(map[string]string{
"error": err.Error(),
}),
}
return
}
resBytes, err := json.Marshal(res)
if err != nil {
// client-side error, should have been marshal-able
c.errCh <- err
actionResults <- &proto.ActionResponse{
Token: c.token,
Id: action.Id,
Status: proto.ActionResponse_FAILED,
Result: ActionErrUnmarshableResult,
}
return
}
actionResults <- &proto.ActionResponse{
Token: c.token,
Id: action.Id,
Status: proto.ActionResponse_SUCCESS,
Result: resBytes,
}
}()
}