github.com/vieux/docker@v0.6.3-0.20161004191708-e097c2a938c7/plugin/manager_linux.go (about)

     1  // +build linux,experimental
     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/api/types/container"
    13  	"github.com/docker/docker/libcontainerd"
    14  	"github.com/docker/docker/oci"
    15  	"github.com/docker/docker/pkg/plugins"
    16  	"github.com/docker/docker/plugin/v2"
    17  	"github.com/docker/docker/restartmanager"
    18  	"github.com/opencontainers/runtime-spec/specs-go"
    19  )
    20  
    21  func (pm *Manager) enable(p *v2.Plugin, force bool) error {
    22  	if p.IsEnabled() && !force {
    23  		return fmt.Errorf("plugin %s is already enabled", p.Name())
    24  	}
    25  	spec, err := p.InitSpec(oci.DefaultSpec(), pm.libRoot)
    26  	if err != nil {
    27  		return err
    28  	}
    29  
    30  	p.RestartManager = restartmanager.New(container.RestartPolicy{Name: "always"}, 0)
    31  	if err := pm.containerdClient.Create(p.GetID(), "", "", specs.Spec(*spec), libcontainerd.WithRestartManager(p.RestartManager)); err != nil {
    32  		if err := p.RestartManager.Cancel(); err != nil {
    33  			logrus.Errorf("enable: restartManager.Cancel failed due to %v", err)
    34  		}
    35  		return err
    36  	}
    37  
    38  	p.PClient, err = plugins.NewClient("unix://"+filepath.Join(p.RuntimeSourcePath, p.GetSocket()), nil)
    39  	if err != nil {
    40  		if err := p.RestartManager.Cancel(); err != nil {
    41  			logrus.Errorf("enable: restartManager.Cancel failed due to %v", err)
    42  		}
    43  		return err
    44  	}
    45  
    46  	pm.pluginStore.SetState(p, true)
    47  	pm.pluginStore.CallHandler(p)
    48  
    49  	return nil
    50  }
    51  
    52  func (pm *Manager) restore(p *v2.Plugin) error {
    53  	p.RestartManager = restartmanager.New(container.RestartPolicy{Name: "always"}, 0)
    54  	return pm.containerdClient.Restore(p.GetID(), libcontainerd.WithRestartManager(p.RestartManager))
    55  }
    56  
    57  func (pm *Manager) disable(p *v2.Plugin) error {
    58  	if !p.IsEnabled() {
    59  		return fmt.Errorf("plugin %s is already disabled", p.Name())
    60  	}
    61  	if err := p.RestartManager.Cancel(); err != nil {
    62  		logrus.Error(err)
    63  	}
    64  	if err := pm.containerdClient.Signal(p.GetID(), int(syscall.SIGKILL)); err != nil {
    65  		logrus.Error(err)
    66  	}
    67  	if err := p.RemoveFromDisk(); err != nil {
    68  		logrus.Error(err)
    69  	}
    70  	pm.pluginStore.SetState(p, false)
    71  	return nil
    72  }
    73  
    74  // Shutdown stops all plugins and called during daemon shutdown.
    75  func (pm *Manager) Shutdown() {
    76  	pm.Lock()
    77  	pm.shutdown = true
    78  	pm.Unlock()
    79  
    80  	pm.RLock()
    81  	defer pm.RUnlock()
    82  	plugins := pm.pluginStore.GetAll()
    83  	for _, p := range plugins {
    84  		if pm.liveRestore && p.IsEnabled() {
    85  			logrus.Debug("Plugin active when liveRestore is set, skipping shutdown")
    86  			continue
    87  		}
    88  		if p.RestartManager != nil {
    89  			if err := p.RestartManager.Cancel(); err != nil {
    90  				logrus.Error(err)
    91  			}
    92  		}
    93  		if pm.containerdClient != nil && p.IsEnabled() {
    94  			pluginID := p.GetID()
    95  			p.ExitChan = make(chan bool)
    96  			err := pm.containerdClient.Signal(p.PluginObj.ID, int(syscall.SIGTERM))
    97  			if err != nil {
    98  				logrus.Errorf("Sending SIGTERM to plugin failed with error: %v", err)
    99  			} else {
   100  				select {
   101  				case <-p.ExitChan:
   102  					logrus.Debug("Clean shutdown of plugin")
   103  				case <-time.After(time.Second * 10):
   104  					logrus.Debug("Force shutdown plugin")
   105  					if err := pm.containerdClient.Signal(pluginID, int(syscall.SIGKILL)); err != nil {
   106  						logrus.Errorf("Sending SIGKILL to plugin failed with error: %v", err)
   107  					}
   108  				}
   109  			}
   110  		}
   111  		if err := p.RemoveFromDisk(); err != nil {
   112  			logrus.Errorf("Remove plugin runtime failed with error: %v", err)
   113  		}
   114  	}
   115  }