Shutdown plugins during daemon shutdown.
Signed-off-by: Anusha Ragunathan <anusha@docker.com> Upstream-commit: 863ab9ab134d0baef3c7e5d745eded891e87e734 Component: engine
This commit is contained in:
@ -47,6 +47,7 @@ type plugin struct {
|
||||
client *plugins.Client
|
||||
restartManager restartmanager.RestartManager
|
||||
runtimeSourcePath string
|
||||
exitChan chan bool
|
||||
}
|
||||
|
||||
func (p *plugin) Client() *plugins.Client {
|
||||
@ -98,6 +99,7 @@ type Manager struct {
|
||||
registryService registry.Service
|
||||
handleLegacy bool
|
||||
liveRestore bool
|
||||
shutdown bool
|
||||
}
|
||||
|
||||
// GetManager returns the singleton plugin Manager
|
||||
@ -250,10 +252,23 @@ func LookupWithCapability(name, capability string) (Plugin, error) {
|
||||
return nil, ErrInadequateCapability{name, capability}
|
||||
}
|
||||
|
||||
// StateChanged updates daemon inter...
|
||||
// StateChanged updates plugin internals using from libcontainerd events.
|
||||
func (pm *Manager) StateChanged(id string, e libcontainerd.StateInfo) error {
|
||||
logrus.Debugf("plugin statechanged %s %#v", id, e)
|
||||
|
||||
switch e.State {
|
||||
case libcontainerd.StateExit:
|
||||
pm.RLock()
|
||||
p, idOk := pm.plugins[id]
|
||||
pm.RUnlock()
|
||||
if !idOk {
|
||||
return ErrNotFound(id)
|
||||
}
|
||||
if pm.shutdown == true {
|
||||
p.exitChan <- true
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/libcontainerd"
|
||||
@ -128,3 +129,39 @@ func (pm *Manager) disable(p *plugin) error {
|
||||
pm.save()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Shutdown stops all plugins and called during daemon shutdown.
|
||||
func (pm *Manager) Shutdown() {
|
||||
pm.RLock()
|
||||
defer pm.RUnlock()
|
||||
|
||||
pm.shutdown = true
|
||||
for _, p := range pm.plugins {
|
||||
if p.restartManager != nil {
|
||||
if err := p.restartManager.Cancel(); err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
}
|
||||
if pm.containerdClient != nil {
|
||||
p.exitChan = make(chan bool)
|
||||
err := pm.containerdClient.Signal(p.P.ID, int(syscall.SIGTERM))
|
||||
if err != nil {
|
||||
logrus.Errorf("Sending SIGTERM to plugin failed with error: %v", err)
|
||||
} else {
|
||||
select {
|
||||
case <-p.exitChan:
|
||||
logrus.Debug("Clean shutdown of plugin")
|
||||
case <-time.After(time.Second * 10):
|
||||
logrus.Debug("Force shutdown plugin")
|
||||
if err := pm.containerdClient.Signal(p.P.ID, int(syscall.SIGKILL)); err != nil {
|
||||
logrus.Errorf("Sending SIGKILL to plugin failed with error: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
close(p.exitChan)
|
||||
}
|
||||
if err := os.RemoveAll(p.runtimeSourcePath); err != nil {
|
||||
logrus.Errorf("Remove plugin runtime failed with error: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,3 +23,7 @@ func (pm *Manager) disable(p *plugin) error {
|
||||
func (pm *Manager) restore(p *plugin) error {
|
||||
return fmt.Errorf("Not implemented")
|
||||
}
|
||||
|
||||
// Shutdown plugins
|
||||
func (pm *Manager) Shutdown() {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user