Skip to content

Commit a495719

Browse files
committed
fix: display containers belonging to multiple networks in nerdctl network inspect
When a container belongs to multiple networks, running the nerdctl network inspect command on the network to which the container belongs does not display the container in the current implementation. Specifically, it is displayed as follows. ``` $ sudo nerdctl run -d --name net --net=foo --net=bar nginx d88e878f0c60823bd0c361bad250f27b19ad117fb3336fcf18fa26ab1910c367 $ sudo nerdctl network inspect foo | jq .[0].Containers {} $ sudo nerdctl network inspect bar | jq .[0].Containers {} ``` Ideally, running the nerdctl network inspect command on the networks to which the contaienr belongs should display the container name as follows. ``` $ sudo nerdctl network inspect foo | jq .[0].Containers { "d88e878f0c60823bd0c361bad250f27b19ad117fb3336fcf18fa26ab1910c367": { "Name": "net" } } $ sudo nerdctl network inspect bar | jq .[0].Containers { "d88e878f0c60823bd0c361bad250f27b19ad117fb3336fcf18fa26ab1910c367": { "Name": "net" } } ``` Therefore, this behaviour is fixed in this PR. Signed-off-by: Hayato Kiwata <[email protected]>
1 parent 694c405 commit a495719

File tree

2 files changed

+60
-4
lines changed

2 files changed

+60
-4
lines changed

cmd/nerdctl/network/network_inspect_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,39 @@ func TestNetworkInspect(t *testing.T) {
320320
}
321321
},
322322
},
323+
{
324+
Description: "Display containers belonging to multiple networks in the output of nerdctl network inspect",
325+
Setup: func(data test.Data, helpers test.Helpers) {
326+
helpers.Ensure("network", "create", data.Identifier("nginx-network-1"))
327+
helpers.Ensure("network", "create", data.Identifier("nginx-network-2"))
328+
329+
helpers.Ensure("run", "-d", "--name", data.Identifier(), "--network", data.Identifier("nginx-network-1"), "--network", data.Identifier("nginx-network-2"), testutil.NginxAlpineImage)
330+
331+
data.Labels().Set("containerID", strings.Trim(helpers.Capture("inspect", data.Identifier(), "--format", "{{.Id}}"), "\n"))
332+
},
333+
Cleanup: func(data test.Data, helpers test.Helpers) {
334+
helpers.Anyhow("rm", "-f", data.Identifier())
335+
helpers.Anyhow("network", "remove", data.Identifier("nginx-network-1"))
336+
helpers.Anyhow("network", "remove", data.Identifier("nginx-network-2"))
337+
},
338+
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
339+
return helpers.Command("network", "inspect", data.Identifier("nginx-network-1"))
340+
},
341+
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
342+
return &test.Expected{
343+
Output: func(stdout string, info string, t *testing.T) {
344+
var dc []dockercompat.Network
345+
err := json.Unmarshal([]byte(stdout), &dc)
346+
347+
assert.NilError(t, err, "Unable to unmarshal output\n"+info)
348+
assert.Equal(t, 1, len(dc), "Unexpectedly got multiple results\n"+info)
349+
assert.Equal(t, dc[0].Name, data.Identifier("nginx-network-1"))
350+
assert.Equal(t, 1, len(dc[0].Containers), "Expected a single container as per configuration, but got multiple.")
351+
assert.Equal(t, data.Identifier(), dc[0].Containers[data.Labels().Get("containerID")].Name)
352+
},
353+
}
354+
},
355+
},
323356
}
324357

325358
testCase.Run(t)

pkg/cmd/network/inspect.go

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"encoding/json"
2222
"errors"
2323
"fmt"
24+
"slices"
2425

2526
containerd "github.com/containerd/containerd/v2/client"
2627
"github.com/containerd/log"
@@ -58,16 +59,14 @@ func Inspect(ctx context.Context, client *containerd.Client, options types.Netwo
5859
}
5960

6061
network := netList[0]
61-
var filters = []string{fmt.Sprintf("labels.%q==%q", labels.Networks, []string{network.Name})}
6262

63+
var filters = []string{fmt.Sprintf("labels.%q~=%q", labels.Networks, network.Name)}
6364
filteredContainers, err := client.Containers(ctx, filters...)
64-
6565
if err != nil {
6666
return err
6767
}
6868

6969
var containers []*native.Container
70-
7170
for _, container := range filteredContainers {
7271
nativeContainer, err := containerinspector.Inspect(ctx, container)
7372
if err != nil {
@@ -76,7 +75,14 @@ func Inspect(ctx context.Context, client *containerd.Client, options types.Netwo
7675
if nativeContainer.Process == nil || nativeContainer.Process.Status.Status != containerd.Running {
7776
continue
7877
}
79-
containers = append(containers, nativeContainer)
78+
79+
isNetworkMember, err := isContainerInNetwork(ctx, container, network.Name)
80+
if err != nil {
81+
return err
82+
}
83+
if isNetworkMember {
84+
containers = append(containers, nativeContainer)
85+
}
8086
}
8187

8288
r := &native.Network{
@@ -113,3 +119,20 @@ func Inspect(ctx context.Context, client *containerd.Client, options types.Netwo
113119

114120
return err
115121
}
122+
123+
func isContainerInNetwork(ctx context.Context, container containerd.Container, networkName string) (bool, error) {
124+
info, err := container.Info(ctx)
125+
if err != nil {
126+
return false, err
127+
}
128+
networkLabels, ok := info.Labels[labels.Networks]
129+
if !ok {
130+
return false, nil
131+
}
132+
133+
var containerNetworks []string
134+
if err := json.Unmarshal([]byte(networkLabels), &containerNetworks); err != nil {
135+
return false, err
136+
}
137+
return slices.Contains(containerNetworks, networkName), nil
138+
}

0 commit comments

Comments
 (0)