Signed-off-by: David Calavera <david.calavera@gmail.com>
| ... | ... |
@@ -148,21 +148,7 @@ func (n *networkRouter) postNetworkDisconnect(ctx context.Context, w http.Respon |
| 148 | 148 |
} |
| 149 | 149 |
|
| 150 | 150 |
func (n *networkRouter) deleteNetwork(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
| 151 |
- if err := httputils.ParseForm(r); err != nil {
|
|
| 152 |
- return err |
|
| 153 |
- } |
|
| 154 |
- |
|
| 155 |
- nw, err := n.backend.FindNetwork(vars["id"]) |
|
| 156 |
- if err != nil {
|
|
| 157 |
- return err |
|
| 158 |
- } |
|
| 159 |
- |
|
| 160 |
- if runconfig.IsPreDefinedNetwork(nw.Name()) {
|
|
| 161 |
- return httputils.WriteJSON(w, http.StatusForbidden, |
|
| 162 |
- fmt.Sprintf("%s is a pre-defined network and cannot be removed", nw.Name()))
|
|
| 163 |
- } |
|
| 164 |
- |
|
| 165 |
- return nw.Delete() |
|
| 151 |
+ return n.backend.DeleteNetwork(vars["id"]) |
|
| 166 | 152 |
} |
| 167 | 153 |
|
| 168 | 154 |
func buildNetworkResource(nw libnetwork.Network) *types.NetworkResource {
|
| ... | ... |
@@ -699,6 +699,7 @@ func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName |
| 699 | 699 |
return derr.ErrorCodeJoinInfo.WithArgs(err) |
| 700 | 700 |
} |
| 701 | 701 |
|
| 702 |
+ daemon.LogNetworkEventWithAttributes(n, "connect", map[string]string{"container": container.ID})
|
|
| 702 | 703 |
return nil |
| 703 | 704 |
} |
| 704 | 705 |
|
| ... | ... |
@@ -850,11 +851,15 @@ func (daemon *Daemon) releaseNetwork(container *container.Container) {
|
| 850 | 850 |
|
| 851 | 851 |
sid := container.NetworkSettings.SandboxID |
| 852 | 852 |
settings := container.NetworkSettings.Networks |
| 853 |
+ var networks []libnetwork.Network |
|
| 853 | 854 |
for n := range settings {
|
| 855 |
+ if nw, err := daemon.FindNetwork(n); err == nil {
|
|
| 856 |
+ networks = append(networks, nw) |
|
| 857 |
+ } |
|
| 854 | 858 |
settings[n] = &networktypes.EndpointSettings{}
|
| 855 | 859 |
} |
| 856 | 860 |
|
| 857 |
- container.NetworkSettings = &network.Settings{Networks: networks}
|
|
| 861 |
+ container.NetworkSettings = &network.Settings{Networks: settings}
|
|
| 858 | 862 |
|
| 859 | 863 |
if sid == "" || len(settings) == 0 {
|
| 860 | 864 |
return |
| ... | ... |
@@ -873,8 +878,8 @@ func (daemon *Daemon) releaseNetwork(container *container.Container) {
|
| 873 | 873 |
attributes := map[string]string{
|
| 874 | 874 |
"container": container.ID, |
| 875 | 875 |
} |
| 876 |
- for nwID := range settings {
|
|
| 877 |
- daemon.logNetworkEventWithID(nwID, "disconnect", attributes) |
|
| 876 |
+ for _, nw := range networks {
|
|
| 877 |
+ daemon.LogNetworkEventWithAttributes(nw, "disconnect", attributes) |
|
| 878 | 878 |
} |
| 879 | 879 |
} |
| 880 | 880 |
|
| ... | ... |
@@ -61,12 +61,8 @@ func (daemon *Daemon) LogNetworkEvent(nw libnetwork.Network, action string) {
|
| 61 | 61 |
func (daemon *Daemon) LogNetworkEventWithAttributes(nw libnetwork.Network, action string, attributes map[string]string) {
|
| 62 | 62 |
attributes["name"] = nw.Name() |
| 63 | 63 |
attributes["type"] = nw.Type() |
| 64 |
- daemon.logNetworkEventWithID(nw.ID(), action, attributes) |
|
| 65 |
-} |
|
| 66 |
- |
|
| 67 |
-func (daemon *Daemon) logNetworkEventWithID(id, action string, attributes map[string]string) {
|
|
| 68 | 64 |
actor := events.Actor{
|
| 69 |
- ID: id, |
|
| 65 |
+ ID: nw.ID(), |
|
| 70 | 66 |
Attributes: attributes, |
| 71 | 67 |
} |
| 72 | 68 |
daemon.EventsService.Log(action, events.NetworkEventType, actor) |
| ... | ... |
@@ -7,6 +7,8 @@ import ( |
| 7 | 7 |
"strings" |
| 8 | 8 |
|
| 9 | 9 |
"github.com/docker/docker/api/types/network" |
| 10 |
+ derr "github.com/docker/docker/errors" |
|
| 11 |
+ "github.com/docker/docker/runconfig" |
|
| 10 | 12 |
"github.com/docker/libnetwork" |
| 11 | 13 |
) |
| 12 | 14 |
|
| ... | ... |
@@ -114,7 +116,13 @@ func (daemon *Daemon) CreateNetwork(name, driver string, ipam network.IPAM, opti |
| 114 | 114 |
|
| 115 | 115 |
nwOptions = append(nwOptions, libnetwork.NetworkOptionIpam(ipam.Driver, "", v4Conf, v6Conf)) |
| 116 | 116 |
nwOptions = append(nwOptions, libnetwork.NetworkOptionDriverOpts(options)) |
| 117 |
- return c.NewNetwork(driver, name, nwOptions...) |
|
| 117 |
+ n, err := c.NewNetwork(driver, name, nwOptions...) |
|
| 118 |
+ if err != nil {
|
|
| 119 |
+ return nil, err |
|
| 120 |
+ } |
|
| 121 |
+ |
|
| 122 |
+ daemon.LogNetworkEvent(n, "create") |
|
| 123 |
+ return n, nil |
|
| 118 | 124 |
} |
| 119 | 125 |
|
| 120 | 126 |
func getIpamConfig(data []network.IPAMConfig) ([]*libnetwork.IpamConf, []*libnetwork.IpamConf, error) {
|
| ... | ... |
@@ -178,3 +186,21 @@ func (daemon *Daemon) GetNetworkDriverList() map[string]bool {
|
| 178 | 178 |
|
| 179 | 179 |
return pluginList |
| 180 | 180 |
} |
| 181 |
+ |
|
| 182 |
+// DeleteNetwork destroys a network unless it's one of docker's predefined networks. |
|
| 183 |
+func (daemon *Daemon) DeleteNetwork(networkID string) error {
|
|
| 184 |
+ nw, err := daemon.FindNetwork(networkID) |
|
| 185 |
+ if err != nil {
|
|
| 186 |
+ return err |
|
| 187 |
+ } |
|
| 188 |
+ |
|
| 189 |
+ if runconfig.IsPreDefinedNetwork(nw.Name()) {
|
|
| 190 |
+ return derr.ErrorCodeCantDeletePredefinedNetwork.WithArgs(nw.Name()) |
|
| 191 |
+ } |
|
| 192 |
+ |
|
| 193 |
+ if err := nw.Delete(); err != nil {
|
|
| 194 |
+ return err |
|
| 195 |
+ } |
|
| 196 |
+ daemon.LogNetworkEvent(nw, "destroy") |
|
| 197 |
+ return nil |
|
| 198 |
+} |
| ... | ... |
@@ -939,4 +939,13 @@ var ( |
| 939 | 939 |
Description: "There was an error while trying to start a container", |
| 940 | 940 |
HTTPStatusCode: http.StatusInternalServerError, |
| 941 | 941 |
}) |
| 942 |
+ |
|
| 943 |
+ // ErrorCodeCantDeletePredefinedNetwork is generated when one of the predefined networks |
|
| 944 |
+ // is attempted to be deleted. |
|
| 945 |
+ ErrorCodeCantDeletePredefinedNetwork = errcode.Register(errGroup, errcode.ErrorDescriptor{
|
|
| 946 |
+ Value: "CANT_DELETE_PREDEFINED_NETWORK", |
|
| 947 |
+ Message: "%s is a pre-defined network and cannot be removed", |
|
| 948 |
+ Description: "Engine's predefined networks cannot be deleted", |
|
| 949 |
+ HTTPStatusCode: http.StatusForbidden, |
|
| 950 |
+ }) |
|
| 942 | 951 |
) |
| ... | ... |
@@ -177,3 +177,29 @@ func (s *DockerSuite) TestVolumeEvents(c *check.C) {
|
| 177 | 177 |
c.Assert(volumeEvents[2], checker.Equals, "unmount") |
| 178 | 178 |
c.Assert(volumeEvents[3], checker.Equals, "destroy") |
| 179 | 179 |
} |
| 180 |
+ |
|
| 181 |
+func (s *DockerSuite) TestNetworkEvents(c *check.C) {
|
|
| 182 |
+ testRequires(c, DaemonIsLinux) |
|
| 183 |
+ |
|
| 184 |
+ since := daemonTime(c).Unix() |
|
| 185 |
+ |
|
| 186 |
+ // Observe create/connect network actions |
|
| 187 |
+ dockerCmd(c, "network", "create", "test-event-network-local") |
|
| 188 |
+ dockerCmd(c, "run", "--name", "test-network-container", "--net", "test-event-network-local", "-d", "busybox", "true") |
|
| 189 |
+ waitRun("test-network-container")
|
|
| 190 |
+ |
|
| 191 |
+ // Observe disconnect/destroy network actions |
|
| 192 |
+ dockerCmd(c, "rm", "-f", "test-network-container") |
|
| 193 |
+ dockerCmd(c, "network", "rm", "test-event-network-local") |
|
| 194 |
+ |
|
| 195 |
+ out, _ := dockerCmd(c, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
|
|
| 196 |
+ events := strings.Split(strings.TrimSpace(out), "\n") |
|
| 197 |
+ c.Assert(len(events), checker.GreaterThan, 4) |
|
| 198 |
+ |
|
| 199 |
+ netEvents := eventActionsByIDAndType(c, events, "test-event-network-local", "network") |
|
| 200 |
+ c.Assert(netEvents, checker.HasLen, 4) |
|
| 201 |
+ c.Assert(netEvents[0], checker.Equals, "create") |
|
| 202 |
+ c.Assert(netEvents[1], checker.Equals, "connect") |
|
| 203 |
+ c.Assert(netEvents[2], checker.Equals, "disconnect") |
|
| 204 |
+ c.Assert(netEvents[3], checker.Equals, "destroy") |
|
| 205 |
+} |