When daemon has liveRestore set, daemon shutdown should not shutdown
plugins. Fixes #24759
Signed-off-by: Anusha Ragunathan <anusha@docker.com>
(cherry picked from commit 4a44cf1d4c8e540b67aaa3834291a964c6ab7524)
Signed-off-by: Tibor Vass <tibor@docker.com>
| ... | ... |
@@ -653,6 +653,9 @@ func (daemon *Daemon) Shutdown() error {
|
| 653 | 653 |
daemon.shutdown = true |
| 654 | 654 |
// Keep mounts and networking running on daemon shutdown if |
| 655 | 655 |
// we are to keep containers running and restore them. |
| 656 |
+ |
|
| 657 |
+ pluginShutdown() |
|
| 658 |
+ |
|
| 656 | 659 |
if daemon.configStore.LiveRestore && daemon.containers != nil {
|
| 657 | 660 |
// check if there are any running containers, if none we should do some cleanup |
| 658 | 661 |
if ls, err := daemon.Containers(&types.ContainerListOptions{}); len(ls) != 0 || err != nil {
|
| ... | ... |
@@ -689,8 +692,6 @@ func (daemon *Daemon) Shutdown() error {
|
| 689 | 689 |
} |
| 690 | 690 |
} |
| 691 | 691 |
|
| 692 |
- pluginShutdown() |
|
| 693 |
- |
|
| 694 | 692 |
if err := daemon.cleanupMounts(); err != nil {
|
| 695 | 693 |
return err |
| 696 | 694 |
} |
| ... | ... |
@@ -74,8 +74,9 @@ func (s *DockerDaemonSuite) TestDaemonRestartWithPluginDisabled(c *check.C) {
|
| 74 | 74 |
c.Assert(out, checker.Contains, "false") |
| 75 | 75 |
} |
| 76 | 76 |
|
| 77 |
-// TestDaemonShutdownLiveRestoreWithPlugins leaves plugin running. |
|
| 78 |
-func (s *DockerDaemonSuite) TestDaemonShutdownLiveRestoreWithPlugins(c *check.C) {
|
|
| 77 |
+// TestDaemonKillLiveRestoreWithPlugins SIGKILLs daemon started with --live-restore. |
|
| 78 |
+// Plugins should continue to run. |
|
| 79 |
+func (s *DockerDaemonSuite) TestDaemonKillLiveRestoreWithPlugins(c *check.C) {
|
|
| 79 | 80 |
if err := s.d.Start("--live-restore"); err != nil {
|
| 80 | 81 |
c.Fatalf("Could not start daemon: %v", err)
|
| 81 | 82 |
} |
| ... | ... |
@@ -104,6 +105,37 @@ func (s *DockerDaemonSuite) TestDaemonShutdownLiveRestoreWithPlugins(c *check.C) |
| 104 | 104 |
} |
| 105 | 105 |
} |
| 106 | 106 |
|
| 107 |
+// TestDaemonShutdownLiveRestoreWithPlugins SIGTERMs daemon started with --live-restore. |
|
| 108 |
+// Plugins should continue to run. |
|
| 109 |
+func (s *DockerDaemonSuite) TestDaemonShutdownLiveRestoreWithPlugins(c *check.C) {
|
|
| 110 |
+ if err := s.d.Start("--live-restore"); err != nil {
|
|
| 111 |
+ c.Fatalf("Could not start daemon: %v", err)
|
|
| 112 |
+ } |
|
| 113 |
+ if out, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", pluginName); err != nil {
|
|
| 114 |
+ c.Fatalf("Could not install plugin: %v %s", err, out)
|
|
| 115 |
+ } |
|
| 116 |
+ defer func() {
|
|
| 117 |
+ if err := s.d.Restart("--live-restore"); err != nil {
|
|
| 118 |
+ c.Fatalf("Could not restart daemon: %v", err)
|
|
| 119 |
+ } |
|
| 120 |
+ if out, err := s.d.Cmd("plugin", "disable", pluginName); err != nil {
|
|
| 121 |
+ c.Fatalf("Could not disable plugin: %v %s", err, out)
|
|
| 122 |
+ } |
|
| 123 |
+ if out, err := s.d.Cmd("plugin", "remove", pluginName); err != nil {
|
|
| 124 |
+ c.Fatalf("Could not remove plugin: %v %s", err, out)
|
|
| 125 |
+ } |
|
| 126 |
+ }() |
|
| 127 |
+ |
|
| 128 |
+ if err := s.d.cmd.Process.Signal(os.Interrupt); err != nil {
|
|
| 129 |
+ c.Fatalf("Could not kill daemon: %v", err)
|
|
| 130 |
+ } |
|
| 131 |
+ |
|
| 132 |
+ cmd := exec.Command("pgrep", "-f", "plugin-no-remove")
|
|
| 133 |
+ if out, ec, err := runCommandWithOutput(cmd); ec != 0 {
|
|
| 134 |
+ c.Fatalf("Expected exit code '0', got %d err: %v output: %s ", ec, err, out)
|
|
| 135 |
+ } |
|
| 136 |
+} |
|
| 137 |
+ |
|
| 107 | 138 |
// TestDaemonShutdownWithPlugins shuts down running plugins. |
| 108 | 139 |
func (s *DockerDaemonSuite) TestDaemonShutdownWithPlugins(c *check.C) {
|
| 109 | 140 |
if err := s.d.Start(); err != nil {
|
| ... | ... |
@@ -319,7 +319,7 @@ func (pm *Manager) init() error {
|
| 319 | 319 |
if requiresManualRestore {
|
| 320 | 320 |
// if liveRestore is not enabled, the plugin will be stopped now so we should enable it |
| 321 | 321 |
if err := pm.enable(p); err != nil {
|
| 322 |
- logrus.Errorf("Error restoring plugin '%s': %s", p.Name(), err)
|
|
| 322 |
+ logrus.Errorf("Error enabling plugin '%s': %s", p.Name(), err)
|
|
| 323 | 323 |
} |
| 324 | 324 |
} |
| 325 | 325 |
}(p) |
| ... | ... |
@@ -135,12 +135,16 @@ func (pm *Manager) Shutdown() {
|
| 135 | 135 |
|
| 136 | 136 |
pm.shutdown = true |
| 137 | 137 |
for _, p := range pm.plugins {
|
| 138 |
+ if pm.liveRestore && p.P.Active {
|
|
| 139 |
+ logrus.Debug("Plugin active when liveRestore is set, skipping shutdown")
|
|
| 140 |
+ continue |
|
| 141 |
+ } |
|
| 138 | 142 |
if p.restartManager != nil {
|
| 139 | 143 |
if err := p.restartManager.Cancel(); err != nil {
|
| 140 | 144 |
logrus.Error(err) |
| 141 | 145 |
} |
| 142 | 146 |
} |
| 143 |
- if pm.containerdClient != nil {
|
|
| 147 |
+ if pm.containerdClient != nil && p.P.Active {
|
|
| 144 | 148 |
p.exitChan = make(chan bool) |
| 145 | 149 |
err := pm.containerdClient.Signal(p.P.ID, int(syscall.SIGTERM)) |
| 146 | 150 |
if err != nil {
|
| ... | ... |
@@ -157,6 +161,10 @@ func (pm *Manager) Shutdown() {
|
| 157 | 157 |
} |
| 158 | 158 |
} |
| 159 | 159 |
close(p.exitChan) |
| 160 |
+ pm.Lock() |
|
| 161 |
+ p.P.Active = false |
|
| 162 |
+ pm.save() |
|
| 163 |
+ pm.Unlock() |
|
| 160 | 164 |
} |
| 161 | 165 |
if err := os.RemoveAll(p.runtimeSourcePath); err != nil {
|
| 162 | 166 |
logrus.Errorf("Remove plugin runtime failed with error: %v", err)
|