From 627bc9172767e94b22f6dc5f88c2874856c55a3a Mon Sep 17 00:00:00 2001 From: Madhu Venugopal Date: Fri, 16 Dec 2016 12:53:22 -0800 Subject: [PATCH] Handle Plugin reference count during network create and delete Signed-off-by: Madhu Venugopal --- daemon/network.go | 33 ++++++++++++++++++++++ integration-cli/docker_cli_plugins_test.go | 29 +++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/daemon/network.go b/daemon/network.go index e1acf7e2e6..8fc9631e3c 100644 --- a/daemon/network.go +++ b/daemon/network.go @@ -12,8 +12,11 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/network" clustertypes "github.com/docker/docker/daemon/cluster/provider" + "github.com/docker/docker/pkg/plugingetter" "github.com/docker/docker/runconfig" "github.com/docker/libnetwork" + "github.com/docker/libnetwork/driverapi" + "github.com/docker/libnetwork/ipamapi" networktypes "github.com/docker/libnetwork/types" "github.com/pkg/errors" "golang.org/x/net/context" @@ -298,6 +301,10 @@ func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string 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") return &types.NetworkCreateResponse{ @@ -306,6 +313,29 @@ func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string }, 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) { ipamV4Cfg := []*libnetwork.IpamConf{} ipamV6Cfg := []*libnetwork.IpamConf{} @@ -420,6 +450,9 @@ func (daemon *Daemon) deleteNetwork(networkID string, dynamic bool) error { if err := nw.Delete(); err != nil { 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") return nil } diff --git a/integration-cli/docker_cli_plugins_test.go b/integration-cli/docker_cli_plugins_test.go index a25df13731..6a24ae8366 100644 --- a/integration-cli/docker_cli_plugins_test.go +++ b/integration-cli/docker_cli_plugins_test.go @@ -16,8 +16,10 @@ import ( var ( pluginProcessName = "sample-volume-plugin" pName = "tonistiigi/sample-volume-plugin" + npName = "tonistiigi/test-docker-netplugin" pTag = "latest" pNameWithTag = pName + ":" + pTag + npNameWithTag = npName + ":" + pTag ) func (s *DockerSuite) TestPluginBasicOps(c *check.C) { @@ -87,6 +89,33 @@ func (s *DockerSuite) TestPluginActive(c *check.C) { 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) { testRequires(c, DaemonIsLinux, IsAmd64, Network) out, _, err := dockerCmdWithError("plugin", "install", "--grant-all-permissions", "--disable", pName)