manager_linux.go 2.3 KB

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