Support reopening container log.

Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
Lantao Liu
2018-02-13 01:55:29 +00:00
parent 8357315564
commit a8264ec035
8 changed files with 93 additions and 53 deletions

View File

@@ -77,8 +77,6 @@ func (c *criContainerdService) attachContainer(ctx context.Context, id string, s
},
}
// TODO(random-liu): Figure out whether we need to support historical output.
if err := cntr.IO.Attach(opts); err != nil {
return fmt.Errorf("failed to attach container: %v", err)
}
cntr.IO.Attach(opts)
return nil
}

View File

@@ -17,7 +17,7 @@ limitations under the License.
package server
import (
"errors"
"fmt"
"golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
@@ -25,7 +25,27 @@ import (
// ReopenContainerLog asks cri-containerd to reopen the stdout/stderr log file for the container.
// This is often called after the log file has been rotated.
// TODO(random-liu): Implement this for kubelet log rotation.
func (c *criContainerdService) ReopenContainerLog(ctx context.Context, r *runtime.ReopenContainerLogRequest) (*runtime.ReopenContainerLogResponse, error) {
return nil, errors.New("not implemented")
container, err := c.containerStore.Get(r.GetContainerId())
if err != nil {
return nil, fmt.Errorf("an error occurred when try to find container %q: %v", r.GetContainerId(), err)
}
if container.Status.Get().State() != runtime.ContainerState_CONTAINER_RUNNING {
return nil, fmt.Errorf("container is not running")
}
// Create new container logger and replace the existing ones.
stdoutWC, stderrWC, err := createContainerLoggers(container.LogPath, container.Config.GetTty())
if err != nil {
return nil, err
}
oldStdoutWC, oldStderrWC := container.IO.AddOutput("log", stdoutWC, stderrWC)
if oldStdoutWC != nil {
oldStdoutWC.Close()
}
if oldStderrWC != nil {
oldStderrWC.Close()
}
return &runtime.ReopenContainerLogResponse{}, nil
}

View File

@@ -110,9 +110,7 @@ func (c *criContainerdService) startContainer(ctx context.Context,
}
}
}()
if err := cio.WithOutput("log", stdoutWC, stderrWC)(cntr.IO); err != nil {
return nil, fmt.Errorf("failed to add container log: %v", err)
}
cntr.IO.AddOutput("log", stdoutWC, stderrWC)
cntr.IO.Pipe()
return cntr.IO, nil
}

View File

@@ -52,23 +52,6 @@ var _ cio.IO = &ContainerIO{}
// ContainerIOOpts sets specific information to newly created ContainerIO.
type ContainerIOOpts func(*ContainerIO) error
// WithOutput adds output stream to the container io.
func WithOutput(name string, stdout, stderr io.WriteCloser) ContainerIOOpts {
return func(c *ContainerIO) error {
if stdout != nil {
if err := c.stdoutGroup.Add(streamKey(c.id, name, Stdout), stdout); err != nil {
return err
}
}
if stderr != nil {
if err := c.stderrGroup.Add(streamKey(c.id, name, Stderr), stderr); err != nil {
return err
}
}
return nil
}
}
// WithFIFOs specifies existing fifos for the container io.
func WithFIFOs(fifos *cio.FIFOSet) ContainerIOOpts {
return func(c *ContainerIO) error {
@@ -149,7 +132,7 @@ func (c *ContainerIO) Pipe() {
// Attach attaches container stdio.
// TODO(random-liu): Use pools.Copy in docker to reduce memory usage?
func (c *ContainerIO) Attach(opts AttachOptions) error {
func (c *ContainerIO) Attach(opts AttachOptions) {
var wg sync.WaitGroup
key := util.GenerateID()
stdinKey := streamKey(c.id, "attach-"+key, Stdin)
@@ -202,21 +185,33 @@ func (c *ContainerIO) Attach(opts AttachOptions) error {
if opts.Stdout != nil {
wg.Add(1)
wc, close := cioutil.NewWriteCloseInformer(opts.Stdout)
if err := c.stdoutGroup.Add(stdoutKey, wc); err != nil {
return err
}
c.stdoutGroup.Add(stdoutKey, wc)
go attachStream(stdoutKey, close)
}
if !opts.Tty && opts.Stderr != nil {
wg.Add(1)
wc, close := cioutil.NewWriteCloseInformer(opts.Stderr)
if err := c.stderrGroup.Add(stderrKey, wc); err != nil {
return err
}
c.stderrGroup.Add(stderrKey, wc)
go attachStream(stderrKey, close)
}
wg.Wait()
return nil
}
// AddOutput adds new write closers to the container stream, and returns existing
// write closers if there are any.
func (c *ContainerIO) AddOutput(name string, stdout, stderr io.WriteCloser) (io.WriteCloser, io.WriteCloser) {
var oldStdout, oldStderr io.WriteCloser
if stdout != nil {
key := streamKey(c.id, name, Stdout)
oldStdout = c.stdoutGroup.Get(key)
c.stdoutGroup.Add(key, stdout)
}
if stderr != nil {
key := streamKey(c.id, name, Stderr)
oldStderr = c.stderrGroup.Get(key)
c.stderrGroup.Add(key, stderr)
}
return oldStdout, oldStderr
}
// Cancel cancels container io.

View File

@@ -161,11 +161,11 @@ func loadContainer(ctx context.Context, cntr containerd.Container, containerDir
}
containerIO, err = cio.NewContainerIO(id,
cio.WithFIFOs(fifos),
cio.WithOutput("log", stdoutWC, stderrWC),
)
if err != nil {
return nil, err
}
containerIO.AddOutput("log", stdoutWC, stderrWC)
containerIO.Pipe()
return containerIO, nil
})