Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
| ... | ... |
@@ -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{
|