diff --git a/libnetwork/endpoint.go b/libnetwork/endpoint.go index 734fbe98a9..e92d610dcc 100644 --- a/libnetwork/endpoint.go +++ b/libnetwork/endpoint.go @@ -296,6 +296,9 @@ func (ep *endpoint) Leave(containerID string, options ...EndpointOption) error { func (ep *endpoint) Delete() error { var err error + if ep.container != nil { + return &ActiveContainerError{name: ep.name, id: string(ep.id)} + } n := ep.network n.Lock() diff --git a/libnetwork/error.go b/libnetwork/error.go index add594079d..eaefe9e95a 100644 --- a/libnetwork/error.go +++ b/libnetwork/error.go @@ -65,6 +65,17 @@ func (uee *UnknownEndpointError) Error() string { return fmt.Sprintf("unknown endpoint %s id %s", uee.name, uee.id) } +// ActiveContainerError is returned when an endpoint is deleted which has active +// containers attached to it. +type ActiveContainerError struct { + name string + id string +} + +func (ace *ActiveContainerError) Error() string { + return fmt.Sprintf("endpoint with name %s id %s has active containers", ace.name, ace.id) +} + // InvalidContainerIDError is returned when an invalid container id is passed // in Join/Leave type InvalidContainerIDError string diff --git a/libnetwork/libnetwork_test.go b/libnetwork/libnetwork_test.go index e84fb890e7..c3577fa048 100644 --- a/libnetwork/libnetwork_test.go +++ b/libnetwork/libnetwork_test.go @@ -635,6 +635,37 @@ func TestEndpointJoinInvalidContainerId(t *testing.T) { } } +func TestEndpointDeleteWithActiveContainer(t *testing.T) { + defer netutils.SetupTestNetNS(t)() + + n, err := createTestNetwork(bridgeNetType, "testnetwork", options.Generic{}, options.Generic{}) + if err != nil { + t.Fatal(err) + } + + ep, err := n.CreateEndpoint("ep1") + if err != nil { + t.Fatal(err) + } + + _, err = ep.Join(containerID, + libnetwork.JoinOptionHostname("test"), + libnetwork.JoinOptionDomainname("docker.io"), + libnetwork.JoinOptionExtraHost("web", "192.168.0.1")) + if err != nil { + t.Fatal(err) + } + + err = ep.Delete() + if err == nil { + t.Fatal("Expected to fail. But instead succeeded") + } + + if _, ok := err.(*libnetwork.ActiveContainerError); !ok { + t.Fatalf("Did not fail with expected error. Actual error: %v", err) + } +} + func TestEndpointMultipleJoins(t *testing.T) { defer netutils.SetupTestNetNS(t)()