Skip to content

Commit fc9c616

Browse files
fix: logs updated on starting of a stopped container
Signed-off-by: Shubharanshu Mahapatra <shubhum@amazon.com>
1 parent 9d0a766 commit fc9c616

File tree

2 files changed

+88
-2
lines changed

2 files changed

+88
-2
lines changed

cmd/nerdctl/container/container_logs_test.go

+85
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ package container
1818

1919
import (
2020
"fmt"
21+
"io"
2122
"os/exec"
2223
"runtime"
24+
"strconv"
2325
"strings"
2426
"testing"
2527
"time"
@@ -345,3 +347,86 @@ func TestNoneLoggerHasNoLogURI(t *testing.T) {
345347
testCase.Expected = test.Expects(1, nil, nil)
346348
testCase.Run(t)
347349
}
350+
351+
func TestLogsWithStartContainer(t *testing.T) {
352+
testCase := nerdtest.Setup()
353+
354+
// For windows we havent added support for dual logging so not adding the test.
355+
testCase.Require = require.All(require.Not(require.Windows))
356+
357+
testCase.SubTests = []*test.Case{
358+
{
359+
Description: "Test logs are directed correctly for container start of a interactive container",
360+
Setup: func(data test.Data, helpers test.Helpers) {
361+
cmd := helpers.Command("run", "-it", "--name", data.Identifier(), testutil.CommonImage)
362+
cmd.WithPseudoTTY()
363+
cmd.WithFeeder(func() io.Reader {
364+
// Note: Without the sleep the test seems flaky.
365+
time.Sleep(time.Second)
366+
return strings.NewReader("echo foo\nexit\n")
367+
})
368+
369+
cmd.Run(&test.Expected{
370+
ExitCode: 0,
371+
})
372+
373+
},
374+
Cleanup: func(data test.Data, helpers test.Helpers) {
375+
helpers.Anyhow("rm", "-f", data.Identifier())
376+
},
377+
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
378+
cmd := helpers.Command("start", "-a", data.Identifier())
379+
cmd.WithPseudoTTY()
380+
cmd.WithFeeder(func() io.Reader {
381+
// Note: Without the sleep the test seems flaky.
382+
time.Sleep(time.Second)
383+
return strings.NewReader("echo bar\nexit\n")
384+
})
385+
cmd.Run(&test.Expected{
386+
ExitCode: 0,
387+
})
388+
cmd = helpers.Command("logs", data.Identifier())
389+
390+
return cmd
391+
},
392+
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
393+
return &test.Expected{
394+
ExitCode: 0,
395+
Output: func(stdout string, info string, t *testing.T) {
396+
assert.Assert(t, strings.Contains(stdout, "foo"))
397+
assert.Assert(t, strings.Contains(stdout, "bar"))
398+
},
399+
}
400+
},
401+
},
402+
{
403+
Description: "Test logs are captured after stopping and starting a non-interactive container and continue capturing new logs",
404+
Setup: func(data test.Data, helpers test.Helpers) {
405+
helpers.Ensure("run", "-d", "--name", data.Identifier(), testutil.CommonImage, "sh", "-c", "while true; do echo foo; sleep 1; done")
406+
},
407+
Cleanup: func(data test.Data, helpers test.Helpers) {
408+
helpers.Anyhow("rm", "-f", data.Identifier())
409+
},
410+
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
411+
helpers.Ensure("stop", data.Identifier())
412+
initialLogs := helpers.Capture("logs", data.Identifier())
413+
initialFooCount := strings.Count(initialLogs, "foo")
414+
data.Set("initialFooCount", strconv.Itoa(initialFooCount))
415+
helpers.Ensure("start", data.Identifier())
416+
nerdtest.EnsureContainerStarted(helpers, data.Identifier())
417+
return helpers.Command("logs", data.Identifier())
418+
},
419+
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
420+
return &test.Expected{
421+
ExitCode: 0,
422+
Output: func(stdout string, info string, t *testing.T) {
423+
finalLogsCount := strings.Count(stdout, "foo")
424+
initialFooCount, _ := strconv.Atoi(data.Get("initialFooCount"))
425+
assert.Assert(t, finalLogsCount > initialFooCount, "Expected 'foo' count to increase after restart", info)
426+
},
427+
}
428+
},
429+
},
430+
}
431+
testCase.Run(t)
432+
}

pkg/taskutil/taskutil.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,16 @@ func NewTask(ctx context.Context, client *containerd.Client, container container
6666
var ioCreator cio.Creator
6767
if len(attachStreamOpt) != 0 {
6868
log.G(ctx).Debug("attaching output instead of using the log-uri")
69+
// when attaching a TTY we use writee for stdio and binary for log persistence
6970
if flagT {
7071
in, err := consoleutil.NewDetachableStdin(con, detachKeys, closer)
7172
if err != nil {
7273
return nil, err
7374
}
74-
ioCreator = cio.NewCreator(cio.WithStreams(in, con, nil), cio.WithTerminal)
75+
ioCreator = cioutil.NewContainerIO(namespace, logURI, true, in, con, nil)
7576
} else {
7677
streams := processAttachStreamsOpt(attachStreamOpt)
77-
ioCreator = cio.NewCreator(cio.WithStreams(streams.stdIn, streams.stdOut, streams.stdErr))
78+
ioCreator = cioutil.NewContainerIO(namespace, logURI, false, streams.stdIn, streams.stdOut, streams.stdErr)
7879
}
7980

8081
} else if flagT && flagD {

0 commit comments

Comments
 (0)