// 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"`
}
// 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")
return
}
- folder := *f
- prj := folder.GetConfig()
+ fld := *f
+ prj := fld.GetConfig()
// Build command line
cmd := []string{}
}
}
- cmd = append(cmd, "cd", folder.GetFullPath(args.RPath))
+ cmd = append(cmd, "cd", "\""+fld.GetFullPath(args.RPath)+"\"")
// FIXME - add 'exec' prevents to use syntax:
// xds-exec -l debug -c xds-config.env -- "cd build && cmake .."
// but exec is mandatory to allow to pass correctly signals
// Process command arguments
cmdArgs := make([]string, len(args.Args)+1)
- copy(cmdArgs, args.Args)
+
+ // Copy and Translate path from client to server
+ for _, aa := range args.Args {
+ if strings.Contains(aa, prj.ClientPath) {
+ cmdArgs = append(cmdArgs, fld.ConvPathCli2Svr(aa))
+ } else {
+ cmdArgs = append(cmdArgs, aa)
+ }
+ }
// Allocate pts if tty if used
if args.TTY {
}
// 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
// Set correct path
data := e.UserData
- rootPath := (*data)["RootPath"].(string)
- clientPath := (*data)["ClientPath"].(string)
- stdin = strings.Replace(stdin, clientPath, rootPath+"/"+clientPath, -1)
+ prjID := (*data)["ID"].(string)
+ f := s.mfolders.Get(prjID)
+ if f == nil {
+ s.log.Errorf("InputCB: Cannot get folder ID %s", prjID)
+ } else {
+ // Translate paths from client to server
+ stdin = (*f).ConvPathCli2Svr(stdin)
+ }
return stdin, nil
}
// Retrieve project ID and RootPath
data := e.UserData
prjID := (*data)["ID"].(string)
- prjRootPath := (*data)["RootPath"].(string)
gdbServerTTY := (*data)["gdbServerTTY"].(string)
- // Cleanup any references to internal rootpath in stdout & stderr
- stdout = strings.Replace(stdout, prjRootPath, "", -1)
- stderr = strings.Replace(stderr, prjRootPath, "", -1)
+ f := s.mfolders.Get(prjID)
+ if f == nil {
+ s.log.Errorf("OutputCB: Cannot get folder ID %s", prjID)
+ } else {
+ // Translate paths from server to client
+ stdout = (*f).ConvPathSvr2Cli(stdout)
+ stderr = (*f).ConvPathSvr2Cli(stderr)
+ }
s.log.Debugf("%s emitted - WS sid[4:] %s - id:%s - prjID:%s", ExecOutEvent, e.Sid[4:], e.CmdID, prjID)
if stdout != "" {
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 {
}
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
// User data (used within callbacks)
data := make(map[string]interface{})
data["ID"] = prj.ID
- data["RootPath"] = prj.RootPath
- data["ClientPath"] = prj.ClientPath
data["ExitImmediate"] = args.ExitImmediate
if args.TTY && args.TTYGdbserverFix {
data["gdbServerTTY"] = "workaround"
execWS.UserData = &data
// Start command execution
- s.log.Debugf("Execute [Cmd ID %s]: %v %v", execWS.CmdID, execWS.Cmd, execWS.Args)
+ s.log.Infof("Execute [Cmd ID %s]: %v %v", execWS.CmdID, execWS.Cmd, execWS.Args)
err = execWS.Start()
if err != nil {