55 "encoding/json"
66 "net/http"
77
8+ "github.com/containerd/errdefs"
89 "github.com/moby/moby/api/types/container"
910)
1011
@@ -61,36 +62,45 @@ func (cli *Client) ExecCreate(ctx context.Context, containerID string, options E
6162 return ExecCreateResult {ID : response .ID }, err
6263}
6364
64- type execStartAttachOptions struct {
65+ type ConsoleSize struct {
66+ Height , Width uint
67+ }
68+
69+ // ExecStartOptions holds options for starting a container exec.
70+ type ExecStartOptions struct {
6571 // ExecStart will first check if it's detached
6672 Detach bool
6773 // Check if there's a tty
68- Tty bool
69- // Terminal size [height, width], unused if Tty == false
70- ConsoleSize * [ 2 ] uint `json:",omitempty "`
74+ TTY bool
75+ // Terminal size [height, width], unused if TTY == false
76+ ConsoleSize ConsoleSize `json:",omitzero "`
7177}
7278
73- // ExecStartOptions holds options for starting a container exec.
74- type ExecStartOptions execStartAttachOptions
75-
7679// ExecStartResult holds the result of starting a container exec.
7780type ExecStartResult struct {
7881}
7982
8083// ExecStart starts an exec process already created in the docker host.
8184func (cli * Client ) ExecStart (ctx context.Context , execID string , options ExecStartOptions ) (ExecStartResult , error ) {
8285 req := container.ExecStartRequest {
83- Detach : options .Detach ,
84- Tty : options .Tty ,
85- ConsoleSize : options .ConsoleSize ,
86+ Detach : options .Detach ,
87+ Tty : options .TTY ,
88+ }
89+ if err := applyConsoleSize (& req , & options .ConsoleSize ); err != nil {
90+ return ExecStartResult {}, err
8691 }
8792 resp , err := cli .post (ctx , "/exec/" + execID + "/start" , nil , req , nil )
8893 defer ensureReaderClosed (resp )
8994 return ExecStartResult {}, err
9095}
9196
9297// ExecAttachOptions holds options for attaching to a container exec.
93- type ExecAttachOptions execStartAttachOptions
98+ type ExecAttachOptions struct {
99+ // Check if there's a tty
100+ TTY bool
101+ // Terminal size [height, width], unused if TTY == false
102+ ConsoleSize ConsoleSize `json:",omitzero"`
103+ }
94104
95105// ExecAttachResult holds the result of attaching to a container exec.
96106type ExecAttachResult struct {
@@ -117,16 +127,28 @@ type ExecAttachResult struct {
117127// [stdcopy.StdCopy]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#StdCopy
118128func (cli * Client ) ExecAttach (ctx context.Context , execID string , options ExecAttachOptions ) (ExecAttachResult , error ) {
119129 req := container.ExecStartRequest {
120- Detach : options .Detach ,
121- Tty : options .Tty ,
122- ConsoleSize : options .ConsoleSize ,
130+ Detach : false ,
131+ Tty : options .TTY ,
132+ }
133+ if err := applyConsoleSize (& req , & options .ConsoleSize ); err != nil {
134+ return ExecAttachResult {}, err
123135 }
124136 response , err := cli .postHijacked (ctx , "/exec/" + execID + "/start" , nil , req , http.Header {
125137 "Content-Type" : {"application/json" },
126138 })
127139 return ExecAttachResult {HijackedResponse : response }, err
128140}
129141
142+ func applyConsoleSize (req * container.ExecStartRequest , consoleSize * ConsoleSize ) error {
143+ if consoleSize .Height != 0 || consoleSize .Width != 0 {
144+ if ! req .Tty {
145+ return errdefs .ErrInvalidArgument .WithMessage ("console size is only supported when TTY is enabled" )
146+ }
147+ req .ConsoleSize = & [2 ]uint {consoleSize .Height , consoleSize .Width }
148+ }
149+ return nil
150+ }
151+
130152// ExecInspectOptions holds options for inspecting a container exec.
131153type ExecInspectOptions struct {
132154}
0 commit comments