Browse Source

Merge pull request #35966 from yongtang/33661-network-alias

 Fix network alias issue with `network connect`
Yong Tang 7 years ago
parent
commit
70a0621f25

+ 5 - 6
api/server/router/network/network_routes.go

@@ -275,12 +275,11 @@ func (n *networkRouter) postNetworkConnect(ctx context.Context, w http.ResponseW
 		return err
 	}
 
-	// Always make sure there is no ambiguity with respect to the network ID/name
-	nw, err := n.backend.FindNetwork(vars["id"])
-	if err != nil {
-		return err
-	}
-	return n.backend.ConnectContainerToNetwork(connect.Container, nw.ID(), connect.EndpointConfig)
+	// Unlike other operations, we does not check ambiguity of the name/ID here.
+	// The reason is that, In case of attachable network in swarm scope, the actual local network
+	// may not be available at the time. At the same time, inside daemon `ConnectContainerToNetwork`
+	// does the ambiguity check anyway. Therefore, passing the name to daemon would be enough.
+	return n.backend.ConnectContainerToNetwork(connect.Container, vars["id"], connect.EndpointConfig)
 }
 
 func (n *networkRouter) postNetworkDisconnect(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {

+ 10 - 4
daemon/container_operations.go

@@ -20,6 +20,7 @@ import (
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/go-connections/nat"
 	"github.com/docker/libnetwork"
+	netconst "github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/options"
 	"github.com/docker/libnetwork/types"
@@ -259,6 +260,13 @@ func (daemon *Daemon) updateNetworkSettings(container *container.Container, n li
 		}
 
 		if sn.Name() == n.Name() {
+			// If the network scope is swarm, then this
+			// is an attachable network, which may not
+			// be locally available previously.
+			// So always update.
+			if n.Info().Scope() == netconst.SwarmScope {
+				continue
+			}
 			// Avoid duplicate config
 			return nil
 		}
@@ -272,10 +280,8 @@ func (daemon *Daemon) updateNetworkSettings(container *container.Container, n li
 		}
 	}
 
-	if _, ok := container.NetworkSettings.Networks[n.Name()]; !ok {
-		container.NetworkSettings.Networks[n.Name()] = &network.EndpointSettings{
-			EndpointSettings: endpointConfig,
-		}
+	container.NetworkSettings.Networks[n.Name()] = &network.EndpointSettings{
+		EndpointSettings: endpointConfig,
 	}
 
 	return nil

+ 86 - 0
integration/service/network_test.go

@@ -0,0 +1,86 @@
+package service
+
+import (
+	"context"
+	"testing"
+
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/api/types/network"
+	"github.com/docker/docker/integration-cli/request"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestDockerNetworkConnectAlias(t *testing.T) {
+	defer setupTest(t)()
+	d := newSwarm(t)
+	defer d.Stop(t)
+	client, err := request.NewClientForHost(d.Sock())
+	require.NoError(t, err)
+	ctx := context.Background()
+
+	name := "test-alias"
+	_, err = client.NetworkCreate(ctx, name, types.NetworkCreate{
+		Driver:     "overlay",
+		Attachable: true,
+	})
+	require.NoError(t, err)
+	_, err = client.ContainerCreate(ctx,
+		&container.Config{
+			Cmd:   []string{"top"},
+			Image: "busybox",
+		},
+		&container.HostConfig{},
+		&network.NetworkingConfig{
+			EndpointsConfig: map[string]*network.EndpointSettings{
+				name: {},
+			},
+		},
+		"ng1",
+	)
+	require.NoError(t, err)
+	err = client.NetworkConnect(ctx, name, "ng1", &network.EndpointSettings{
+		Aliases: []string{
+			"aaa",
+		},
+	})
+	require.NoError(t, err)
+
+	err = client.ContainerStart(ctx, "ng1", types.ContainerStartOptions{})
+	require.NoError(t, err)
+
+	ng1, err := client.ContainerInspect(ctx, "ng1")
+	require.NoError(t, err)
+	assert.Equal(t, len(ng1.NetworkSettings.Networks[name].Aliases), 2)
+	assert.Equal(t, ng1.NetworkSettings.Networks[name].Aliases[0], "aaa")
+
+	_, err = client.ContainerCreate(ctx,
+		&container.Config{
+			Cmd:   []string{"top"},
+			Image: "busybox",
+		},
+		&container.HostConfig{},
+		&network.NetworkingConfig{
+			EndpointsConfig: map[string]*network.EndpointSettings{
+				name: {},
+			},
+		},
+		"ng2",
+	)
+	require.NoError(t, err)
+	err = client.NetworkConnect(ctx, name, "ng2", &network.EndpointSettings{
+		Aliases: []string{
+			"bbb",
+		},
+	})
+	require.NoError(t, err)
+
+	err = client.ContainerStart(ctx, "ng2", types.ContainerStartOptions{})
+	require.NoError(t, err)
+
+	ng2, err := client.ContainerInspect(ctx, "ng2")
+	require.NoError(t, err)
+	assert.Equal(t, len(ng2.NetworkSettings.Networks[name].Aliases), 2)
+	assert.Equal(t, ng2.NetworkSettings.Networks[name].Aliases[0], "bbb")
+}