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:
parent
742a7d53f2
commit
b464f1d78c
11 changed files with 62 additions and 10 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue