Browse code

Handle Plugin reference count during network create and delete

Signed-off-by: Madhu Venugopal <madhu@docker.com>

Madhu Venugopal authored on 2016/12/17 05:53:22
Showing 2 changed files
... ...
@@ -12,8 +12,11 @@ import (
12 12
 	"github.com/docker/docker/api/types"
13 13
 	"github.com/docker/docker/api/types/network"
14 14
 	clustertypes "github.com/docker/docker/daemon/cluster/provider"
15
+	"github.com/docker/docker/pkg/plugingetter"
15 16
 	"github.com/docker/docker/runconfig"
16 17
 	"github.com/docker/libnetwork"
18
+	"github.com/docker/libnetwork/driverapi"
19
+	"github.com/docker/libnetwork/ipamapi"
17 20
 	networktypes "github.com/docker/libnetwork/types"
18 21
 	"github.com/pkg/errors"
19 22
 	"golang.org/x/net/context"
... ...
@@ -298,6 +301,10 @@ func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string
298 298
 		return nil, err
299 299
 	}
300 300
 
301
+	daemon.pluginRefCount(driver, driverapi.NetworkPluginEndpointType, plugingetter.ACQUIRE)
302
+	if create.IPAM != nil {
303
+		daemon.pluginRefCount(create.IPAM.Driver, ipamapi.PluginEndpointType, plugingetter.ACQUIRE)
304
+	}
301 305
 	daemon.LogNetworkEvent(n, "create")
302 306
 
303 307
 	return &types.NetworkCreateResponse{
... ...
@@ -306,6 +313,29 @@ func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string
306 306
 	}, nil
307 307
 }
308 308
 
309
+func (daemon *Daemon) pluginRefCount(driver, capability string, mode int) {
310
+	var builtinDrivers []string
311
+
312
+	if capability == driverapi.NetworkPluginEndpointType {
313
+		builtinDrivers = daemon.netController.BuiltinDrivers()
314
+	} else if capability == ipamapi.PluginEndpointType {
315
+		builtinDrivers = daemon.netController.BuiltinIPAMDrivers()
316
+	}
317
+
318
+	for _, d := range builtinDrivers {
319
+		if d == driver {
320
+			return
321
+		}
322
+	}
323
+
324
+	if daemon.PluginStore != nil {
325
+		_, err := daemon.PluginStore.Get(driver, capability, mode)
326
+		if err != nil {
327
+			logrus.WithError(err).WithFields(logrus.Fields{"mode": mode, "driver": driver}).Error("Error handling plugin refcount operation")
328
+		}
329
+	}
330
+}
331
+
309 332
 func getIpamConfig(data []network.IPAMConfig) ([]*libnetwork.IpamConf, []*libnetwork.IpamConf, error) {
310 333
 	ipamV4Cfg := []*libnetwork.IpamConf{}
311 334
 	ipamV6Cfg := []*libnetwork.IpamConf{}
... ...
@@ -420,6 +450,9 @@ func (daemon *Daemon) deleteNetwork(networkID string, dynamic bool) error {
420 420
 	if err := nw.Delete(); err != nil {
421 421
 		return err
422 422
 	}
423
+	daemon.pluginRefCount(nw.Type(), driverapi.NetworkPluginEndpointType, plugingetter.RELEASE)
424
+	ipamType, _, _, _ := nw.Info().IpamConfig()
425
+	daemon.pluginRefCount(ipamType, ipamapi.PluginEndpointType, plugingetter.RELEASE)
423 426
 	daemon.LogNetworkEvent(nw, "destroy")
424 427
 	return nil
425 428
 }
... ...
@@ -16,8 +16,10 @@ import (
16 16
 var (
17 17
 	pluginProcessName = "sample-volume-plugin"
18 18
 	pName             = "tonistiigi/sample-volume-plugin"
19
+	npName            = "tonistiigi/test-docker-netplugin"
19 20
 	pTag              = "latest"
20 21
 	pNameWithTag      = pName + ":" + pTag
22
+	npNameWithTag     = npName + ":" + pTag
21 23
 )
22 24
 
23 25
 func (s *DockerSuite) TestPluginBasicOps(c *check.C) {
... ...
@@ -87,6 +89,33 @@ func (s *DockerSuite) TestPluginActive(c *check.C) {
87 87
 	c.Assert(out, checker.Contains, pNameWithTag)
88 88
 }
89 89
 
90
+func (s *DockerSuite) TestPluginActiveNetwork(c *check.C) {
91
+	testRequires(c, DaemonIsLinux, IsAmd64, Network)
92
+	out, _, err := dockerCmdWithError("plugin", "install", "--grant-all-permissions", npNameWithTag)
93
+	c.Assert(err, checker.IsNil)
94
+
95
+	out, _, err = dockerCmdWithError("network", "create", "-d", npNameWithTag, "test")
96
+	c.Assert(err, checker.IsNil)
97
+
98
+	nID := strings.TrimSpace(out)
99
+
100
+	out, _, err = dockerCmdWithError("plugin", "remove", npNameWithTag)
101
+	c.Assert(out, checker.Contains, "is in use")
102
+
103
+	_, _, err = dockerCmdWithError("network", "rm", nID)
104
+	c.Assert(err, checker.IsNil)
105
+
106
+	out, _, err = dockerCmdWithError("plugin", "remove", npNameWithTag)
107
+	c.Assert(out, checker.Contains, "is enabled")
108
+
109
+	_, _, err = dockerCmdWithError("plugin", "disable", npNameWithTag)
110
+	c.Assert(err, checker.IsNil)
111
+
112
+	out, _, err = dockerCmdWithError("plugin", "remove", npNameWithTag)
113
+	c.Assert(err, checker.IsNil)
114
+	c.Assert(out, checker.Contains, npNameWithTag)
115
+}
116
+
90 117
 func (s *DockerSuite) TestPluginInstallDisable(c *check.C) {
91 118
 	testRequires(c, DaemonIsLinux, IsAmd64, Network)
92 119
 	out, _, err := dockerCmdWithError("plugin", "install", "--grant-all-permissions", "--disable", pName)