ソースを参照

Merge pull request #46406 from akerouanton/issue-46404

daemon: fix under what conditions container's mac-address is applied
Sebastiaan van Stijn 1 年間 前
コミット
39b2bf51ca

+ 25 - 0
daemon/container_operations.go

@@ -691,6 +691,12 @@ func (daemon *Daemon) connectToNetwork(cfg *config.Config, container *container.
 	}
 	nwName := n.Name()
 
+	if idOrName != container.HostConfig.NetworkMode.NetworkName() {
+		if err := daemon.normalizeNetMode(container); err != nil {
+			return err
+		}
+	}
+
 	var operIPAM bool
 	if nwCfg != nil {
 		if epConfig, ok := nwCfg.EndpointsConfig[nwName]; ok {
@@ -886,6 +892,25 @@ func (daemon *Daemon) tryDetachContainerFromClusterNetwork(network *libnetwork.N
 	})
 }
 
+// normalizeNetMode checks whether the network mode references a network by a partial ID. In that case, it replaces the
+// partial ID with the full network ID.
+// TODO(aker): transform ID into name when the referenced network is one of the predefined.
+func (daemon *Daemon) normalizeNetMode(container *container.Container) error {
+	if container.HostConfig.NetworkMode.IsUserDefined() {
+		netMode := container.HostConfig.NetworkMode.NetworkName()
+		nw, err := daemon.FindNetwork(netMode)
+		if err != nil {
+			return fmt.Errorf("could not find a network matching network mode %s: %w", netMode, err)
+		}
+
+		if netMode != nw.ID() && netMode != nw.Name() {
+			container.HostConfig.NetworkMode = containertypes.NetworkMode(nw.ID())
+		}
+	}
+
+	return nil
+}
+
 func (daemon *Daemon) initializeNetworking(cfg *config.Config, container *container.Container) error {
 	if container.HostConfig.NetworkMode.IsContainer() {
 		// we need to get the hosts files from the container to join

+ 2 - 1
daemon/network.go

@@ -856,7 +856,8 @@ func buildCreateEndpointOptions(c *container.Container, n *libnetwork.Network, e
 	// to which container was connected to on docker run.
 	// Ideally all these network-specific endpoint configurations must be moved under
 	// container.NetworkSettings.Networks[n.Name()]
-	if nwName == c.HostConfig.NetworkMode.NetworkName() || (nwName == defaultNetName && c.HostConfig.NetworkMode.IsDefault()) {
+	netMode := c.HostConfig.NetworkMode
+	if nwName == netMode.NetworkName() || n.ID() == netMode.NetworkName() || (nwName == defaultNetName && netMode.IsDefault()) {
 		if c.Config.MacAddress != "" {
 			mac, err := net.ParseMAC(c.Config.MacAddress)
 			if err != nil {

+ 26 - 0
integration/container/run_linux_test.go

@@ -276,3 +276,29 @@ func TestRunWithAlternativeContainerdShim(t *testing.T) {
 
 	assert.Equal(t, strings.TrimSpace(b.String()), "Hello, world!")
 }
+
+func TestMacAddressIsAppliedToMainNetworkWithShortID(t *testing.T) {
+	skip.If(t, testEnv.IsRemoteDaemon)
+	skip.If(t, testEnv.DaemonInfo.OSType != "linux")
+
+	ctx := testutil.StartSpan(baseContext, t)
+
+	d := daemon.New(t)
+	d.StartWithBusybox(ctx, t)
+	defer d.Stop(t)
+
+	apiClient := d.NewClientT(t)
+
+	n := net.CreateNoError(ctx, t, apiClient, "testnet", net.WithIPAM("192.168.101.0/24", "192.168.101.1"))
+
+	cid := container.Run(ctx, t, apiClient,
+		container.WithImage("busybox:latest"),
+		container.WithCmd("/bin/sleep", "infinity"),
+		container.WithStopSignal("SIGKILL"),
+		container.WithNetworkMode(n[:10]),
+		container.WithMacAddress("02:42:08:26:a9:55"))
+	defer container.Remove(ctx, t, apiClient, cid, types.ContainerRemoveOptions{Force: true})
+
+	c := container.Inspect(ctx, t, apiClient, cid)
+	assert.Equal(t, c.NetworkSettings.Networks["testnet"].MacAddress, "02:42:08:26:a9:55")
+}

+ 16 - 0
integration/internal/container/container.go

@@ -154,3 +154,19 @@ func demultiplexStreams(ctx context.Context, resp types.HijackedResponse) (strea
 	wg.Wait()
 	return s, err
 }
+
+func Remove(ctx context.Context, t *testing.T, apiClient client.APIClient, container string, options types.ContainerRemoveOptions) {
+	t.Helper()
+
+	err := apiClient.ContainerRemove(ctx, container, options)
+	assert.NilError(t, err)
+}
+
+func Inspect(ctx context.Context, t *testing.T, apiClient client.APIClient, containerRef string) types.ContainerJSON {
+	t.Helper()
+
+	c, err := apiClient.ContainerInspect(ctx, containerRef)
+	assert.NilError(t, err)
+
+	return c
+}

+ 12 - 0
integration/internal/container/ops.go

@@ -280,3 +280,15 @@ func WithPIDMode(mode container.PidMode) func(c *TestContainerConfig) {
 		c.HostConfig.PidMode = mode
 	}
 }
+
+func WithStopSignal(stopSignal string) func(c *TestContainerConfig) {
+	return func(c *TestContainerConfig) {
+		c.Config.StopSignal = stopSignal
+	}
+}
+
+func WithMacAddress(address string) func(c *TestContainerConfig) {
+	return func(c *TestContainerConfig) {
+		c.Config.MacAddress = address
+	}
+}