Skip to content

Commit 1eab5e6

Browse files
authored
Merge pull request #4953 from immanuwell/fix-network-inspect-pseudo-networks
fix(network): allow inspecting pseudo networks
2 parents 43225a4 + 5a04185 commit 1eab5e6

4 files changed

Lines changed: 75 additions & 6 deletions

File tree

cmd/nerdctl/network/network_inspect_test.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ func TestNetworkInspectBasic(t *testing.T) {
6262
},
6363
{
6464
Description: "none",
65-
Require: nerdtest.NerdctlNeedsFixing("no issue opened"),
6665
Command: test.Command("network", "inspect", "none"),
6766
Expected: test.Expects(0, nil, func(stdout string, t tig.T) {
6867
var dc []dockercompat.Network
@@ -74,7 +73,6 @@ func TestNetworkInspectBasic(t *testing.T) {
7473
},
7574
{
7675
Description: "host",
77-
Require: nerdtest.NerdctlNeedsFixing("no issue opened"),
7876
Command: test.Command("network", "inspect", "host"),
7977
Expected: test.Expects(0, nil, func(stdout string, t tig.T) {
8078
var dc []dockercompat.Network

pkg/netutil/cni_plugin.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ type CNIPlugin interface {
2020
GetPluginType() string
2121
}
2222

23+
type pseudoNetworkPlugin struct {
24+
PluginType string `json:"type"`
25+
}
26+
27+
func (p *pseudoNetworkPlugin) GetPluginType() string {
28+
return p.PluginType
29+
}
30+
2331
type IPAMRange struct {
2432
Subnet string `json:"subnet"`
2533
RangeStart string `json:"rangeStart,omitempty"`

pkg/netutil/netutil.go

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,17 @@ func (e *CNIEnv) ListNetworksMatch(reqs []string, allowPseudoNetwork bool) (list
6060

6161
list = make(map[string][]*NetworkConfig)
6262
for _, req := range reqs {
63-
if !allowPseudoNetwork && (req == "host" || req == "none") {
64-
errs = append(errs, fmt.Errorf("pseudo network not allowed: %s", req))
63+
if req == "host" || req == "none" {
64+
if !allowPseudoNetwork {
65+
errs = append(errs, fmt.Errorf("pseudo network not allowed: %s", req))
66+
continue
67+
}
68+
cfg, err := newPseudoNetworkConfig(req)
69+
if err != nil {
70+
errs = append(errs, err)
71+
continue
72+
}
73+
list[req] = []*NetworkConfig{cfg}
6574
continue
6675
}
6776

@@ -88,6 +97,30 @@ func (e *CNIEnv) ListNetworksMatch(reqs []string, allowPseudoNetwork bool) (list
8897
return list, errs
8998
}
9099

100+
func newPseudoNetworkConfig(name string) (*NetworkConfig, error) {
101+
confJSON, err := json.Marshal(&cniNetworkConfig{
102+
CNIVersion: "1.0.0",
103+
Name: name,
104+
// Pseudo networks are not backed by real CNI config files. We still need a
105+
// parseable config object so network inspect can render them consistently.
106+
Plugins: []CNIPlugin{
107+
&pseudoNetworkPlugin{PluginType: "nerdctl-pseudo"},
108+
},
109+
})
110+
if err != nil {
111+
return nil, err
112+
}
113+
114+
confList, err := libcni.ConfListFromBytes(confJSON)
115+
if err != nil {
116+
return nil, err
117+
}
118+
119+
return &NetworkConfig{
120+
NetworkConfigList: confList,
121+
}, nil
122+
}
123+
91124
func UsedNetworks(ctx context.Context, client *containerd.Client) (map[string][]string, error) {
92125
nsService := client.NamespaceService()
93126
nsList, err := nsService.List(ctx)
@@ -288,8 +321,8 @@ type NetworkConfig struct {
288321
type cniNetworkConfig struct {
289322
CNIVersion string `json:"cniVersion"`
290323
Name string `json:"name"`
291-
ID string `json:"nerdctlID"`
292-
Labels map[string]string `json:"nerdctlLabels"`
324+
ID string `json:"nerdctlID,omitempty"`
325+
Labels map[string]string `json:"nerdctlLabels,omitempty"`
293326
Plugins []CNIPlugin `json:"plugins"`
294327
}
295328

pkg/netutil/netutil_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,3 +379,33 @@ func TestFSExistsPropagatesStatError(t *testing.T) {
379379
assert.Assert(t, !exists)
380380
assert.Assert(t, err != nil)
381381
}
382+
383+
func TestListNetworksMatchIncludesPseudoNetworks(t *testing.T) {
384+
cniConfTestDir := t.TempDir()
385+
cniEnv := CNIEnv{
386+
Path: t.TempDir(),
387+
NetconfPath: cniConfTestDir,
388+
}
389+
390+
values := map[string]string{
391+
"network_name": "regular-network",
392+
"subnet": "10.7.1.0/24",
393+
"gateway": "10.7.1.1",
394+
}
395+
tpl, err := template.New("test").Parse(preExistingNetworkConfigTemplate)
396+
assert.NilError(t, err)
397+
buf := &bytes.Buffer{}
398+
assert.NilError(t, tpl.ExecuteTemplate(buf, "test", values))
399+
400+
testConfFile := filepath.Join(cniConfTestDir, fmt.Sprintf("%s.conf", testutil.Identifier(t)))
401+
assert.NilError(t, filesystem.WriteFile(testConfFile, buf.Bytes(), 0600))
402+
403+
matches, errs := cniEnv.ListNetworksMatch([]string{"host", "none", "regular-network"}, true)
404+
assert.Assert(t, len(errs) == 0)
405+
assert.Equal(t, len(matches["host"]), 1)
406+
assert.Equal(t, matches["host"][0].Name, "host")
407+
assert.Equal(t, len(matches["none"]), 1)
408+
assert.Equal(t, matches["none"][0].Name, "none")
409+
assert.Equal(t, len(matches["regular-network"]), 1)
410+
assert.Equal(t, matches["regular-network"][0].Name, "regular-network")
411+
}

0 commit comments

Comments
 (0)