[lxc-devel] [lxd/master] Send window size initially
tych0 on Github
lxc-bot at linuxcontainers.org
Fri Mar 25 19:19:59 UTC 2016
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20160325/9030c2e7/attachment.bin>
-------------- next part --------------
From a2170a6b96b69bdf30e87f7924a7a1c99f8d9fca Mon Sep 17 00:00:00 2001
From: Tycho Andersen <tycho.andersen at canonical.com>
Date: Fri, 25 Mar 2016 13:15:48 -0600
Subject: [PATCH 1/2] exec: send initial window size
Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
client.go | 3 ++-
doc/rest-api.md | 4 +++-
lxc/exec.go | 7 ++++++-
lxd/container_exec.go | 10 ++++++++++
4 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/client.go b/client.go
index bc4f3fb..e958cf8 100644
--- a/client.go
+++ b/client.go
@@ -1395,7 +1395,8 @@ func (c *Client) Monitor(types []string, handler func(interface{})) error {
// output is sent to the output buffers.
func (c *Client) Exec(name string, cmd []string, env map[string]string,
stdin io.ReadCloser, stdout io.WriteCloser,
- stderr io.WriteCloser, controlHandler func(*Client, *websocket.Conn)) (int, error) {
+ stderr io.WriteCloser, controlHandler func(*Client, *websocket.Conn),
+ width int, height int) (int, error) {
if c.Remote.Public {
return -1, fmt.Errorf("This function isn't supported by public remotes.")
diff --git a/doc/rest-api.md b/doc/rest-api.md
index 137455d..af3f368 100644
--- a/doc/rest-api.md
+++ b/doc/rest-api.md
@@ -926,7 +926,9 @@ Input (run bash):
"command": ["/bin/bash"], # Command and arguments
"environment": {}, # Optional extra environment variables to set
"wait-for-websocket": false, # Whether to wait for a connection before starting the process
- "interactive": true # Whether to allocate a pts device instead of PIPEs
+ "interactive": true, # Whether to allocate a pts device instead of PIPEs
+ "width": 80, # initial width of the terminal (optional)
+ "height": 25, # initial height of the terminal (optional)
}
`wait-for-websocket` indicates whether the operation should block and wait for
diff --git a/lxc/exec.go b/lxc/exec.go
index d218fd5..894cd9d 100644
--- a/lxc/exec.go
+++ b/lxc/exec.go
@@ -137,8 +137,13 @@ func (c *execCmd) run(config *lxd.Config, args []string) error {
handler = nil
}
+ width, height, err := termios.GetSize(int(syscall.Stdout))
+ if err != nil {
+ return err
+ }
+
stdout := c.getStdout()
- ret, err := d.Exec(name, args[1:], env, os.Stdin, stdout, os.Stderr, handler)
+ ret, err := d.Exec(name, args[1:], env, os.Stdin, stdout, os.Stderr, handler, width, height)
if err != nil {
return err
}
diff --git a/lxd/container_exec.go b/lxd/container_exec.go
index 6780089..27c9ea1 100644
--- a/lxd/container_exec.go
+++ b/lxd/container_exec.go
@@ -22,6 +22,8 @@ type commandPostContent struct {
WaitForWS bool `json:"wait-for-websocket"`
Interactive bool `json:"interactive"`
Environment map[string]string `json:"environment"`
+ Width int `json:"width"`
+ Height int `json:"height"`
}
func runCommand(container *lxc.Container, command []string, options lxc.AttachOptions) (int, error) {
@@ -46,6 +48,8 @@ type execWs struct {
controlConnected chan bool
interactive bool
fds map[int]string
+ width int
+ height int
}
func (s *execWs) Metadata() interface{} {
@@ -112,6 +116,10 @@ func (s *execWs) Do(op *operation) error {
s.options.StdinFd = ttys[0].Fd()
s.options.StdoutFd = ttys[0].Fd()
s.options.StderrFd = ttys[0].Fd()
+
+ if s.width > 0 && s.height > 0 {
+ shared.SetSize(int(ptys[0].Fd()), s.width, s.height)
+ }
} else {
ttys = make([]*os.File, 3)
ptys = make([]*os.File, 3)
@@ -317,6 +325,8 @@ func containerExecPost(d *Daemon, r *http.Request) Response {
ws.command = post.Command
ws.container = c.LXContainerGet()
+ ws.width = post.Width
+ ws.height = post.Height
resources := map[string][]string{}
resources["containers"] = []string{ws.container.Name()}
From cb354a483d3b28b18b810b542cdf0684f1cfd77d Mon Sep 17 00:00:00 2001
From: Tycho Andersen <tycho.andersen at canonical.com>
Date: Fri, 25 Mar 2016 13:16:58 -0600
Subject: [PATCH 2/2] exec client: don't always send window size
Now that we don't rely on the first window size send to set the window
size, let's only send it when there is actually a SIGWINCH.
Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
lxc/exec_unix.go | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/lxc/exec_unix.go b/lxc/exec_unix.go
index a4fa8db..9b46add 100644
--- a/lxc/exec_unix.go
+++ b/lxc/exec_unix.go
@@ -23,15 +23,15 @@ func (c *execCmd) controlSocketHandler(d *lxd.Client, control *websocket.Conn) {
signal.Notify(ch, syscall.SIGWINCH)
for {
+ sig := <-ch
+
+ shared.Debugf("Received '%s signal', updating window geometry.", sig)
+
err := c.sendTermSize(control)
if err != nil {
shared.Debugf("error setting term size %s", err)
break
}
-
- sig := <-ch
-
- shared.Debugf("Received '%s signal', updating window geometry.", sig)
}
closeMsg := websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")
More information about the lxc-devel
mailing list