Skip to content

Commit 8c64b85

Browse files
committed
No inspect 'Config.MacAddress' unless configured.
Do not set 'Config.MacAddress' in inspect output unless the MAC address is configured. Also, make sure it is filled in for a configured address on the default network before the container is started (by translating the network name from 'default' to 'config' so that the address lookup works). Signed-off-by: Rob Murray <[email protected]>
1 parent dae3303 commit 8c64b85

2 files changed

Lines changed: 102 additions & 3 deletions

File tree

daemon/inspect.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ func (daemon *Daemon) ContainerInspectCurrent(ctx context.Context, name string,
7070
if epConf.EndpointSettings != nil {
7171
// We must make a copy of this pointer object otherwise it can race with other operations
7272
apiNetworks[nwName] = epConf.EndpointSettings.Copy()
73-
apiNetworks[nwName].DesiredMacAddress = ""
7473
}
7574
}
7675

@@ -163,8 +162,12 @@ func (daemon *Daemon) getInspectData(daemonCfg *config.Config, container *contai
163162
// unversioned API endpoints.
164163
if container.Config != nil && container.Config.MacAddress == "" { //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.44.
165164
if nwm := hostConfig.NetworkMode; nwm.IsDefault() || nwm.IsBridge() || nwm.IsUserDefined() {
166-
if epConf, ok := container.NetworkSettings.Networks[nwm.NetworkName()]; ok {
167-
container.Config.MacAddress = epConf.MacAddress //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.44.
165+
name := nwm.NetworkName()
166+
if nwm.IsDefault() {
167+
name = daemon.netController.Config().DefaultNetwork
168+
}
169+
if epConf, ok := container.NetworkSettings.Networks[name]; ok {
170+
container.Config.MacAddress = epConf.DesiredMacAddress //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.44.
168171
}
169172
}
170173
}

integration/networking/mac_addr_test.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import (
44
"testing"
55

66
containertypes "github.com/docker/docker/api/types/container"
7+
"github.com/docker/docker/client"
78
"github.com/docker/docker/integration/internal/container"
89
"github.com/docker/docker/integration/internal/network"
910
"github.com/docker/docker/libnetwork/drivers/bridge"
11+
"github.com/docker/docker/testutil"
1012
"github.com/docker/docker/testutil/daemon"
1113
"gotest.tools/v3/assert"
1214
is "gotest.tools/v3/assert/cmp"
@@ -135,3 +137,97 @@ func TestCfgdMACAddrOnRestart(t *testing.T) {
135137
d.Restart(t)
136138
startAndCheck()
137139
}
140+
141+
// Regression test for https://github.com/moby/moby/issues/47228 - check that a
142+
// generated MAC address is not included in the Config section of 'inspect'
143+
// output, but a configured address is.
144+
func TestInspectCfgdMAC(t *testing.T) {
145+
skip.If(t, testEnv.DaemonInfo.OSType == "windows")
146+
147+
ctx := setupTest(t)
148+
149+
d := daemon.New(t)
150+
d.StartWithBusybox(ctx, t)
151+
defer d.Stop(t)
152+
153+
testcases := []struct {
154+
name string
155+
desiredMAC string
156+
netName string
157+
ctrWide bool
158+
}{
159+
{
160+
name: "generated address default bridge",
161+
netName: "bridge",
162+
},
163+
{
164+
name: "configured address default bridge",
165+
desiredMAC: "02:42:ac:11:00:42",
166+
netName: "bridge",
167+
},
168+
{
169+
name: "generated address custom bridge",
170+
netName: "testnet",
171+
},
172+
{
173+
name: "configured address custom bridge",
174+
desiredMAC: "02:42:ac:11:00:42",
175+
netName: "testnet",
176+
},
177+
{
178+
name: "ctr-wide address default bridge",
179+
desiredMAC: "02:42:ac:11:00:42",
180+
netName: "bridge",
181+
ctrWide: true,
182+
},
183+
}
184+
185+
for _, tc := range testcases {
186+
t.Run(tc.name, func(t *testing.T) {
187+
ctx := testutil.StartSpan(ctx, t)
188+
189+
var copts []client.Opt
190+
if tc.ctrWide {
191+
copts = append(copts, client.WithVersion("1.43"))
192+
}
193+
c := d.NewClientT(t, copts...)
194+
defer c.Close()
195+
196+
if tc.netName != "bridge" {
197+
const netName = "inspectcfgmac"
198+
network.CreateNoError(ctx, t, c, netName,
199+
network.WithDriver("bridge"),
200+
network.WithOption(bridge.BridgeName, netName))
201+
defer network.RemoveNoError(ctx, t, c, netName)
202+
}
203+
204+
const ctrName = "ctr"
205+
opts := []func(*container.TestContainerConfig){
206+
container.WithName(ctrName),
207+
container.WithCmd("top"),
208+
container.WithImage("busybox:latest"),
209+
}
210+
// Don't specify the network name for the bridge network, because that
211+
// exercises a different code path (the network name isn't set until the
212+
// container starts, until then it's "default").
213+
if tc.netName != "bridge" {
214+
opts = append(opts, container.WithNetworkMode(tc.netName))
215+
}
216+
if tc.desiredMAC != "" {
217+
if tc.ctrWide {
218+
opts = append(opts, container.WithContainerWideMacAddress(tc.desiredMAC))
219+
} else {
220+
opts = append(opts, container.WithMacAddress(tc.netName, tc.desiredMAC))
221+
}
222+
}
223+
id := container.Create(ctx, t, c, opts...)
224+
defer c.ContainerRemove(ctx, id, containertypes.RemoveOptions{
225+
Force: true,
226+
})
227+
228+
inspect := container.Inspect(ctx, t, c, ctrName)
229+
configMAC := inspect.Config.MacAddress //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.44.
230+
assert.Check(t, is.DeepEqual(configMAC, tc.desiredMAC))
231+
})
232+
}
233+
}

0 commit comments

Comments
 (0)