From 17812a0a4388ab0c87084ef7e8118d87e8fadcf7 Mon Sep 17 00:00:00 2001 From: Sebastien Douheret Date: Fri, 9 Mar 2018 17:19:50 +0100 Subject: [PATCH] Fixed terminal output (support escape and control characters) Signed-off-by: Sebastien Douheret --- glide.yaml | 2 +- lib/xdsserver/apiv1-exec.go | 16 +++++++++++----- lib/xdsserver/sdk.go | 7 ++++++- lib/xdsserver/terminal-ssh.go | 31 +++++++++++++------------------ lib/xsapiv1/targets.go | 4 ++-- 5 files changed, 33 insertions(+), 27 deletions(-) diff --git a/glide.yaml b/glide.yaml index 70502be..112bebd 100644 --- a/glide.yaml +++ b/glide.yaml @@ -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 diff --git a/lib/xdsserver/apiv1-exec.go b/lib/xdsserver/apiv1-exec.go index 327c4c5..57ea1f1 100644 --- a/lib/xdsserver/apiv1-exec.go +++ b/lib/xdsserver/apiv1-exec.go @@ -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 { diff --git a/lib/xdsserver/sdk.go b/lib/xdsserver/sdk.go index 374fb12..c1bf043 100644 --- a/lib/xdsserver/sdk.go +++ b/lib/xdsserver/sdk.go @@ -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) diff --git a/lib/xdsserver/terminal-ssh.go b/lib/xdsserver/terminal-ssh.go index 3f4a344..9a9f5fd 100644 --- a/lib/xdsserver/terminal-ssh.go +++ b/lib/xdsserver/terminal-ssh.go @@ -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 diff --git a/lib/xsapiv1/targets.go b/lib/xsapiv1/targets.go index 3f2b3c4..793724a 100644 --- a/lib/xsapiv1/targets.go +++ b/lib/xsapiv1/targets.go @@ -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 -- 2.16.6