Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[backport 24.0] daemon: fix under what conditions container's mac-address is applied #46478

Merged
merged 1 commit into from Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 25 additions & 0 deletions daemon/container_operations.go
Expand Up @@ -744,6 +744,12 @@ func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName
return nil
}

if idOrName != container.HostConfig.NetworkMode.NetworkName() {
if err := daemon.normalizeNetMode(container); err != nil {
return err
}
}

var operIPAM bool
if config != nil {
if epConfig, ok := config.EndpointsConfig[n.Name()]; ok {
Expand Down Expand Up @@ -946,6 +952,25 @@ func (daemon *Daemon) tryDetachContainerFromClusterNetwork(network libnetwork.Ne
daemon.LogNetworkEventWithAttributes(network, "disconnect", attributes)
}

// 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(container *container.Container) error {
var err error

Expand Down
4 changes: 2 additions & 2 deletions daemon/network.go
Expand Up @@ -875,8 +875,8 @@ func buildCreateEndpointOptions(c *container.Container, n libnetwork.Network, ep
// 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 n.Name() == c.HostConfig.NetworkMode.NetworkName() ||
(n.Name() == defaultNetName && c.HostConfig.NetworkMode.IsDefault()) {
netMode := c.HostConfig.NetworkMode
if n.Name() == netMode.NetworkName() || n.ID() == netMode.NetworkName() || (n.Name() == defaultNetName && netMode.IsDefault()) {
if c.Config.MacAddress != "" {
mac, err := net.ParseMAC(c.Config.MacAddress)
if err != nil {
Expand Down
26 changes: 26 additions & 0 deletions integration/container/run_linux_test.go
Expand Up @@ -291,3 +291,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 := context.Background()

d := daemon.New(t)
d.StartWithBusybox(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 changes: 16 additions & 0 deletions integration/internal/container/container.go
Expand Up @@ -71,3 +71,19 @@ func Run(ctx context.Context, t *testing.T, client client.APIClient, ops ...func

return id
}

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 changes: 12 additions & 0 deletions integration/internal/container/ops.go
Expand Up @@ -255,3 +255,15 @@ func WithSecurityOpt(opt string) func(*TestContainerConfig) {
c.HostConfig.SecurityOpt = append(c.HostConfig.SecurityOpt, opt)
}
}

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
}
}