Sfoglia il codice sorgente

Handle Plugin reference count during network create and delete

Signed-off-by: Madhu Venugopal <madhu@docker.com>
Madhu Venugopal 8 anni fa
parent
commit
fc2c0e623d
2 ha cambiato i file con 62 aggiunte e 0 eliminazioni
  1. 33 0
      daemon/network.go
  2. 29 0
      integration-cli/docker_cli_plugins_test.go

+ 33 - 0
daemon/network.go

@@ -12,8 +12,11 @@ import (
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/network"
 	"github.com/docker/docker/api/types/network"
 	clustertypes "github.com/docker/docker/daemon/cluster/provider"
 	clustertypes "github.com/docker/docker/daemon/cluster/provider"
+	"github.com/docker/docker/pkg/plugingetter"
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/libnetwork"
 	"github.com/docker/libnetwork"
+	"github.com/docker/libnetwork/driverapi"
+	"github.com/docker/libnetwork/ipamapi"
 	networktypes "github.com/docker/libnetwork/types"
 	networktypes "github.com/docker/libnetwork/types"
 	"github.com/pkg/errors"
 	"github.com/pkg/errors"
 	"golang.org/x/net/context"
 	"golang.org/x/net/context"
@@ -298,6 +301,10 @@ func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string
 		return nil, err
 		return nil, err
 	}
 	}
 
 
+	daemon.pluginRefCount(driver, driverapi.NetworkPluginEndpointType, plugingetter.ACQUIRE)
+	if create.IPAM != nil {
+		daemon.pluginRefCount(create.IPAM.Driver, ipamapi.PluginEndpointType, plugingetter.ACQUIRE)
+	}
 	daemon.LogNetworkEvent(n, "create")
 	daemon.LogNetworkEvent(n, "create")
 
 
 	return &types.NetworkCreateResponse{
 	return &types.NetworkCreateResponse{
@@ -306,6 +313,29 @@ func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string
 	}, nil
 	}, nil
 }
 }
 
 
+func (daemon *Daemon) pluginRefCount(driver, capability string, mode int) {
+	var builtinDrivers []string
+
+	if capability == driverapi.NetworkPluginEndpointType {
+		builtinDrivers = daemon.netController.BuiltinDrivers()
+	} else if capability == ipamapi.PluginEndpointType {
+		builtinDrivers = daemon.netController.BuiltinIPAMDrivers()
+	}
+
+	for _, d := range builtinDrivers {
+		if d == driver {
+			return
+		}
+	}
+
+	if daemon.PluginStore != nil {
+		_, err := daemon.PluginStore.Get(driver, capability, mode)
+		if err != nil {
+			logrus.WithError(err).WithFields(logrus.Fields{"mode": mode, "driver": driver}).Error("Error handling plugin refcount operation")
+		}
+	}
+}
+
 func getIpamConfig(data []network.IPAMConfig) ([]*libnetwork.IpamConf, []*libnetwork.IpamConf, error) {
 func getIpamConfig(data []network.IPAMConfig) ([]*libnetwork.IpamConf, []*libnetwork.IpamConf, error) {
 	ipamV4Cfg := []*libnetwork.IpamConf{}
 	ipamV4Cfg := []*libnetwork.IpamConf{}
 	ipamV6Cfg := []*libnetwork.IpamConf{}
 	ipamV6Cfg := []*libnetwork.IpamConf{}
@@ -420,6 +450,9 @@ func (daemon *Daemon) deleteNetwork(networkID string, dynamic bool) error {
 	if err := nw.Delete(); err != nil {
 	if err := nw.Delete(); err != nil {
 		return err
 		return err
 	}
 	}
+	daemon.pluginRefCount(nw.Type(), driverapi.NetworkPluginEndpointType, plugingetter.RELEASE)
+	ipamType, _, _, _ := nw.Info().IpamConfig()
+	daemon.pluginRefCount(ipamType, ipamapi.PluginEndpointType, plugingetter.RELEASE)
 	daemon.LogNetworkEvent(nw, "destroy")
 	daemon.LogNetworkEvent(nw, "destroy")
 	return nil
 	return nil
 }
 }

+ 29 - 0
integration-cli/docker_cli_plugins_test.go

@@ -16,8 +16,10 @@ import (
 var (
 var (
 	pluginProcessName = "sample-volume-plugin"
 	pluginProcessName = "sample-volume-plugin"
 	pName             = "tonistiigi/sample-volume-plugin"
 	pName             = "tonistiigi/sample-volume-plugin"
+	npName            = "tonistiigi/test-docker-netplugin"
 	pTag              = "latest"
 	pTag              = "latest"
 	pNameWithTag      = pName + ":" + pTag
 	pNameWithTag      = pName + ":" + pTag
+	npNameWithTag     = npName + ":" + pTag
 )
 )
 
 
 func (s *DockerSuite) TestPluginBasicOps(c *check.C) {
 func (s *DockerSuite) TestPluginBasicOps(c *check.C) {
@@ -87,6 +89,33 @@ func (s *DockerSuite) TestPluginActive(c *check.C) {
 	c.Assert(out, checker.Contains, pNameWithTag)
 	c.Assert(out, checker.Contains, pNameWithTag)
 }
 }
 
 
+func (s *DockerSuite) TestPluginActiveNetwork(c *check.C) {
+	testRequires(c, DaemonIsLinux, IsAmd64, Network)
+	out, _, err := dockerCmdWithError("plugin", "install", "--grant-all-permissions", npNameWithTag)
+	c.Assert(err, checker.IsNil)
+
+	out, _, err = dockerCmdWithError("network", "create", "-d", npNameWithTag, "test")
+	c.Assert(err, checker.IsNil)
+
+	nID := strings.TrimSpace(out)
+
+	out, _, err = dockerCmdWithError("plugin", "remove", npNameWithTag)
+	c.Assert(out, checker.Contains, "is in use")
+
+	_, _, err = dockerCmdWithError("network", "rm", nID)
+	c.Assert(err, checker.IsNil)
+
+	out, _, err = dockerCmdWithError("plugin", "remove", npNameWithTag)
+	c.Assert(out, checker.Contains, "is enabled")
+
+	_, _, err = dockerCmdWithError("plugin", "disable", npNameWithTag)
+	c.Assert(err, checker.IsNil)
+
+	out, _, err = dockerCmdWithError("plugin", "remove", npNameWithTag)
+	c.Assert(err, checker.IsNil)
+	c.Assert(out, checker.Contains, npNameWithTag)
+}
+
 func (s *DockerSuite) TestPluginInstallDisable(c *check.C) {
 func (s *DockerSuite) TestPluginInstallDisable(c *check.C) {
 	testRequires(c, DaemonIsLinux, IsAmd64, Network)
 	testRequires(c, DaemonIsLinux, IsAmd64, Network)
 	out, _, err := dockerCmdWithError("plugin", "install", "--grant-all-permissions", "--disable", pName)
 	out, _, err := dockerCmdWithError("plugin", "install", "--grant-all-permissions", "--disable", pName)