Skip to content

Commit

Permalink
fix: workaround race in containerd runner with stdin pipe
Browse files Browse the repository at this point in the history
Containerd API to pass stdin to the container is far from being perfect,
but it seems to contain a race condition we can't avoid: if `NewTask()`
fails, it starts the I/O loop in a goroutine, but never stops it. We
can't stop it as well, as `NewTask()` failed, so to workaround this
failure, copy the stdin into new reader on each access.

This copying shouldn't be a big deal for us, as it's just machine
configuration and it's tiny.

Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
  • Loading branch information
smira authored and talos-bot committed Mar 29, 2021
1 parent 2ea20f5 commit a0dcfc3
Showing 1 changed file with 9 additions and 1 deletion.
Expand Up @@ -5,6 +5,7 @@
package containerd

import (
"bytes"
"context"
"fmt"
"io"
Expand Down Expand Up @@ -283,8 +284,15 @@ func (c *containerdRunner) StdinReader() (io.Reader, error) {
return nil, err
}

// copy the input buffer as containerd API seems to be buggy:
// * if the task fails to start, IO loop is not stopped properly, so after a restart there are two goroutines concurrently reading from stdin
contents, err := io.ReadAll(c.opts.Stdin)
if err != nil {
return nil, err
}

c.stdinCloser = &stdinCloser{
stdin: c.opts.Stdin,
stdin: bytes.NewReader(contents),
closer: make(chan struct{}),
}

Expand Down

0 comments on commit a0dcfc3

Please sign in to comment.