Fixed terminal output (support escape and control characters)
authorSebastien Douheret <sebastien.douheret@iot.bzh>
Fri, 9 Mar 2018 16:19:50 +0000 (17:19 +0100)
committerSebastien Douheret <sebastien.douheret@iot.bzh>
Fri, 9 Mar 2018 16:19:50 +0000 (17:19 +0100)
Signed-off-by: Sebastien Douheret <sebastien.douheret@iot.bzh>
glide.yaml
lib/xdsserver/apiv1-exec.go
lib/xdsserver/sdk.go
lib/xdsserver/terminal-ssh.go
lib/xsapiv1/targets.go

index 70502be..112bebd 100644 (file)
@@ -25,7 +25,7 @@ import:
 - package: github.com/satori/go.uuid
   version: ^1.1.0
 - package: gerrit.automotivelinux.org/gerrit/src/xds/xds-common.git
-  version: ~0.2.0
+  version: ~0.3.0
   subpackages:
   - golib/common
   - golib/eows
index 327c4c5..57ea1f1 100644 (file)
@@ -152,14 +152,17 @@ func (s *APIService) execCmd(c *gin.Context) {
 
        // Define callback for input (stdin)
        execWS.InputEvent = xsapiv1.ExecInEvent
-       execWS.InputCB = func(e *eows.ExecOverWS, stdin string) (string, error) {
+       execWS.InputCB = func(e *eows.ExecOverWS, bStdin []byte) ([]byte, error) {
+
+               stdin := string(bStdin)
+
                s.Log.Debugf("STDIN <<%v>>", strings.Replace(stdin, "\n", "\\n", -1))
 
                // Handle Ctrl-D
                if len(stdin) == 1 && stdin == "\x04" {
                        // Close stdin
                        errMsg := fmt.Errorf("close stdin: %v", stdin)
-                       return "", errMsg
+                       return []byte{}, errMsg
                }
 
                // Set correct path
@@ -172,12 +175,15 @@ func (s *APIService) execCmd(c *gin.Context) {
                        // Translate paths from client to server
                        stdin = (*f).ConvPathCli2Svr(stdin)
                }
-
-               return stdin, nil
+               return []byte(stdin), nil
        }
 
        // Define callback for output (stdout+stderr)
-       execWS.OutputCB = func(e *eows.ExecOverWS, stdout, stderr string) {
+       execWS.OutputCB = func(e *eows.ExecOverWS, bStdout, bStderr []byte) {
+
+               stdout := string(bStdout)
+               stderr := string(bStderr)
+
                // IO socket can be nil when disconnected
                so := s.sessions.IOSocketGet(e.Sid)
                if so == nil {
index 374fb12..c1bf043 100644 (file)
@@ -247,6 +247,7 @@ func (s *CrossSDK) Install(file string, force bool, timeout int, args []string,
        // Create new instance to execute command and sent output over WS
        s.installCmd = eows.New(s.scripts[scriptAdd], cmdArgs, sess.IOSocket, sess.ID, cmdID)
        s.installCmd.Log = s.Log
+       // TODO: enable Term s.installCmd.PtyMode = true
        s.installCmd.LineTimeSpan = 500 * time.Millisecond.Nanoseconds()
        if timeout > 0 {
                s.installCmd.CmdExecTimeout = timeout
@@ -255,7 +256,11 @@ func (s *CrossSDK) Install(file string, force bool, timeout int, args []string,
        }
 
        // Define callback for output (stdout+stderr)
-       s.installCmd.OutputCB = func(e *eows.ExecOverWS, stdout, stderr string) {
+       s.installCmd.OutputCB = func(e *eows.ExecOverWS, bStdout, bStderr []byte) {
+
+               stdout := string(bStdout)
+               stderr := string(bStderr)
+
                // paranoia
                data := e.UserData
                sdkID := (*data)["SDKID"].(string)
index 3f4a344..9a9f5fd 100644 (file)
@@ -128,26 +128,19 @@ func (t *TermSSH) Open(sock *socketio.Socket, sessID string) (*xsapiv1.TerminalC
 
        t.sshWS = eows.New(cmd, args, sock, sessID, cmdID)
        t.sshWS.Log = t.Log
-       t.sshWS.OutSplit = eows.SplitChar
-       t.sshWS.PtsMode = true
+       t.sshWS.PtyMode = true
 
        // Define callback for input (stdin)
        t.sshWS.InputEvent = xsapiv1.TerminalInEvent
-       t.sshWS.InputCB = func(e *eows.ExecOverWS, stdin string) (string, error) {
-               t.Log.Debugf("STDIN <<%v>>", strings.Replace(stdin, "\n", "\\n", -1))
-
-               // Handle Ctrl-D
-               if len(stdin) == 1 && stdin == "\x04" {
-                       // Close stdin
-                       errMsg := fmt.Errorf("close stdin: %v", stdin)
-                       return "", errMsg
+       t.sshWS.InputCB = func(e *eows.ExecOverWS, stdin []byte) ([]byte, error) {
+               if t.LogLevelSilly {
+                       t.Log.Debugf("STDIN <<%v>> %s", stdin, string(stdin))
                }
-
                return stdin, nil
        }
 
        // Define callback for output (stdout+stderr)
-       t.sshWS.OutputCB = func(e *eows.ExecOverWS, stdout, stderr string) {
+       t.sshWS.OutputCB = func(e *eows.ExecOverWS, stdout, stderr []byte) {
                // IO socket can be nil when disconnected
                so := t.sessions.IOSocketGet(e.Sid)
                if so == nil {
@@ -159,12 +152,14 @@ func (t *TermSSH) Open(sock *socketio.Socket, sessID string) (*xsapiv1.TerminalC
                data := e.UserData
                termID := (*data)["ID"].(string)
 
-               t.Log.Debugf("%s emitted - WS sid[4:] %s - id:%s - termID:%s", xsapiv1.TerminalOutEvent, e.Sid[4:], e.CmdID, termID)
-               if stdout != "" {
-                       t.Log.Debugf("STDOUT <<%v>>", strings.Replace(stdout, "\n", "\\n", -1))
-               }
-               if stderr != "" {
-                       t.Log.Debugf("STDERR <<%v>>", strings.Replace(stderr, "\n", "\\n", -1))
+               if t.LogLevelSilly {
+                       t.Log.Debugf("%s emitted - WS sid[4:] %s - id:%s - termID:%s", xsapiv1.TerminalOutEvent, e.Sid[4:], e.CmdID, termID)
+                       if len(stdout) > 0 {
+                               t.Log.Debugf("STDOUT <<%v>>", strings.Replace(string(stdout), "\n", "\\n", -1))
+                       }
+                       if len(stderr) > 0 {
+                               t.Log.Debugf("STDERR <<%v>>", strings.Replace(string(stderr), "\n", "\\n", -1))
+                       }
                }
 
                // FIXME replace by .BroadcastTo a room
index 3f2b3c4..793724a 100644 (file)
@@ -99,8 +99,8 @@ type (
        TerminalOutMsg struct {
                TermID    string `json:"termID"`
                Timestamp string `json:"timestamp"`
-               Stdout    string `json:"stdout"`
-               Stderr    string `json:"stderr"`
+               Stdout    []byte `json:"stdout"`
+               Stderr    []byte `json:"stderr"`
        }
 
        // TerminalExitMsg Message sent on terminal/console exit