瀏覽代碼

Net dial to the plugin socket during enable.

When a plugin fails to start, we still incorrectly mark it as enabled.
This change verifies that we can dial to the plugin socket to confirm that
the plugin is functional and only then mark the plugin as enabled. Also,
dont delete the plugin on install, if only the enable fails.

Signed-off-by: Anusha Ragunathan <anusha.ragunathan@docker.com>
Anusha Ragunathan 8 年之前
父節點
當前提交
1b41b7a4f4
共有 2 個文件被更改,包括 26 次插入3 次删除
  1. 2 2
      client/plugin_install.go
  2. 24 1
      plugin/manager_linux.go

+ 2 - 2
client/plugin_install.go

@@ -60,8 +60,8 @@ func (cli *Client) PluginInstall(ctx context.Context, name string, options types
 			return
 		}
 
-		err = cli.PluginEnable(ctx, name, types.PluginEnableOptions{Timeout: 0})
-		pw.CloseWithError(err)
+		enableErr := cli.PluginEnable(ctx, name, types.PluginEnableOptions{Timeout: 0})
+		pw.CloseWithError(enableErr)
 	}()
 	return pr, nil
 }

+ 24 - 1
plugin/manager_linux.go

@@ -5,6 +5,7 @@ package plugin
 import (
 	"encoding/json"
 	"fmt"
+	"net"
 	"os"
 	"path/filepath"
 	"syscall"
@@ -77,7 +78,8 @@ func (pm *Manager) enable(p *v2.Plugin, c *controller, force bool) error {
 }
 
 func (pm *Manager) pluginPostStart(p *v2.Plugin, c *controller) error {
-	client, err := plugins.NewClientWithTimeout("unix://"+filepath.Join(pm.config.ExecRoot, p.GetID(), p.GetSocket()), nil, c.timeoutInSecs)
+	sockAddr := filepath.Join(pm.config.ExecRoot, p.GetID(), p.GetSocket())
+	client, err := plugins.NewClientWithTimeout("unix://"+sockAddr, nil, c.timeoutInSecs)
 	if err != nil {
 		c.restart = false
 		shutdownPlugin(p, c, pm.containerdClient)
@@ -85,6 +87,27 @@ func (pm *Manager) pluginPostStart(p *v2.Plugin, c *controller) error {
 	}
 
 	p.SetPClient(client)
+
+	maxRetries := 3
+	var retries int
+	for {
+		time.Sleep(3 * time.Second)
+		retries++
+
+		if retries > maxRetries {
+			logrus.Debugf("error net dialing plugin: %v", err)
+			c.restart = false
+			shutdownPlugin(p, c, pm.containerdClient)
+			return err
+		}
+
+		// net dial into the unix socket to see if someone's listening.
+		conn, err := net.Dial("unix", sockAddr)
+		if err == nil {
+			conn.Close()
+			break
+		}
+	}
 	pm.config.Store.SetState(p, true)
 	pm.config.Store.CallHandler(p)