github.com/endophage/docker@v1.4.2-0.20161027011718-242853499895/plugin/manager_linux.go (about)

     1  // +build linux
     2  
     3  package plugin
     4  
     5  import (
     6  	"fmt"
     7  	"path/filepath"
     8  	"syscall"
     9  	"time"
    10  
    11  	"github.com/Sirupsen/logrus"
    12  	"github.com/docker/docker/oci"
    13  	"github.com/docker/docker/pkg/plugins"
    14  	"github.com/docker/docker/plugin/v2"
    15  	specs "github.com/opencontainers/runtime-spec/specs-go"
    16  )
    17  
    18  func (pm *Manager) enable(p *v2.Plugin, force bool) error {
    19  	if p.IsEnabled() && !force {
    20  		return fmt.Errorf("plugin %s is already enabled", p.Name())
    21  	}
    22  	spec, err := p.InitSpec(oci.DefaultSpec(), pm.libRoot)
    23  	if err != nil {
    24  		return err
    25  	}
    26  	p.Lock()
    27  	p.Restart = true
    28  	p.Unlock()
    29  	if err := pm.containerdClient.Create(p.GetID(), "", "", specs.Spec(*spec), attachToLog(p.GetID())); err != nil {
    30  		return err
    31  	}
    32  
    33  	p.PClient, err = plugins.NewClient("unix://"+filepath.Join(p.RuntimeSourcePath, p.GetSocket()), nil)
    34  	if err != nil {
    35  		p.Lock()
    36  		p.Restart = false
    37  		p.Unlock()
    38  		return err
    39  	}
    40  
    41  	pm.pluginStore.SetState(p, true)
    42  	pm.pluginStore.CallHandler(p)
    43  
    44  	return nil
    45  }
    46  
    47  func (pm *Manager) restore(p *v2.Plugin) error {
    48  	return pm.containerdClient.Restore(p.GetID(), attachToLog(p.GetID()))
    49  }
    50  
    51  func (pm *Manager) disable(p *v2.Plugin) error {
    52  	if !p.IsEnabled() {
    53  		return fmt.Errorf("plugin %s is already disabled", p.Name())
    54  	}
    55  	p.Lock()
    56  	p.Restart = false
    57  	p.Unlock()
    58  	if err := pm.containerdClient.Signal(p.GetID(), int(syscall.SIGKILL)); err != nil {
    59  		logrus.Error(err)
    60  	}
    61  	pm.pluginStore.SetState(p, false)
    62  	return nil
    63  }
    64  
    65  // Shutdown stops all plugins and called during daemon shutdown.
    66  func (pm *Manager) Shutdown() {
    67  	plugins := pm.pluginStore.GetAll()
    68  	for _, p := range plugins {
    69  		if pm.liveRestore && p.IsEnabled() {
    70  			logrus.Debug("Plugin active when liveRestore is set, skipping shutdown")
    71  			continue
    72  		}
    73  		if pm.containerdClient != nil && p.IsEnabled() {
    74  			pluginID := p.GetID()
    75  			p.Lock()
    76  			p.ExitChan = make(chan bool)
    77  			p.Restart = false
    78  			p.Unlock()
    79  			err := pm.containerdClient.Signal(p.PluginObj.ID, int(syscall.SIGTERM))
    80  			if err != nil {
    81  				logrus.Errorf("Sending SIGTERM to plugin failed with error: %v", err)
    82  			} else {
    83  				select {
    84  				case <-p.ExitChan:
    85  					logrus.Debug("Clean shutdown of plugin")
    86  				case <-time.After(time.Second * 10):
    87  					logrus.Debug("Force shutdown plugin")
    88  					if err := pm.containerdClient.Signal(pluginID, int(syscall.SIGKILL)); err != nil {
    89  						logrus.Errorf("Sending SIGKILL to plugin failed with error: %v", err)
    90  					}
    91  				}
    92  			}
    93  		}
    94  	}
    95  }