Fixes an issue when starting the daemon with live-restore
where previously it was not set, plugins are not running.
Fixes an issue when starting the daemon with live-restore, the plugin
client (for interacting with the plugins HTTP interface) is not set,
causing a panic when the plugin is called.
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit cb6633175c0de0a7ae155c4d378cd2379681554b)
Signed-off-by: Victor Vieux <vieux@docker.com>
| ... | ... |
@@ -145,7 +145,7 @@ func (s *DockerDaemonSuite) TestDaemonShutdownLiveRestoreWithPlugins(c *check.C) |
| 145 | 145 |
|
| 146 | 146 |
// TestDaemonShutdownWithPlugins shuts down running plugins. |
| 147 | 147 |
func (s *DockerDaemonSuite) TestDaemonShutdownWithPlugins(c *check.C) {
|
| 148 |
- testRequires(c, IsAmd64, Network) |
|
| 148 |
+ testRequires(c, IsAmd64, Network, SameHostDaemon) |
|
| 149 | 149 |
|
| 150 | 150 |
if err := s.d.Start(); err != nil {
|
| 151 | 151 |
c.Fatalf("Could not start daemon: %v", err)
|
| ... | ... |
@@ -180,6 +180,11 @@ func (s *DockerDaemonSuite) TestDaemonShutdownWithPlugins(c *check.C) {
|
| 180 | 180 |
if out, ec, err := runCommandWithOutput(cmd); ec != 1 {
|
| 181 | 181 |
c.Fatalf("Expected exit code '1', got %d err: %v output: %s ", ec, err, out)
|
| 182 | 182 |
} |
| 183 |
+ |
|
| 184 |
+ s.d.Start("--live-restore")
|
|
| 185 |
+ cmd = exec.Command("pgrep", "-f", pluginProcessName)
|
|
| 186 |
+ out, _, err := runCommandWithOutput(cmd) |
|
| 187 |
+ c.Assert(err, checker.IsNil, check.Commentf(out)) |
|
| 183 | 188 |
} |
| 184 | 189 |
|
| 185 | 190 |
// TestVolumePlugin tests volume creation using a plugin. |
| ... | ... |
@@ -49,6 +49,10 @@ func (pm *Manager) enable(p *v2.Plugin, c *controller, force bool) error {
|
| 49 | 49 |
return err |
| 50 | 50 |
} |
| 51 | 51 |
|
| 52 |
+ return pm.pluginPostStart(p, c) |
|
| 53 |
+} |
|
| 54 |
+ |
|
| 55 |
+func (pm *Manager) pluginPostStart(p *v2.Plugin, c *controller) error {
|
|
| 52 | 56 |
client, err := plugins.NewClientWithTimeout("unix://"+filepath.Join(p.GetRuntimeSourcePath(), p.GetSocket()), nil, c.timeoutInSecs)
|
| 53 | 57 |
if err != nil {
|
| 54 | 58 |
c.restart = false |
| ... | ... |
@@ -59,12 +63,30 @@ func (pm *Manager) enable(p *v2.Plugin, c *controller, force bool) error {
|
| 59 | 59 |
p.SetPClient(client) |
| 60 | 60 |
pm.pluginStore.SetState(p, true) |
| 61 | 61 |
pm.pluginStore.CallHandler(p) |
| 62 |
- |
|
| 63 | 62 |
return nil |
| 64 | 63 |
} |
| 65 | 64 |
|
| 66 | 65 |
func (pm *Manager) restore(p *v2.Plugin) error {
|
| 67 |
- return pm.containerdClient.Restore(p.GetID(), attachToLog(p.GetID())) |
|
| 66 |
+ if err := pm.containerdClient.Restore(p.GetID(), attachToLog(p.GetID())); err != nil {
|
|
| 67 |
+ return err |
|
| 68 |
+ } |
|
| 69 |
+ |
|
| 70 |
+ if pm.liveRestore {
|
|
| 71 |
+ c := &controller{}
|
|
| 72 |
+ if pids, _ := pm.containerdClient.GetPidsForContainer(p.GetID()); len(pids) == 0 {
|
|
| 73 |
+ // plugin is not running, so follow normal startup procedure |
|
| 74 |
+ return pm.enable(p, c, true) |
|
| 75 |
+ } |
|
| 76 |
+ |
|
| 77 |
+ c.exitChan = make(chan bool) |
|
| 78 |
+ c.restart = true |
|
| 79 |
+ pm.mu.Lock() |
|
| 80 |
+ pm.cMap[p] = c |
|
| 81 |
+ pm.mu.Unlock() |
|
| 82 |
+ return pm.pluginPostStart(p, c) |
|
| 83 |
+ } |
|
| 84 |
+ |
|
| 85 |
+ return nil |
|
| 68 | 86 |
} |
| 69 | 87 |
|
| 70 | 88 |
func shutdownPlugin(p *v2.Plugin, c *controller, containerdClient libcontainerd.Client) {
|