Browse code

Fix issues with plugin and `--live-restore`

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>

Brian Goff authored on 2016/12/10 02:53:10
Showing 2 changed files
... ...
@@ -129,7 +129,7 @@ func (s *DockerDaemonSuite) TestDaemonShutdownLiveRestoreWithPlugins(c *check.C)
129 129
 
130 130
 // TestDaemonShutdownWithPlugins shuts down running plugins.
131 131
 func (s *DockerDaemonSuite) TestDaemonShutdownWithPlugins(c *check.C) {
132
-	testRequires(c, IsAmd64, Network)
132
+	testRequires(c, IsAmd64, Network, SameHostDaemon)
133 133
 
134 134
 	s.d.Start(c)
135 135
 	if out, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", pName); err != nil {
... ...
@@ -160,6 +160,11 @@ func (s *DockerDaemonSuite) TestDaemonShutdownWithPlugins(c *check.C) {
160 160
 	if out, ec, err := runCommandWithOutput(cmd); ec != 1 {
161 161
 		c.Fatalf("Expected exit code '1', got %d err: %v output: %s ", ec, err, out)
162 162
 	}
163
+
164
+	s.d.Start(c, "--live-restore")
165
+	cmd = exec.Command("pgrep", "-f", pluginProcessName)
166
+	out, _, err := runCommandWithOutput(cmd)
167
+	c.Assert(err, checker.IsNil, check.Commentf(out))
163 168
 }
164 169
 
165 170
 // 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) {