Signed-off-by: Rob Murray <rob.murray@docker.com>
| ... | ... |
@@ -1218,3 +1218,76 @@ func TestBridgeIPAMStatus(t *testing.T) {
|
| 1218 | 1218 |
}) |
| 1219 | 1219 |
}) |
| 1220 | 1220 |
} |
| 1221 |
+ |
|
| 1222 |
+// TestJoinError checks that if network connection fails late in the process, it's |
|
| 1223 |
+// rolled back properly - the failed connection should not show up in container |
|
| 1224 |
+// or network inspect, and the container should not gain a network interface. |
|
| 1225 |
+func TestJoinError(t *testing.T) {
|
|
| 1226 |
+ ctx := setupTest(t) |
|
| 1227 |
+ d := daemon.New(t) |
|
| 1228 |
+ d.StartWithBusybox(ctx, t) |
|
| 1229 |
+ defer d.Stop(t) |
|
| 1230 |
+ c := d.NewClientT(t) |
|
| 1231 |
+ |
|
| 1232 |
+ const intNet = "intnet" |
|
| 1233 |
+ const gwAddr = "192.168.123.1" |
|
| 1234 |
+ network.CreateNoError(ctx, t, c, intNet, |
|
| 1235 |
+ network.WithInternal(), |
|
| 1236 |
+ network.WithIPAM("192.168.123.0/24", gwAddr),
|
|
| 1237 |
+ ) |
|
| 1238 |
+ defer network.RemoveNoError(ctx, t, c, intNet) |
|
| 1239 |
+ |
|
| 1240 |
+ const extNet = "extnet" |
|
| 1241 |
+ network.CreateNoError(ctx, t, c, extNet) |
|
| 1242 |
+ defer network.RemoveNoError(ctx, t, c, extNet) |
|
| 1243 |
+ |
|
| 1244 |
+ cid := ctr.Run(ctx, t, c, |
|
| 1245 |
+ ctr.WithNetworkMode(intNet), |
|
| 1246 |
+ ctr.WithPrivileged(true), |
|
| 1247 |
+ ) |
|
| 1248 |
+ defer c.ContainerRemove(ctx, cid, client.ContainerRemoveOptions{Force: true})
|
|
| 1249 |
+ |
|
| 1250 |
+ // Add a default route to the container, so that connecting extNet will fail to |
|
| 1251 |
+ // set up its own default route. |
|
| 1252 |
+ res := ctr.ExecT(ctx, t, c, cid, []string{"ip", "route", "add", "default", "via", gwAddr})
|
|
| 1253 |
+ assert.Equal(t, res.ExitCode, 0) |
|
| 1254 |
+ |
|
| 1255 |
+ // Expect an error when connecting extNet. |
|
| 1256 |
+ err := c.NetworkConnect(ctx, extNet, cid, &networktypes.EndpointSettings{})
|
|
| 1257 |
+ assert.Check(t, is.ErrorContains(err, "failed to set gateway: file exists")) |
|
| 1258 |
+ |
|
| 1259 |
+ // Only intNet should show up in container inspect. |
|
| 1260 |
+ ctrInsp := ctr.Inspect(ctx, t, c, cid) |
|
| 1261 |
+ assert.Check(t, is.Len(ctrInsp.NetworkSettings.Networks, 1)) |
|
| 1262 |
+ assert.Check(t, is.Contains(ctrInsp.NetworkSettings.Networks, intNet)) |
|
| 1263 |
+ |
|
| 1264 |
+ // extNet should not report any attached containers |
|
| 1265 |
+ extNetInsp, err := c.NetworkInspect(ctx, extNet, client.NetworkInspectOptions{})
|
|
| 1266 |
+ assert.Check(t, err) |
|
| 1267 |
+ assert.Check(t, is.Len(extNetInsp.Containers, 0)) |
|
| 1268 |
+ |
|
| 1269 |
+ // The container should have an eth0, but no eth1. |
|
| 1270 |
+ res = ctr.ExecT(ctx, t, c, cid, []string{"ip", "link", "show", "eth0"})
|
|
| 1271 |
+ assert.Check(t, is.Equal(res.ExitCode, 0), "container should have an eth0") |
|
| 1272 |
+ res = ctr.ExecT(ctx, t, c, cid, []string{"ip", "link", "show", "eth1"})
|
|
| 1273 |
+ assert.Check(t, is.Contains(res.Stderr(), "can't find device"), "container should not have an eth1") |
|
| 1274 |
+ |
|
| 1275 |
+ // Remove the dodgy route. |
|
| 1276 |
+ res = ctr.ExecT(ctx, t, c, cid, []string{"ip", "route", "del", "default", "via", gwAddr})
|
|
| 1277 |
+ assert.Equal(t, res.ExitCode, 0) |
|
| 1278 |
+ |
|
| 1279 |
+ // Check network connect now succeeds. |
|
| 1280 |
+ err = c.NetworkConnect(ctx, extNet, cid, &networktypes.EndpointSettings{})
|
|
| 1281 |
+ assert.Check(t, err) |
|
| 1282 |
+ ctrInsp = ctr.Inspect(ctx, t, c, cid) |
|
| 1283 |
+ assert.Check(t, is.Len(ctrInsp.NetworkSettings.Networks, 2)) |
|
| 1284 |
+ assert.Check(t, is.Contains(ctrInsp.NetworkSettings.Networks, intNet)) |
|
| 1285 |
+ assert.Check(t, is.Contains(ctrInsp.NetworkSettings.Networks, extNet)) |
|
| 1286 |
+ extNetInsp, err = c.NetworkInspect(ctx, extNet, client.NetworkInspectOptions{})
|
|
| 1287 |
+ assert.Check(t, err) |
|
| 1288 |
+ assert.Check(t, is.Len(extNetInsp.Containers, 1)) |
|
| 1289 |
+ res = ctr.ExecT(ctx, t, c, cid, []string{"ip", "link", "show", "eth0"})
|
|
| 1290 |
+ assert.Check(t, is.Equal(res.ExitCode, 0), "container should have an eth0") |
|
| 1291 |
+ res = ctr.ExecT(ctx, t, c, cid, []string{"ip", "link", "show", "eth1"})
|
|
| 1292 |
+ assert.Check(t, is.Equal(res.ExitCode, 0), "container should have an eth1") |
|
| 1293 |
+} |