Prevent Syncthing auto-upgrade and restart.
[src/xds/xds-server.git] / lib / common / execPipeWs.go
index 3b63cdc..9bb4517 100644 (file)
@@ -5,6 +5,7 @@ import (
        "fmt"
        "io"
        "os"
+       "strings"
        "time"
 
        "syscall"
@@ -14,17 +15,17 @@ import (
 )
 
 // EmitOutputCB is the function callback used to emit data
-type EmitOutputCB func(sid string, cmdID int, stdout, stderr string)
+type EmitOutputCB func(sid string, cmdID int, stdout, stderr string, data *map[string]interface{})
 
 // EmitExitCB is the function callback used to emit exit proc code
-type EmitExitCB func(sid string, cmdID int, code int, err error)
+type EmitExitCB func(sid string, cmdID int, code int, err error, data *map[string]interface{})
 
 // Inspired by :
 // https://github.com/gorilla/websocket/blob/master/examples/command/main.go
 
 // ExecPipeWs executes a command and redirect stdout/stderr into a WebSocket
-func ExecPipeWs(cmd string, so *socketio.Socket, sid string, cmdID int,
-       cmdExecTimeout int, log *logrus.Logger, eoCB EmitOutputCB, eeCB EmitExitCB) error {
+func ExecPipeWs(cmd []string, env []string, so *socketio.Socket, sid string, cmdID int,
+       cmdExecTimeout int, log *logrus.Logger, eoCB EmitOutputCB, eeCB EmitExitCB, data *map[string]interface{}) error {
 
        outr, outw, err := os.Pipe()
        if err != nil {
@@ -39,9 +40,10 @@ func ExecPipeWs(cmd string, so *socketio.Socket, sid string, cmdID int,
                return fmt.Errorf("Pipe stdin error: " + err.Error())
        }
 
-       bashArgs := []string{"/bin/bash", "-c", cmd}
+       bashArgs := []string{"/bin/bash", "-c", strings.Join(cmd, " ")}
        proc, err := os.StartProcess("/bin/bash", bashArgs, &os.ProcAttr{
                Files: []*os.File{inr, outw, outw},
+               Env:   append(os.Environ(), env...),
        })
        if err != nil {
                outr.Close()
@@ -58,10 +60,10 @@ func ExecPipeWs(cmd string, so *socketio.Socket, sid string, cmdID int,
                defer inw.Close()
 
                stdoutDone := make(chan struct{})
-               go cmdPumpStdout(so, outr, stdoutDone, sid, cmdID, log, eoCB)
+               go cmdPumpStdout(so, outr, stdoutDone, sid, cmdID, log, eoCB, data)
 
                // Blocking function that poll input or wait for end of process
-               cmdPumpStdin(so, inw, proc, sid, cmdID, cmdExecTimeout, log, eeCB)
+               cmdPumpStdin(so, inw, proc, sid, cmdID, cmdExecTimeout, log, eeCB, data)
 
                // Some commands will exit when stdin is closed.
                inw.Close()
@@ -92,7 +94,8 @@ func ExecPipeWs(cmd string, so *socketio.Socket, sid string, cmdID int,
 }
 
 func cmdPumpStdin(so *socketio.Socket, w io.Writer, proc *os.Process,
-       sid string, cmdID int, tmo int, log *logrus.Logger, exitFuncCB EmitExitCB) {
+       sid string, cmdID int, tmo int, log *logrus.Logger, exitFuncCB EmitExitCB,
+       data *map[string]interface{}) {
        /* XXX - code to add to support stdin through WS
        for {
                _, message, err := so. ?? ReadMessage()
@@ -125,21 +128,21 @@ func cmdPumpStdin(so *socketio.Socket, w io.Writer, proc *os.Process,
        // Wait cmd complete
        select {
        case dC := <-done:
-               exitFuncCB(sid, cmdID, dC.status, dC.err)
+               exitFuncCB(sid, cmdID, dC.status, dC.err, data)
        case <-time.After(time.Duration(tmo) * time.Second):
                exitFuncCB(sid, cmdID, -99,
-                       fmt.Errorf("Exit Timeout for command ID %v", cmdID))
+                       fmt.Errorf("Exit Timeout for command ID %v", cmdID), data)
        }
 }
 
 func cmdPumpStdout(so *socketio.Socket, r io.Reader, done chan struct{},
-       sid string, cmdID int, log *logrus.Logger, emitFuncCB EmitOutputCB) {
+       sid string, cmdID int, log *logrus.Logger, emitFuncCB EmitOutputCB, data *map[string]interface{}) {
        defer func() {
        }()
 
        sc := bufio.NewScanner(r)
        for sc.Scan() {
-               emitFuncCB(sid, cmdID, string(sc.Bytes()), "")
+               emitFuncCB(sid, cmdID, string(sc.Bytes()), "", data)
        }
        if sc.Err() != nil {
                log.Errorln("scan:", sc.Err())