Forced endpoint cleanup

docker's network disconnect api now supports `Force` option which can be
used to force cleanup an endpoint from any host in the cluster.

Signed-off-by: Madhu Venugopal <madhu@docker.com>
This commit is contained in:
Madhu Venugopal 2016-01-12 20:56:36 -08:00
parent 742a7d53f2
commit b464f1d78c
11 changed files with 62 additions and 10 deletions

View File

@ -137,12 +137,13 @@ func (cli *DockerCli) CmdNetworkConnect(args ...string) error {
// Usage: docker network disconnect <NETWORK> <CONTAINER>
func (cli *DockerCli) CmdNetworkDisconnect(args ...string) error {
cmd := Cli.Subcmd("network disconnect", []string{"NETWORK CONTAINER"}, "Disconnects container from a network", false)
force := cmd.Bool([]string{"f", "-force"}, false, "Force the container to disconnect from a network")
cmd.Require(flag.Exact, 2)
if err := cmd.ParseFlags(args, true); err != nil {
return err
}
return cli.client.NetworkDisconnect(cmd.Arg(0), cmd.Arg(1), false)
return cli.client.NetworkDisconnect(cmd.Arg(0), cmd.Arg(1), *force)
}
// CmdNetworkLs lists all the networks managed by docker daemon

View File

@ -16,7 +16,7 @@ type Backend interface {
options map[string]string, internal bool) (libnetwork.Network, error)
ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error
DisconnectContainerFromNetwork(containerName string,
network libnetwork.Network) error
network libnetwork.Network, force bool) error
NetworkControllerEnabled() bool
DeleteNetwork(name string) error
}

View File

@ -144,7 +144,7 @@ func (n *networkRouter) postNetworkDisconnect(ctx context.Context, w http.Respon
return err
}
return n.backend.DisconnectContainerFromNetwork(disconnect.Container, nw)
return n.backend.DisconnectContainerFromNetwork(disconnect.Container, nw, disconnect.Force)
}
func (n *networkRouter) deleteNetwork(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {

View File

@ -833,8 +833,17 @@ func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName
return nil
}
// ForceEndpointDelete deletes an endpoing from a network forcefully
func (daemon *Daemon) ForceEndpointDelete(name string, n libnetwork.Network) error {
ep, err := n.EndpointByName(name)
if err != nil {
return err
}
return ep.Delete(true)
}
// DisconnectFromNetwork disconnects container from network n.
func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, n libnetwork.Network) error {
func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, n libnetwork.Network, force bool) error {
if container.HostConfig.NetworkMode.IsHost() && containertypes.NetworkMode(n.Type()).IsHost() {
return runconfig.ErrConflictHostNetwork
}
@ -848,7 +857,7 @@ func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, n li
return fmt.Errorf("container %s is not connected to the network %s", container.ID, n.Name())
}
} else {
if err := disconnectFromNetwork(container, n); err != nil {
if err := disconnectFromNetwork(container, n, false); err != nil {
return err
}
}
@ -864,7 +873,7 @@ func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, n li
return nil
}
func disconnectFromNetwork(container *container.Container, n libnetwork.Network) error {
func disconnectFromNetwork(container *container.Container, n libnetwork.Network, force bool) error {
var (
ep libnetwork.Endpoint
sbox libnetwork.Sandbox
@ -886,6 +895,15 @@ func disconnectFromNetwork(container *container.Container, n libnetwork.Network)
}
n.WalkEndpoints(s)
if ep == nil && force {
epName := strings.TrimPrefix(container.Name, "/")
ep, err := n.EndpointByName(epName)
if err != nil {
return err
}
return ep.Delete(force)
}
if ep == nil {
return fmt.Errorf("container %s is not connected to the network", container.ID)
}

View File

@ -32,8 +32,13 @@ func (daemon *Daemon) ConnectToNetwork(container *container.Container, idOrName
return nil
}
// ForceEndpointDelete deletes an endpoing from a network forcefully
func (daemon *Daemon) ForceEndpointDelete(name string, n libnetwork.Network) error {
return nil
}
// DisconnectFromNetwork disconnects a container from the network.
func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, n libnetwork.Network) error {
func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, n libnetwork.Network, force bool) error {
return nil
}

View File

@ -163,12 +163,15 @@ func (daemon *Daemon) ConnectContainerToNetwork(containerName, networkName strin
// DisconnectContainerFromNetwork disconnects the given container from
// the given network. If either cannot be found, an err is returned.
func (daemon *Daemon) DisconnectContainerFromNetwork(containerName string, network libnetwork.Network) error {
func (daemon *Daemon) DisconnectContainerFromNetwork(containerName string, network libnetwork.Network, force bool) error {
container, err := daemon.GetContainer(containerName)
if err != nil {
if force {
return daemon.ForceEndpointDelete(containerName, network)
}
return err
}
return daemon.DisconnectFromNetwork(container, network)
return daemon.DisconnectFromNetwork(container, network, force)
}
// GetNetworkDriverList returns the list of plugins drivers

View File

@ -115,6 +115,7 @@ This section lists each version from latest to oldest. Each listing includes a
* `POST /networks/(id)/connect` now allows you to set the static IPv4 and/or IPv6 address for the container.
* `GET /info` now includes the number of containers running, stopped, and paused.
* `POST /networks/create` now supports restricting external access to the network by setting the `internal` field.
* `POST /networks/(id)/disconnect` now includes a `Force` option to forcefully disconnect a container from network
### v1.21 API changes

View File

@ -3073,7 +3073,8 @@ POST /networks/22be93d5babb089c5aab8dbc369042fad48ff791584ca2da2100db837a1c7c30/
Content-Type: application/json
{
"Container":"3613f73ba0e4"
"Container":"3613f73ba0e4",
"Force":false
}
```
@ -3090,6 +3091,7 @@ Status Codes:
JSON Parameters:
- **Container** - container-id/name to be disconnected from a network
- **Force** - Force the container to disconnect from a network
### Remove a network

View File

@ -12,8 +12,10 @@ parent = "smn_cli"
Usage: docker network disconnect [OPTIONS] NETWORK CONTAINER
Disconnects a container from a network
-f, --force Force the container to disconnect from a network
--help Print usage
Disconnects a container from a network. The container must be running to disconnect it from the network.

View File

@ -448,6 +448,22 @@ func (s *DockerNetworkSuite) TestDockerNetworkConnectDisconnect(c *check.C) {
c.Assert(nr.Name, checker.Equals, "test")
c.Assert(len(nr.Containers), checker.Equals, 0)
// run another container
out, _ = dockerCmd(c, "run", "-d", "--net", "test", "--name", "test2", "busybox", "top")
c.Assert(waitRun("test2"), check.IsNil)
containerID = strings.TrimSpace(out)
nr = getNwResource(c, "test")
c.Assert(nr.Name, checker.Equals, "test")
c.Assert(len(nr.Containers), checker.Equals, 1)
// force disconnect the container to the test network
dockerCmd(c, "network", "disconnect", "-f", "test", containerID)
nr = getNwResource(c, "test")
c.Assert(nr.Name, checker.Equals, "test")
c.Assert(len(nr.Containers), checker.Equals, 0)
dockerCmd(c, "network", "rm", "test")
assertNwNotAvailable(c, "test")
}

View File

@ -7,6 +7,7 @@ docker-network-disconnect - disconnect a container from a network
# SYNOPSIS
**docker network disconnect**
[**--help**]
[**--force**]
NETWORK CONTAINER
# DESCRIPTION
@ -25,6 +26,9 @@ Disconnects a container from a network.
**CONTAINER**
Specify container name
**--force**
Force the container to disconnect from a network
**--help**
Print usage statement