Skip to content

Commit 13e738c

Browse files
committed
feat: add --no-stdin flag to container attach
Signed-off-by: Subash Kotha <subash.kotha2@gmail.com>
1 parent e94e9c6 commit 13e738c

File tree

4 files changed

+80
-5
lines changed

4 files changed

+80
-5
lines changed

cmd/nerdctl/container/container_attach.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
package container
1818

1919
import (
20+
"io"
21+
2022
"github.com/spf13/cobra"
2123

2224
containerd "github.com/containerd/containerd/v2/client"
@@ -56,6 +58,7 @@ Caveats:
5658
SilenceErrors: true,
5759
}
5860
cmd.Flags().String("detach-keys", consoleutil.DefaultDetachKeys, "Override the default detach keys")
61+
cmd.Flags().Bool("no-stdin", false, "Do not attach STDIN")
5962
return cmd
6063
}
6164

@@ -68,9 +71,18 @@ func attachOptions(cmd *cobra.Command) (types.ContainerAttachOptions, error) {
6871
if err != nil {
6972
return types.ContainerAttachOptions{}, err
7073
}
74+
noStdin, err := cmd.Flags().GetBool("no-stdin")
75+
if err != nil {
76+
return types.ContainerAttachOptions{}, err
77+
}
78+
79+
var stdin io.Reader
80+
if !noStdin {
81+
stdin = cmd.InOrStdin()
82+
}
7183
return types.ContainerAttachOptions{
7284
GOptions: globalOptions,
73-
Stdin: cmd.InOrStdin(),
85+
Stdin: stdin,
7486
Stdout: cmd.OutOrStdout(),
7587
Stderr: cmd.ErrOrStderr(),
7688
DetachKeys: detachKeys,

cmd/nerdctl/container/container_attach_linux_test.go

+58
Original file line numberDiff line numberDiff line change
@@ -211,3 +211,61 @@ func TestAttachForAutoRemovedContainer(t *testing.T) {
211211

212212
testCase.Run(t)
213213
}
214+
215+
func TestAttachNoStdin(t *testing.T) {
216+
testCase := nerdtest.Setup()
217+
218+
testCase.Cleanup = func(data test.Data, helpers test.Helpers) {
219+
helpers.Anyhow("rm", "-f", data.Identifier())
220+
}
221+
222+
testCase.Setup = func(data test.Data, helpers test.Helpers) {
223+
cmd := helpers.Command("run", "-it", "--detach-keys=ctrl-p,ctrl-q", "--name", data.Identifier(),
224+
testutil.CommonImage, "sh", "-c", `echo ready; sleep 5`)
225+
cmd.WithPseudoTTY()
226+
time.Sleep(1 * time.Second)
227+
cmd.Feed(bytes.NewReader([]byte{16, 17})) // Ctrl-p, Ctrl-q to detach (https://en.wikipedia.org/wiki/C0_and_C1_control_codes)
228+
cmd.Run(&test.Expected{
229+
ExitCode: 0,
230+
Output: func(stdout string, info string, t *testing.T) {
231+
assert.Assert(t, strings.Contains(helpers.Capture("inspect", "--format", "{{.State.Running}}", data.Identifier()), "true"))
232+
},
233+
})
234+
}
235+
236+
testCase.Command = func(data test.Data, helpers test.Helpers) test.TestableCommand {
237+
cmd := helpers.Command("attach", "--no-stdin", data.Identifier())
238+
cmd.WithPseudoTTY()
239+
cmd.WithFeeder(func() io.Reader {
240+
maxRetries := 30
241+
retryCount := 0
242+
for {
243+
if retryCount >= maxRetries {
244+
t.Fatalf("Container did not output 'ready' message after %d retries", maxRetries)
245+
return nil
246+
}
247+
out := helpers.Capture("logs", data.Identifier())
248+
if strings.Contains(out, "ready") {
249+
break
250+
}
251+
time.Sleep(1 * time.Second)
252+
retryCount++
253+
}
254+
return strings.NewReader("should-not-appear\n")
255+
})
256+
return cmd
257+
}
258+
259+
testCase.Expected = func(data test.Data, helpers test.Helpers) *test.Expected {
260+
return &test.Expected{
261+
ExitCode: 0, // Since it's a normal exit and not detach.
262+
Output: func(stdout string, info string, t *testing.T) {
263+
logs := helpers.Capture("logs", data.Identifier())
264+
assert.Assert(t, strings.Contains(logs, "ready"))
265+
assert.Assert(t, !strings.Contains(stdout, "should-not-appear"))
266+
},
267+
}
268+
}
269+
270+
testCase.Run(t)
271+
}

docs/command-reference.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -686,8 +686,9 @@ Usage: `nerdctl attach CONTAINER`
686686
Flags:
687687

688688
- :whale: `--detach-keys`: Override the default detach keys
689+
- :whale: `--no-stdin`: Do not attach STDIN
689690

690-
Unimplemented `docker attach` flags: `--no-stdin`, `--sig-proxy`
691+
Unimplemented `docker attach` flags: `--sig-proxy`
691692

692693
### :whale: nerdctl container prune
693694

pkg/cmd/container/attach.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"context"
2121
"errors"
2222
"fmt"
23+
"io"
2324

2425
"golang.org/x/term"
2526

@@ -114,9 +115,12 @@ func Attach(ctx context.Context, client *containerd.Client, req string, options
114115
}
115116
io.Cancel()
116117
}
117-
in, err := consoleutil.NewDetachableStdin(con, options.DetachKeys, closer)
118-
if err != nil {
119-
return err
118+
var in io.Reader
119+
if options.Stdin != nil {
120+
in, err = consoleutil.NewDetachableStdin(con, options.DetachKeys, closer)
121+
if err != nil {
122+
return err
123+
}
120124
}
121125
opt = cio.WithStreams(in, con, nil)
122126
} else {

0 commit comments

Comments
 (0)