Skip to content

Commit bc2d0b4

Browse files
authored
Merge pull request moby#51289 from vvoland/client-container-exec2
client/container_exec: Separate structs for Start and Attach
2 parents f363523 + 4aac139 commit bc2d0b4

File tree

4 files changed

+92
-30
lines changed

4 files changed

+92
-30
lines changed

client/container_exec.go

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
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.
7780
type ExecStartResult struct {
7881
}
7982

8083
// ExecStart starts an exec process already created in the docker host.
8184
func (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.
96106
type ExecAttachResult struct {
@@ -117,16 +127,28 @@ type ExecAttachResult struct {
117127
// [stdcopy.StdCopy]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#StdCopy
118128
func (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.
131153
type ExecInspectOptions struct {
132154
}

client/container_exec_test.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"net/http"
88
"testing"
99

10+
"github.com/containerd/errdefs"
1011
cerrdefs "github.com/containerd/errdefs"
1112
"github.com/moby/moby/api/types/container"
1213
"gotest.tools/v3/assert"
@@ -109,11 +110,28 @@ func TestExecStart(t *testing.T) {
109110

110111
_, err = client.ExecStart(context.Background(), "exec_id", ExecStartOptions{
111112
Detach: true,
112-
Tty: false,
113+
TTY: false,
113114
})
114115
assert.NilError(t, err)
115116
}
116117

118+
func TestExecStartConsoleSize(t *testing.T) {
119+
client, err := NewClientWithOpts(
120+
WithMockClient(func(req *http.Request) (*http.Response, error) {
121+
return nil, nil
122+
}),
123+
)
124+
assert.NilError(t, err)
125+
126+
_, err = client.ExecStart(context.Background(), "exec_id", ExecStartOptions{
127+
Detach: true,
128+
TTY: false,
129+
ConsoleSize: ConsoleSize{Height: 100, Width: 100},
130+
})
131+
assert.Check(t, is.ErrorType(err, errdefs.IsInvalidArgument))
132+
assert.Check(t, is.ErrorContains(err, "console size is only supported when TTY is enabled"))
133+
}
134+
117135
func TestExecInspectError(t *testing.T) {
118136
client, err := NewClientWithOpts(
119137
WithMockClient(errorMock(http.StatusInternalServerError, "Server error")),

integration/system/event_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func TestEventsExecDie(t *testing.T) {
3636

3737
_, err = apiClient.ExecStart(ctx, res.ID, client.ExecStartOptions{
3838
Detach: true,
39-
Tty: false,
39+
TTY: false,
4040
})
4141
assert.NilError(t, err)
4242

vendor/github.com/moby/moby/client/container_exec.go

Lines changed: 36 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)