Skip to content

Commit

Permalink
feat: initial support for terminal resizing
Browse files Browse the repository at this point in the history
  • Loading branch information
devbranch-vadym committed Jul 29, 2021
1 parent 49e4694 commit e236a35
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 9 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15 // indirect
github.com/gorilla/websocket v1.4.2
github.com/kopoli/go-terminal-size v0.0.0-20170219200355-5c97524c8b54
github.com/spf13/viper v1.8.1
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97
gopkg.in/alecthomas/kingpin.v2 v2.2.6
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kopoli/go-terminal-size v0.0.0-20170219200355-5c97524c8b54 h1:0SMHxjkLKNawqUjjnMlCtEdj6uWZjv0+qDZ3F6GOADI=
github.com/kopoli/go-terminal-size v0.0.0-20170219200355-5c97524c8b54/go.mod h1:bm7MVZZvHQBfqHG5X59jrRE/3ak6HvK+/Zb6aZhLR2s=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
Expand All @@ -183,6 +185,7 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
Expand Down
40 changes: 31 additions & 9 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"fmt"
tsize "github.com/kopoli/go-terminal-size"
"io/ioutil"
"net/http"
"os"
Expand Down Expand Up @@ -79,6 +80,11 @@ type WebTerm struct {
errChn chan error
}

type TerminalDimensions struct {
Width int
Height int
}

func (w *WebTerm) wsWrite() {
var err error
var keybuf [1]byte
Expand Down Expand Up @@ -296,20 +302,36 @@ func (r *PortainerAPI) getWsUrl(containerId string, command string) string {
os.Exit(1)
}

// TODO: Implement terminal resize request as well as resizing in runtime.
//cols, rows, _ := terminal.GetSize(int(os.Stdin.Fd()))
//req, _ := http.NewRequest("POST", containerId+"?action=execute",
// strings.NewReader(fmt.Sprintf(
// `{"attachStdin":true, "attachStdout":true,`+
// `"command":["/bin/sh", "-c", "TERM=xterm-256color; export TERM; `+
// `stty cols %d rows %d; `+
// `[ -x /bin/bash ] && ([ -x /usr/bin/script ] && /usr/bin/script -q -c \"/bin/bash\" /dev/null || exec /bin/bash) || exec /bin/sh"], "tty":true}`, cols, rows)))
//resp, err := r.makeObjReq(req, true)
// TODO: Connect to a tsize channel.
s, err := tsize.GetSize()
if (err != nil) {
fmt.Println("GetSize failed: ", err.Error())
} else {
// TODO: That's not really a correct approach; Portainer is expecting resize request _after_ WS connection
// is established.
go r.resizeTerminal(endpointId, TerminalDimensions{Height: s.Height, Width: s.Width})
}

jwt, _ := r.getJwt()

return r.formatWsApiUrl() + "/websocket/exec?token=" + jwt + "&endpointId=1&id=" + endpointId
}

func (r *PortainerAPI) resizeTerminal(execEndpointId string, dimensions TerminalDimensions) (map[string]interface{}, error) {
jsonBodyData := map[string]interface{}{
"Height": dimensions.Height,
"Width": dimensions.Width,
"id": execEndpointId,
}
body, err := json.Marshal(jsonBodyData)
if err != nil {
return nil, err
}
req, _ := http.NewRequest("POST", r.formatHttpApiUrl()+"/endpoints/"+strconv.Itoa(r.Endpoint)+"/docker/exec/"+execEndpointId+"/resize?h="+strconv.Itoa(dimensions.Height)+"&w="+strconv.Itoa(dimensions.Width), bytes.NewReader(body))

return r.makeObjReq(req, true)
}

func (r *PortainerAPI) getWSConn(wsUrl string) *websocket.Conn {
apiUrl := r.formatHttpApiUrl()
header := http.Header{}
Expand Down

0 comments on commit e236a35

Please sign in to comment.