Defined structures for /exec and /signal response.
[src/xds/xds-server.git] / lib / apiv1 / exec.go
index de40c70..baf431f 100644 (file)
@@ -19,7 +19,8 @@ type (
        // ExecArgs JSON parameters of /exec command
        ExecArgs struct {
                ID              string   `json:"id" binding:"required"`
-               SdkID           string   `json:"sdkid"` // sdk ID to use for setting env
+               SdkID           string   `json:"sdkID"` // sdk ID to use for setting env
+               CmdID           string   `json:"cmdID"` // command unique ID
                Cmd             string   `json:"cmd" binding:"required"`
                Args            []string `json:"args"`
                Env             []string `json:"env"`
@@ -30,6 +31,18 @@ type (
                CmdTimeout      int      `json:"timeout"`         // command completion timeout in Second
        }
 
+       // ExecRes JSON result of /exec command
+       ExecRes struct {
+               Status string `json:"status"` // status OK
+               CmdID  string `json:"cmdID"`  // command unique ID
+       }
+
+       // ExecSigRes JSON result of /signal command
+       ExecSigRes struct {
+               Status string `json:"status"` // status OK
+               CmdID  string `json:"cmdID"`  // command unique ID
+       }
+
        // ExecInMsg Message used to received input characters (stdin)
        ExecInMsg struct {
                CmdID     string `json:"cmdID"`
@@ -104,15 +117,19 @@ func (s *APIService) execCmd(c *gin.Context) {
        }
 
        // Allow to pass id in url (/exec/:id) or as JSON argument
-       id := c.Param("id")
-       if id == "" {
-               id = args.ID
+       idArg := c.Param("id")
+       if idArg == "" {
+               idArg = args.ID
        }
-       if id == "" {
+       if idArg == "" {
                common.APIError(c, "Invalid id")
                return
        }
-
+       id, err := s.mfolders.ResolveID(idArg)
+       if err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
        f := s.mfolders.Get(id)
        if f == nil {
                common.APIError(c, "Unknown id")
@@ -168,11 +185,13 @@ func (s *APIService) execCmd(c *gin.Context) {
        }
 
        // Unique ID for each commands
-       cmdID := strconv.Itoa(execCommandID)
-       execCommandID++
+       if args.CmdID == "" {
+               args.CmdID = s.cfg.ServerUID[:18] + "_" + strconv.Itoa(execCommandID)
+               execCommandID++
+       }
 
        // Create new execution over WS context
-       execWS := eows.New(strings.Join(cmd, " "), cmdArgs, sop, sess.ID, cmdID)
+       execWS := eows.New(strings.Join(cmd, " "), cmdArgs, sop, sess.ID, args.CmdID)
        execWS.Log = s.log
 
        // Append client project dir to environment
@@ -292,6 +311,16 @@ func (s *APIService) execCmd(c *gin.Context) {
        execWS.ExitCB = func(e *eows.ExecOverWS, code int, err error) {
                s.log.Debugf("Command [Cmd ID %s] exited: code %d, error: %v", e.CmdID, code, err)
 
+               // Close client tty
+               defer func() {
+                       if gdbPty != nil {
+                               gdbPty.Close()
+                       }
+                       if gdbTty != nil {
+                               gdbTty.Close()
+                       }
+               }()
+
                // IO socket can be nil when disconnected
                so := s.sessions.IOSocketGet(e.Sid)
                if so == nil {
@@ -322,14 +351,7 @@ func (s *APIService) execCmd(c *gin.Context) {
                                }
                                time.Sleep(time.Second)
                        }
-               }
-
-               // Close client tty
-               if gdbPty != nil {
-                       gdbPty.Close()
-               }
-               if gdbTty != nil {
-                       gdbTty.Close()
+                       s.log.Debugf("OK file are synchronized.")
                }
 
                // FIXME replace by .BroadcastTo a room
@@ -364,11 +386,7 @@ func (s *APIService) execCmd(c *gin.Context) {
                return
        }
 
-       c.JSON(http.StatusOK,
-               gin.H{
-                       "status": "OK",
-                       "cmdID":  execWS.CmdID,
-               })
+       c.JSON(http.StatusOK, ExecRes{Status: "OK", CmdID: execWS.CmdID})
 }
 
 // ExecCmd executes remotely a command
@@ -394,8 +412,5 @@ func (s *APIService) execSignalCmd(c *gin.Context) {
                return
        }
 
-       c.JSON(http.StatusOK,
-               gin.H{
-                       "status": "OK",
-               })
+       c.JSON(http.StatusOK, ExecSigRes{Status: "OK", CmdID: args.CmdID})
 }