diff --git a/api/handlers.go b/api/handlers.go index 066eff5b65..8548dcfe90 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -18,6 +18,7 @@ import ( apitypes "github.com/docker/docker/api/types" containertypes "github.com/docker/docker/api/types/container" dockerfilters "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/network" typesversions "github.com/docker/docker/api/types/versions" volumetypes "github.com/docker/docker/api/types/volume" "github.com/docker/docker/pkg/parsers/kernel" @@ -698,6 +699,7 @@ func postContainersCreate(c *context, w http.ResponseWriter, r *http.Request) { httpError(w, err.Error(), http.StatusInternalServerError) return } + containerConfig.NetworkingConfig = stripNodeNamesFromNetworkingConfig(containerConfig.NetworkingConfig, c.cluster.EngineNames()) container, err := c.cluster.CreateContainer(containerConfig, name, authConfig) if err != nil { @@ -1645,3 +1647,26 @@ func (h headerFlusher) WriteHeader(status int) { func postContainersWait(c *context, w http.ResponseWriter, r *http.Request) { proxyContainerAndForceRefresh(c, headerFlusher{w}, r) } + +// stripNodeNamesFromNetworkingConfig goes through a container's +// NetworkingConfig and, if a user specified a Swarm classic-style network +// name in the endpoints config (i.e. /), strips off +// the node name so that the daemon will recognize the network. +func stripNodeNamesFromNetworkingConfig(n network.NetworkingConfig, nodeNames []string) network.NetworkingConfig { + endpointsConfig := map[string]*network.EndpointSettings{} + nodeNamesMap := map[string]struct{}{} + for _, name := range nodeNames { + nodeNamesMap[name] = struct{}{} + } + for networkName, v := range n.EndpointsConfig { + parts := strings.SplitN(networkName, "/", 2) + if len(parts) > 1 { + if _, ok := nodeNamesMap[parts[0]]; ok { + networkName = parts[1] + } + } + endpointsConfig[networkName] = v + } + n.EndpointsConfig = endpointsConfig + return n +} diff --git a/api/handlers_test.go b/api/handlers_test.go new file mode 100644 index 0000000000..d24471a2be --- /dev/null +++ b/api/handlers_test.go @@ -0,0 +1,26 @@ +package api + +import ( + "testing" + + "github.com/docker/docker/api/types/network" + "github.com/stretchr/testify/assert" +) + +func TestStripNodeNamesFromNetworkingConfig(t *testing.T) { + networkingConfig := network.NetworkingConfig{ + EndpointsConfig: map[string]*network.EndpointSettings{ + "testnet1": {}, + "nodename/testnet2": {}, + "nodename/test/net3": {}, + "foo/test/net4": {}, + "nodename/nodename/net5": {}, + }, + } + networkingConfig = stripNodeNamesFromNetworkingConfig(networkingConfig, []string{"nodename"}) + assert.Contains(t, networkingConfig.EndpointsConfig, "testnet1") + assert.Contains(t, networkingConfig.EndpointsConfig, "testnet2") + assert.Contains(t, networkingConfig.EndpointsConfig, "test/net3") + assert.Contains(t, networkingConfig.EndpointsConfig, "foo/test/net4") + assert.Contains(t, networkingConfig.EndpointsConfig, "nodename/net5") +} diff --git a/cluster/cluster.go b/cluster/cluster.go index 09a3909679..b886e29793 100644 --- a/cluster/cluster.go +++ b/cluster/cluster.go @@ -75,6 +75,9 @@ type Cluster interface { // TotalCpus returns the number of CPUs in the cluster. TotalCpus() int64 + // EngineNames returns the names of all the engines in the cluster. + EngineNames() []string + // RegisterEventHandler registers an event handler for cluster-wide events. RegisterEventHandler(h EventHandler) error diff --git a/cluster/swarm/cluster.go b/cluster/swarm/cluster.go index 99867c4dac..1575bff4c3 100644 --- a/cluster/swarm/cluster.go +++ b/cluster/swarm/cluster.go @@ -965,6 +965,15 @@ func (c *Cluster) TotalCpus() int64 { return totalCpus } +// EngineNames returns the names of all the engines in the cluster. +func (c *Cluster) EngineNames() []string { + ret := make([]string, len(c.engines)) + for _, engine := range c.engines { + ret = append(ret, engine.Name) + } + return ret +} + // Info returns some info about the cluster, like nb or containers / images. func (c *Cluster) Info() [][2]string { info := [][2]string{ diff --git a/test/integration/api/network.bats b/test/integration/api/network.bats index cbbf671f1b..1841f86404 100644 --- a/test/integration/api/network.bats +++ b/test/integration/api/network.bats @@ -222,4 +222,6 @@ function teardown() { run docker_swarm network inspect testn [[ "${output}" != *"\"Containers\": {}"* ]] + + docker_swarm run -d --net node-1/testn --network-alias=foobar --name test_container2 busybox sleep 100 }