When tailing a container log, if the log file is empty it will cause the
log stream to abort with an unexpected `EOF`.
Note that this only applies to the "current" log file as rotated files
cannot be empty.
This fix just skips adding the "current" file the log tail if it is
empty.
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
| ... | ... |
@@ -192,8 +192,12 @@ func (w *LogFile) ReadLogs(config logger.ReadConfig, watcher *logger.LogWatcher) |
| 192 | 192 |
for _, f := range files {
|
| 193 | 193 |
seekers = append(seekers, f) |
| 194 | 194 |
} |
| 195 |
- seekers = append(seekers, currentChunk) |
|
| 196 |
- tailFile(multireader.MultiReadSeeker(seekers...), watcher, w.createDecoder, config) |
|
| 195 |
+ if currentChunk.Size() > 0 {
|
|
| 196 |
+ seekers = append(seekers, currentChunk) |
|
| 197 |
+ } |
|
| 198 |
+ if len(seekers) > 0 {
|
|
| 199 |
+ tailFile(multireader.MultiReadSeeker(seekers...), watcher, w.createDecoder, config) |
|
| 200 |
+ } |
|
| 197 | 201 |
} |
| 198 | 202 |
|
| 199 | 203 |
w.mu.RLock() |
| 200 | 204 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,33 @@ |
| 0 |
+package container |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "context" |
|
| 4 |
+ "io/ioutil" |
|
| 5 |
+ "testing" |
|
| 6 |
+ |
|
| 7 |
+ "github.com/docker/docker/api/types" |
|
| 8 |
+ "github.com/docker/docker/integration/internal/container" |
|
| 9 |
+ "github.com/docker/docker/integration/internal/request" |
|
| 10 |
+ "github.com/docker/docker/pkg/stdcopy" |
|
| 11 |
+ "github.com/stretchr/testify/assert" |
|
| 12 |
+) |
|
| 13 |
+ |
|
| 14 |
+// Regression test for #35370 |
|
| 15 |
+// Makes sure that when following we don't get an EOF error when there are no logs |
|
| 16 |
+func TestLogsFollowTailEmpty(t *testing.T) {
|
|
| 17 |
+ defer setupTest(t)() |
|
| 18 |
+ client := request.NewAPIClient(t) |
|
| 19 |
+ ctx := context.Background() |
|
| 20 |
+ |
|
| 21 |
+ id := container.Run(t, ctx, client, container.WithCmd("sleep", "100000"))
|
|
| 22 |
+ defer client.ContainerRemove(ctx, id, types.ContainerRemoveOptions{Force: true})
|
|
| 23 |
+ |
|
| 24 |
+ logs, err := client.ContainerLogs(ctx, id, types.ContainerLogsOptions{ShowStdout: true, Tail: "2"})
|
|
| 25 |
+ if logs != nil {
|
|
| 26 |
+ defer logs.Close() |
|
| 27 |
+ } |
|
| 28 |
+ assert.NoError(t, err) |
|
| 29 |
+ |
|
| 30 |
+ _, err = stdcopy.StdCopy(ioutil.Discard, ioutil.Discard, logs) |
|
| 31 |
+ assert.NoError(t, err) |
|
| 32 |
+} |