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 }