Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Yong Tang authored on 2017/11/01 05:05:24... | ... |
@@ -530,7 +530,7 @@ func (n *networkRouter) postNetworksPrune(ctx context.Context, w http.ResponseWr |
530 | 530 |
} |
531 | 531 |
|
532 | 532 |
// findUniqueNetwork will search network across different scopes (both local and swarm). |
533 |
-// NOTE: This findUniqueNetwork is differnt from FindUniqueNetwork from the daemon. |
|
533 |
+// NOTE: This findUniqueNetwork is different from FindUniqueNetwork in the daemon. |
|
534 | 534 |
// In case multiple networks have duplicate names, return error. |
535 | 535 |
// First find based on full ID, return immediately once one is found. |
536 | 536 |
// If a network appears both in swarm and local, assume it is in local first |
... | ... |
@@ -547,7 +547,7 @@ func (n *networkRouter) findUniqueNetwork(term string) (types.NetworkResource, e |
547 | 547 |
return *n.buildDetailedNetworkResources(network, false), nil |
548 | 548 |
|
549 | 549 |
} |
550 |
- if network.Name() == term { |
|
550 |
+ if network.Name() == term && !network.Info().Ingress() { |
|
551 | 551 |
// No need to check the ID collision here as we are still in |
552 | 552 |
// local scope and the network ID is unique in this scope. |
553 | 553 |
listByFullName[network.ID()] = *n.buildDetailedNetworkResources(network, false) |
... | ... |
@@ -170,7 +170,7 @@ func (daemon *Daemon) initializeNetworkingPaths(container *container.Container, |
170 | 170 |
|
171 | 171 |
if nc.NetworkSettings != nil { |
172 | 172 |
for n := range nc.NetworkSettings.Networks { |
173 |
- sn, err := daemon.FindNetwork(n) |
|
173 |
+ sn, err := daemon.FindUniqueNetwork(n) |
|
174 | 174 |
if err != nil { |
175 | 175 |
continue |
176 | 176 |
} |
... | ... |
@@ -317,7 +317,7 @@ func TestValidateContainerIsolation(t *testing.T) { |
317 | 317 |
|
318 | 318 |
func TestFindNetworkErrorType(t *testing.T) { |
319 | 319 |
d := Daemon{} |
320 |
- _, err := d.FindNetwork("fakeNet") |
|
320 |
+ _, err := d.FindUniqueNetwork("fakeNet") |
|
321 | 321 |
_, ok := errors.Cause(err).(libnetwork.ErrNoSuchNetwork) |
322 | 322 |
if !errdefs.IsNotFound(err) || !ok { |
323 | 323 |
assert.Fail(t, "The FindNetwork method MUST always return an error that implements the NotFound interface and is ErrNoSuchNetwork") |
... | ... |
@@ -226,20 +226,3 @@ func translateContainerdStartErr(cmd string, setExitCode func(int), err error) e |
226 | 226 |
// TODO: it would be nice to get some better errors from containerd so we can return better errors here |
227 | 227 |
return retErr |
228 | 228 |
} |
229 |
- |
|
230 |
-// TODO: cpuguy83 take care of it once the new library is ready |
|
231 |
-type errNotFound struct{ error } |
|
232 |
- |
|
233 |
-func (errNotFound) NotFound() {} |
|
234 |
- |
|
235 |
-func (e errNotFound) Cause() error { |
|
236 |
- return e.error |
|
237 |
-} |
|
238 |
- |
|
239 |
-// notFound is a helper to create an error of the class with the same name from any error type |
|
240 |
-func notFound(err error) error { |
|
241 |
- if err == nil { |
|
242 |
- return nil |
|
243 |
- } |
|
244 |
- return errNotFound{err} |
|
245 |
-} |
... | ... |
@@ -61,11 +61,6 @@ func (daemon *Daemon) FindUniqueNetwork(term string) (libnetwork.Network, error) |
61 | 61 |
return nil, libnetwork.ErrNoSuchNetwork(term) |
62 | 62 |
} |
63 | 63 |
|
64 |
-func isNoSuchNetworkError(err error) bool { |
|
65 |
- _, ok := err.(libnetwork.ErrNoSuchNetwork) |
|
66 |
- return ok |
|
67 |
-} |
|
68 |
- |
|
69 | 64 |
// GetNetworkByID function returns a network whose ID matches the given ID. |
70 | 65 |
// It fails with an error if no matching network is found. |
71 | 66 |
func (daemon *Daemon) GetNetworkByID(id string) (libnetwork.Network, error) { |
... | ... |
@@ -109,7 +104,11 @@ func (daemon *Daemon) GetNetworksByIDPrefix(partialID string) []libnetwork.Netwo |
109 | 109 |
|
110 | 110 |
// getAllNetworks returns a list containing all networks |
111 | 111 |
func (daemon *Daemon) getAllNetworks() []libnetwork.Network { |
112 |
- return daemon.netController.Networks() |
|
112 |
+ c := daemon.netController |
|
113 |
+ if c == nil { |
|
114 |
+ return nil |
|
115 |
+ } |
|
116 |
+ return c.Networks() |
|
113 | 117 |
} |
114 | 118 |
|
115 | 119 |
type ingressJob struct { |
... | ... |
@@ -159,7 +159,7 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) { |
159 | 159 |
gwHNSID := "" |
160 | 160 |
if c.NetworkSettings != nil { |
161 | 161 |
for n := range c.NetworkSettings.Networks { |
162 |
- sn, err := daemon.FindNetwork(n) |
|
162 |
+ sn, err := daemon.FindUniqueNetwork(n) |
|
163 | 163 |
if err != nil { |
164 | 164 |
continue |
165 | 165 |
} |
... | ... |
@@ -2137,76 +2137,3 @@ func (s *DockerSwarmSuite) TestSwarmClusterEventsConfig(c *check.C) { |
2137 | 2137 |
// filtered by config |
2138 | 2138 |
waitForEvent(c, d, t1, "-f type=config", "config remove "+id, defaultRetryCount) |
2139 | 2139 |
} |
2140 |
- |
|
2141 |
-func (s *DockerSwarmSuite) TestServiceCreateWithDuplicateNetworkNames(c *check.C) { |
|
2142 |
- d := s.AddDaemon(c, true, true) |
|
2143 |
- |
|
2144 |
- name := "foo" |
|
2145 |
- networkCreateRequest := types.NetworkCreateRequest{ |
|
2146 |
- Name: name, |
|
2147 |
- NetworkCreate: types.NetworkCreate{ |
|
2148 |
- CheckDuplicate: false, |
|
2149 |
- Driver: "bridge", |
|
2150 |
- }, |
|
2151 |
- } |
|
2152 |
- |
|
2153 |
- // Create networks with the same name, 2 in local scope and 1 in swarm scope |
|
2154 |
- var n1 types.NetworkCreateResponse |
|
2155 |
- status, body, err := d.SockRequest("POST", "/networks/create", networkCreateRequest) |
|
2156 |
- c.Assert(err, checker.IsNil, check.Commentf(string(body))) |
|
2157 |
- c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(body))) |
|
2158 |
- c.Assert(json.Unmarshal(body, &n1), checker.IsNil) |
|
2159 |
- |
|
2160 |
- var n2 types.NetworkCreateResponse |
|
2161 |
- status, body, err = d.SockRequest("POST", "/networks/create", networkCreateRequest) |
|
2162 |
- c.Assert(err, checker.IsNil, check.Commentf(string(body))) |
|
2163 |
- c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(body))) |
|
2164 |
- c.Assert(json.Unmarshal(body, &n2), checker.IsNil) |
|
2165 |
- |
|
2166 |
- var n3 types.NetworkCreateResponse |
|
2167 |
- // Dupliates with name but with different driver |
|
2168 |
- networkCreateRequest.NetworkCreate.Driver = "overlay" |
|
2169 |
- status, body, err = d.SockRequest("POST", "/networks/create", networkCreateRequest) |
|
2170 |
- c.Assert(err, checker.IsNil, check.Commentf(string(body))) |
|
2171 |
- c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(body))) |
|
2172 |
- c.Assert(json.Unmarshal(body, &n3), checker.IsNil) |
|
2173 |
- |
|
2174 |
- // Create Service with the same name |
|
2175 |
- d.CreateService(c, simpleTestService, func(s *swarm.Service) { |
|
2176 |
- s.Spec.Name = "top" |
|
2177 |
- s.Spec.TaskTemplate.Networks = []swarm.NetworkAttachmentConfig{ |
|
2178 |
- {Target: name}, |
|
2179 |
- } |
|
2180 |
- }) |
|
2181 |
- |
|
2182 |
- // make sure task has been deployed. |
|
2183 |
- waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1) |
|
2184 |
- |
|
2185 |
- result := icmd.RunCmd(d.Command("ps", "-a", "-q")) |
|
2186 |
- result.Assert(c, icmd.Success) |
|
2187 |
- containers := strings.Split(strings.TrimSpace(result.Stdout()), "\n") |
|
2188 |
- c.Assert(len(containers), checker.Equals, 1) |
|
2189 |
- |
|
2190 |
- result = icmd.RunCmd(d.Command("inspect", "--format", `{{.NetworkSettings.Networks.foo.NetworkID}}`, containers[0])) |
|
2191 |
- result.Assert(c, icmd.Success) |
|
2192 |
- c.Assert(strings.TrimSpace(result.Stdout()), checker.Equals, n3.ID) |
|
2193 |
- |
|
2194 |
- // Remove Service |
|
2195 |
- result = icmd.RunCmd(d.Command("service", "rm", "top")) |
|
2196 |
- result.Assert(c, icmd.Success) |
|
2197 |
- |
|
2198 |
- // make sure task has been destroyed. |
|
2199 |
- waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 0) |
|
2200 |
- |
|
2201 |
- result = icmd.RunCmd(d.Command("network", "rm", n1.ID)) |
|
2202 |
- result.Assert(c, icmd.Success) |
|
2203 |
- c.Assert(strings.TrimSpace(result.Stdout()), checker.Equals, n1.ID) |
|
2204 |
- |
|
2205 |
- result = icmd.RunCmd(d.Command("network", "rm", n2.ID)) |
|
2206 |
- result.Assert(c, icmd.Success) |
|
2207 |
- c.Assert(strings.TrimSpace(result.Stdout()), checker.Equals, n2.ID) |
|
2208 |
- |
|
2209 |
- result = icmd.RunCmd(d.Command("network", "rm", n3.ID)) |
|
2210 |
- result.Assert(c, icmd.Success) |
|
2211 |
- c.Assert(strings.TrimSpace(result.Stdout()), checker.Equals, n3.ID) |
|
2212 |
-} |
... | ... |
@@ -11,6 +11,7 @@ import ( |
11 | 11 |
"github.com/docker/docker/client" |
12 | 12 |
"github.com/docker/docker/integration-cli/request" |
13 | 13 |
"github.com/gotestyourself/gotestyourself/poll" |
14 |
+ "github.com/stretchr/testify/assert" |
|
14 | 15 |
"github.com/stretchr/testify/require" |
15 | 16 |
"golang.org/x/net/context" |
16 | 17 |
) |
... | ... |
@@ -80,6 +81,68 @@ func TestCreateServiceMultipleTimes(t *testing.T) { |
80 | 80 |
poll.WaitOn(t, networkIsRemoved(client, overlayID), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second)) |
81 | 81 |
} |
82 | 82 |
|
83 |
+func TestCreateWithDuplicateNetworkNames(t *testing.T) { |
|
84 |
+ defer setupTest(t)() |
|
85 |
+ d := newSwarm(t) |
|
86 |
+ defer d.Stop(t) |
|
87 |
+ client, err := request.NewClientForHost(d.Sock()) |
|
88 |
+ require.NoError(t, err) |
|
89 |
+ |
|
90 |
+ name := "foo" |
|
91 |
+ networkCreate := types.NetworkCreate{ |
|
92 |
+ CheckDuplicate: false, |
|
93 |
+ Driver: "bridge", |
|
94 |
+ } |
|
95 |
+ |
|
96 |
+ n1, err := client.NetworkCreate(context.Background(), name, networkCreate) |
|
97 |
+ require.NoError(t, err) |
|
98 |
+ |
|
99 |
+ n2, err := client.NetworkCreate(context.Background(), name, networkCreate) |
|
100 |
+ require.NoError(t, err) |
|
101 |
+ |
|
102 |
+ // Dupliates with name but with different driver |
|
103 |
+ networkCreate.Driver = "overlay" |
|
104 |
+ n3, err := client.NetworkCreate(context.Background(), name, networkCreate) |
|
105 |
+ require.NoError(t, err) |
|
106 |
+ |
|
107 |
+ // Create Service with the same name |
|
108 |
+ var instances uint64 = 1 |
|
109 |
+ serviceSpec := swarmServiceSpec("top", instances) |
|
110 |
+ |
|
111 |
+ serviceSpec.TaskTemplate.Networks = append(serviceSpec.TaskTemplate.Networks, swarm.NetworkAttachmentConfig{Target: name}) |
|
112 |
+ |
|
113 |
+ service, err := client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{}) |
|
114 |
+ require.NoError(t, err) |
|
115 |
+ |
|
116 |
+ poll.WaitOn(t, serviceRunningTasksCount(client, service.ID, instances)) |
|
117 |
+ |
|
118 |
+ resp, _, err := client.ServiceInspectWithRaw(context.Background(), service.ID, types.ServiceInspectOptions{}) |
|
119 |
+ require.NoError(t, err) |
|
120 |
+ assert.Equal(t, n3.ID, resp.Spec.TaskTemplate.Networks[0].Target) |
|
121 |
+ |
|
122 |
+ // Remove Service |
|
123 |
+ err = client.ServiceRemove(context.Background(), service.ID) |
|
124 |
+ require.NoError(t, err) |
|
125 |
+ |
|
126 |
+ // Make sure task has been destroyed. |
|
127 |
+ poll.WaitOn(t, serviceIsRemoved(client, service.ID)) |
|
128 |
+ |
|
129 |
+ // Remove networks |
|
130 |
+ err = client.NetworkRemove(context.Background(), n3.ID) |
|
131 |
+ require.NoError(t, err) |
|
132 |
+ |
|
133 |
+ err = client.NetworkRemove(context.Background(), n2.ID) |
|
134 |
+ require.NoError(t, err) |
|
135 |
+ |
|
136 |
+ err = client.NetworkRemove(context.Background(), n1.ID) |
|
137 |
+ require.NoError(t, err) |
|
138 |
+ |
|
139 |
+ // Make sure networks have been destroyed. |
|
140 |
+ poll.WaitOn(t, networkIsRemoved(client, n3.ID), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second)) |
|
141 |
+ poll.WaitOn(t, networkIsRemoved(client, n2.ID), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second)) |
|
142 |
+ poll.WaitOn(t, networkIsRemoved(client, n1.ID), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second)) |
|
143 |
+} |
|
144 |
+ |
|
83 | 145 |
func swarmServiceSpec(name string, replicas uint64) swarm.ServiceSpec { |
84 | 146 |
return swarm.ServiceSpec{ |
85 | 147 |
Annotations: swarm.Annotations{ |