Use containerd client Reconnect() API.

This fixes an issue where the containerd client is cached in a container
object in libcontainerd and becomes stale after containerd is restarted.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This commit is contained in:
Brian Goff 2018-03-23 14:25:53 -04:00
parent 30cb23360e
commit 2c682d5209
3 changed files with 9 additions and 27 deletions

View file

@ -114,6 +114,13 @@ type client struct {
containers map[string]*container
}
func (c *client) reconnect() error {
c.Lock()
err := c.remote.Reconnect()
c.Unlock()
return err
}
func (c *client) setRemote(remote *containerd.Client) {
c.Lock()
c.remote = remote

View file

@ -309,20 +309,17 @@ func (r *remote) monitorConnection(monitor *containerd.Client) {
}
<-r.daemonWaitCh
monitor.Close()
os.Remove(r.GRPC.Address)
if err := r.startContainerd(); err != nil {
r.logger.WithError(err).Error("failed restarting containerd")
continue
}
newMonitor, err := containerd.New(r.GRPC.Address)
if err != nil {
if err := monitor.Reconnect(); err != nil {
r.logger.WithError(err).Error("failed connect to containerd")
continue
}
monitor = newMonitor
var wg sync.WaitGroup
for _, c := range r.clients {
@ -331,18 +328,12 @@ func (r *remote) monitorConnection(monitor *containerd.Client) {
go func(c *client) {
defer wg.Done()
c.logger.WithField("namespace", c.namespace).Debug("creating new containerd remote client")
c.remote.Close()
remote, err := containerd.New(r.GRPC.Address, containerd.WithDefaultNamespace(c.namespace))
if err != nil {
if err := c.reconnect(); err != nil {
r.logger.WithError(err).Error("failed to connect to containerd")
// TODO: Better way to handle this?
// This *shouldn't* happen, but this could wind up where the daemon
// is not able to communicate with an eventually up containerd
return
}
c.setRemote(remote)
}(c)
wg.Wait()

View file

@ -16,19 +16,3 @@ func (o oomScore) Apply(r Remote) error {
}
return fmt.Errorf("WithOOMScore option not supported for this remote")
}
// WithSubreaper sets whether containerd should register itself as a
// subreaper
func WithSubreaper(reap bool) RemoteOption {
return subreaper(reap)
}
type subreaper bool
func (s subreaper) Apply(r Remote) error {
if remote, ok := r.(*remote); ok {
remote.NoSubreaper = !bool(s)
return nil
}
return fmt.Errorf("WithSubreaper option not supported for this remote")
}