"strings"
"time"
+ "fmt"
+
"github.com/gin-gonic/gin"
common "github.com/iotbzh/xds-common/golib"
)
Error error `json:"error"`
}
+// ExecSignalArgs JSON parameters of /exec/signal command
+type ExecSignalArgs struct {
+ CmdID string `json:"cmdID" binding:"required"` // command id
+ Signal string `json:"signal" binding:"required"` // signal number
+}
+
// ExecOutEvent Event send in WS when characters are received
const ExecOutEvent = "exec:output"
}
execTmo := args.CmdTimeout
- if execTmo == 0 {
+ if execTmo == -1 {
+ // -1 : no timeout
+ execTmo = 365 * 24 * 60 * 60 // 1 year == no timeout
+ } else if execTmo == 0 {
+ // 0 : default timeout
// TODO get default timeout from config.json file
execTmo = 24 * 60 * 60 // 1 day
}
+ // Define callback for input
+ /* SEB TODO
+ var iCB common.OnInputCB
+ iCB = func() {
+
+ }
+ */
+
// Define callback for output
var oCB common.EmitOutputCB
- oCB = func(sid string, id int, stdout, stderr string, data *map[string]interface{}) {
+ oCB = func(sid string, id string, stdout, stderr string, data *map[string]interface{}) {
// IO socket can be nil when disconnected
so := s.sessions.IOSocketGet(sid)
if so == nil {
s.log.Debugf("%s emitted - WS sid %s - id:%d - prjID:%s", ExecOutEvent, sid, id, prjID)
+ fmt.Printf("SEB SEND out <%v>, err <%v>\n", stdout, stderr)
+
// FIXME replace by .BroadcastTo a room
err := (*so).Emit(ExecOutEvent, ExecOutMsg{
- CmdID: strconv.Itoa(id),
+ CmdID: id,
Timestamp: time.Now().String(),
Stdout: stdout,
Stderr: stderr,
}
// Define callback for output
- eCB := func(sid string, id int, code int, err error, data *map[string]interface{}) {
+ eCB := func(sid string, id string, code int, err error, data *map[string]interface{}) {
s.log.Debugf("Command [Cmd ID %d] exited: code %d, error: %v", id, code, err)
// IO socket can be nil when disconnected
// FIXME replace by .BroadcastTo a room
e := (*so).Emit(ExecExitEvent, ExecExitMsg{
- CmdID: strconv.Itoa(id),
+ CmdID: id,
Timestamp: time.Now().String(),
Code: code,
Error: err,
}
}
- cmdID := execCommandID
+ cmdID := strconv.Itoa(execCommandID)
execCommandID++
cmd := []string{}
if envCmd := s.sdks.GetEnvCmd(args.SdkID, prj.DefaultSdk); len(envCmd) > 0 {
cmd = append(cmd, envCmd...)
cmd = append(cmd, "&&")
+ } else {
+ // It's an error if no envcmd found while a sdkid has been provided
+ if args.SdkID != "" {
+ common.APIError(c, "Unknown sdkid")
+ return
+ }
}
cmd = append(cmd, "cd", prj.GetFullPath(args.RPath), "&&", args.Cmd)
cmd = append(cmd, args.Args...)
}
+ // SEB Workaround for stderr issue (order not respected with stdout)
+ cmd = append(cmd, " 2>&1")
+
// Append client project dir to environment
args.Env = append(args.Env, "CLIENT_PROJECT_DIR="+prj.RelativePath)
- s.log.Debugf("Execute [Cmd ID %d]: %v", cmdID, cmd)
+ s.log.Debugf("Execute [Cmd ID %s]: %v", cmdID, cmd)
data := make(map[string]interface{})
data["ID"] = prj.ID
"cmdID": cmdID,
})
}
+
+// ExecCmd executes remotely a command
+func (s *APIService) execSignalCmd(c *gin.Context) {
+ var args ExecSignalArgs
+
+ if c.BindJSON(&args) != nil {
+ common.APIError(c, "Invalid arguments")
+ return
+ }
+
+ s.log.Debugf("Signal %s for command ID %s", args.Signal, args.CmdID)
+ err := common.ExecSignal(args.CmdID, args.Signal)
+ if err != nil {
+ common.APIError(c, err.Error())
+ return
+ }
+
+ c.JSON(http.StatusOK,
+ gin.H{
+ "status": "OK",
+ })
+}