mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			95 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			95 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// +build linux
 | 
						|
 | 
						|
package plugin
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"path/filepath"
 | 
						|
	"syscall"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/Sirupsen/logrus"
 | 
						|
	"github.com/docker/docker/oci"
 | 
						|
	"github.com/docker/docker/pkg/plugins"
 | 
						|
	"github.com/docker/docker/plugin/v2"
 | 
						|
	specs "github.com/opencontainers/runtime-spec/specs-go"
 | 
						|
)
 | 
						|
 | 
						|
func (pm *Manager) enable(p *v2.Plugin, force bool) error {
 | 
						|
	if p.IsEnabled() && !force {
 | 
						|
		return fmt.Errorf("plugin %s is already enabled", p.Name())
 | 
						|
	}
 | 
						|
	spec, err := p.InitSpec(oci.DefaultSpec(), pm.libRoot)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	p.Lock()
 | 
						|
	p.Restart = true
 | 
						|
	p.Unlock()
 | 
						|
	if err := pm.containerdClient.Create(p.GetID(), "", "", specs.Spec(*spec), attachToLog(p.GetID())); err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	p.PClient, err = plugins.NewClient("unix://"+filepath.Join(p.RuntimeSourcePath, p.GetSocket()), nil)
 | 
						|
	if err != nil {
 | 
						|
		p.Lock()
 | 
						|
		p.Restart = false
 | 
						|
		p.Unlock()
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	pm.pluginStore.SetState(p, true)
 | 
						|
	pm.pluginStore.CallHandler(p)
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (pm *Manager) restore(p *v2.Plugin) error {
 | 
						|
	return pm.containerdClient.Restore(p.GetID(), attachToLog(p.GetID()))
 | 
						|
}
 | 
						|
 | 
						|
func (pm *Manager) disable(p *v2.Plugin) error {
 | 
						|
	if !p.IsEnabled() {
 | 
						|
		return fmt.Errorf("plugin %s is already disabled", p.Name())
 | 
						|
	}
 | 
						|
	p.Lock()
 | 
						|
	p.Restart = false
 | 
						|
	p.Unlock()
 | 
						|
	if err := pm.containerdClient.Signal(p.GetID(), int(syscall.SIGKILL)); err != nil {
 | 
						|
		logrus.Error(err)
 | 
						|
	}
 | 
						|
	pm.pluginStore.SetState(p, false)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Shutdown stops all plugins and called during daemon shutdown.
 | 
						|
func (pm *Manager) Shutdown() {
 | 
						|
	plugins := pm.pluginStore.GetAll()
 | 
						|
	for _, p := range plugins {
 | 
						|
		if pm.liveRestore && p.IsEnabled() {
 | 
						|
			logrus.Debug("Plugin active when liveRestore is set, skipping shutdown")
 | 
						|
			continue
 | 
						|
		}
 | 
						|
		if pm.containerdClient != nil && p.IsEnabled() {
 | 
						|
			pluginID := p.GetID()
 | 
						|
			p.Lock()
 | 
						|
			p.ExitChan = make(chan bool)
 | 
						|
			p.Restart = false
 | 
						|
			p.Unlock()
 | 
						|
			err := pm.containerdClient.Signal(p.PluginObj.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(pluginID, int(syscall.SIGKILL)); err != nil {
 | 
						|
						logrus.Errorf("Sending SIGKILL to plugin failed with error: %v", err)
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |