Skip to content

Commit 4f696e7

Browse files
Merge pull request #284 from arkadeepsen/bump-cni-version-4.21
[release-4.21] OCPBUGS-82064: Bump CNI version to 1.1.0
2 parents 93556f9 + d87161a commit 4f696e7

10 files changed

Lines changed: 531 additions & 39 deletions

File tree

cmd/thin_entrypoint/main.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"time"
3030

3131
"github.com/containernetworking/cni/libcni"
32+
cniversion "github.com/containernetworking/cni/pkg/version"
3233
"github.com/spf13/pflag"
3334

3435
"gopkg.in/k8snetworkplumbingwg/multus-cni.v4/pkg/cmdutils"
@@ -497,14 +498,14 @@ func (o *Options) createMultusConfig(prevMasterConfigFileHash []byte) (string, [
497498
return "", nil, fmt.Errorf("cannot create multus cni temp file: %v", err)
498499
}
499500

500-
// use conflist template if cniVersionConfig == "1.0.0"
501+
// use conflist template if cniVersionConfig >= "1.0.0"
501502
multusConfFilePath := fmt.Sprintf("%s/00-multus.conf", o.CNIConfDir)
502503
templateMultusConfig, err := template.New("multusCNIConfig").Parse(multusConfTemplate)
503504
if err != nil {
504505
return "", nil, fmt.Errorf("template parse error: %v", err)
505506
}
506507

507-
if o.CNIVersion == "1.0.0" { //Check 1.0.0 or above!
508+
if gt, err := cniversion.GreaterThanOrEqualTo(o.CNIVersion, "1.0.0"); err == nil && gt {
508509
multusConfFilePath = fmt.Sprintf("%s/00-multus.conflist", o.CNIConfDir)
509510
templateMultusConfig, err = template.New("multusCNIConfig").Parse(multusConflistTemplate)
510511
if err != nil {

cmd/thin_entrypoint/main_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,56 @@ var _ = Describe("thin entrypoint testing", func() {
318318
Expect(os.RemoveAll(tmpDir)).To(Succeed())
319319
})
320320

321+
It("Run createMultusConfig(), default, conflist for cniVersion 1.1.0", func() {
322+
// create directory and files
323+
tmpDir, err := os.MkdirTemp("", "multus_thin_entrypoint_tmp")
324+
Expect(err).NotTo(HaveOccurred())
325+
326+
multusAutoConfigDir := fmt.Sprintf("%s/auto_conf", tmpDir)
327+
cniConfDir := fmt.Sprintf("%s/cni_conf", tmpDir)
328+
329+
Expect(os.Mkdir(multusAutoConfigDir, 0755)).To(Succeed())
330+
Expect(os.Mkdir(cniConfDir, 0755)).To(Succeed())
331+
332+
// create master CNI config
333+
masterCNIConfig := `
334+
{
335+
"cniVersion": "1.1.0",
336+
"name": "test1",
337+
"type": "cnitesttype"
338+
}`
339+
Expect(os.WriteFile(fmt.Sprintf("%s/10-testcni.conf", multusAutoConfigDir), []byte(masterCNIConfig), 0755)).To(Succeed())
340+
341+
masterConfigPath, masterConfigHash, err := (&Options{
342+
MultusAutoconfigDir: multusAutoConfigDir,
343+
CNIConfDir: cniConfDir,
344+
MultusKubeConfigFileHost: "/etc/foobar_kubeconfig",
345+
}).createMultusConfig(nil)
346+
Expect(err).NotTo(HaveOccurred())
347+
348+
Expect(masterConfigPath).NotTo(Equal(""))
349+
Expect(masterConfigHash).NotTo(Equal(""))
350+
351+
expectedResult :=
352+
`{
353+
"cniVersion": "1.1.0",
354+
"name": "multus-cni-network",
355+
"plugins": [ {
356+
"type": "multus",
357+
"logToStderr": false,
358+
"kubeconfig": "/etc/foobar_kubeconfig",
359+
"delegates": [
360+
{"cniVersion":"1.1.0","name":"test1","type":"cnitesttype"}
361+
]
362+
}]
363+
}
364+
`
365+
conf, err := os.ReadFile(fmt.Sprintf("%s/00-multus.conflist", cniConfDir))
366+
Expect(string(conf)).To(Equal(expectedResult))
367+
368+
Expect(os.RemoveAll(tmpDir)).To(Succeed())
369+
})
370+
321371
It("Run createMultusConfig(), capabilities, conflist", func() {
322372
// create directory and files
323373
tmpDir, err := os.MkdirTemp("", "multus_thin_entrypoint_tmp")

pkg/multus/multus.go

Lines changed: 144 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package multus
1818
import (
1919
"context"
2020
"encoding/json"
21+
stderrors "errors"
2122
"fmt"
2223
"net"
2324
"os"
@@ -30,6 +31,7 @@ import (
3031
"github.com/containernetworking/cni/pkg/skel"
3132
cnitypes "github.com/containernetworking/cni/pkg/types"
3233
cni100 "github.com/containernetworking/cni/pkg/types/100"
34+
cniversion "github.com/containernetworking/cni/pkg/version"
3335
"github.com/containernetworking/plugins/pkg/ns"
3436
nettypes "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
3537
nadutils "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils"
@@ -258,6 +260,42 @@ func confDel(rt *libcni.RuntimeConf, rawNetconf []byte, multusNetconf *types.Net
258260
return err
259261
}
260262

263+
func confStatus(rt *libcni.RuntimeConf, rawNetconf []byte, multusNetconf *types.NetConf, exec invoke.Exec) error {
264+
logging.Debugf("confStatus: %v, %s", rt, string(rawNetconf))
265+
266+
binDirs := filepath.SplitList(os.Getenv("CNI_PATH"))
267+
binDirs = append([]string{multusNetconf.BinDir}, binDirs...)
268+
cniNet := libcni.NewCNIConfigWithCacheDir(binDirs, multusNetconf.CNIDir, exec)
269+
270+
conf, err := libcni.ConfFromBytes(rawNetconf)
271+
if err != nil {
272+
return logging.Errorf("error in converting the raw bytes to conf: %v", err)
273+
}
274+
275+
if gt, _ := cniversion.GreaterThanOrEqualTo(conf.Network.CNIVersion, "1.1.0"); !gt {
276+
logging.Debugf("confStatus: skipping STATUS for network %q type %q cniVersion %q (< 1.1.0)",
277+
conf.Network.Name, conf.Network.Type, conf.Network.CNIVersion)
278+
return nil
279+
}
280+
281+
confList := &libcni.NetworkConfigList{
282+
Name: conf.Network.Name,
283+
CNIVersion: conf.Network.CNIVersion,
284+
Plugins: []*libcni.PluginConfig{conf},
285+
}
286+
287+
err = cniNet.GetStatusNetworkList(context.Background(), confList)
288+
if err != nil {
289+
var cniErr *cnitypes.Error
290+
if stderrors.As(err, &cniErr) {
291+
return err
292+
}
293+
return logging.Errorf("error in getting result from StatusNetworkList: %v", err)
294+
}
295+
296+
return err
297+
}
298+
261299
func conflistAdd(rt *libcni.RuntimeConf, rawnetconflist []byte, cniConfList *libcni.NetworkConfigList, multusNetconf *types.NetConf, exec invoke.Exec) (cnitypes.Result, error) {
262300
logging.Debugf("conflistAdd: %v, %s", rt, string(rawnetconflist))
263301
// In part, adapted from K8s pkg/kubelet/dockershim/network/cni/cni.go
@@ -327,6 +365,34 @@ func conflistDel(rt *libcni.RuntimeConf, rawnetconflist []byte, multusNetconf *t
327365
return err
328366
}
329367

368+
func conflistStatus(rt *libcni.RuntimeConf, rawnetconflist []byte, multusNetconf *types.NetConf, exec invoke.Exec) error {
369+
logging.Debugf("conflistStatus: %v, %s", rt, string(rawnetconflist))
370+
371+
binDirs := filepath.SplitList(os.Getenv("CNI_PATH"))
372+
binDirs = append([]string{multusNetconf.BinDir}, binDirs...)
373+
cniNet := libcni.NewCNIConfigWithCacheDir(binDirs, multusNetconf.CNIDir, exec)
374+
375+
confList, err := libcni.ConfListFromBytes(rawnetconflist)
376+
if err != nil {
377+
return logging.Errorf("conflistStatus: error converting the raw bytes into a conflist: %v", err)
378+
}
379+
if gt, _ := cniversion.GreaterThanOrEqualTo(confList.CNIVersion, "1.1.0"); !gt {
380+
logging.Debugf("conflistStatus: skipping STATUS for network list %q cniVersion %q (< 1.1.0)", confList.Name, confList.CNIVersion)
381+
return nil
382+
}
383+
384+
err = cniNet.GetStatusNetworkList(context.Background(), confList)
385+
if err != nil {
386+
var cniErr *cnitypes.Error
387+
if stderrors.As(err, &cniErr) {
388+
return err
389+
}
390+
return logging.Errorf("conflistStatus: error in getting result from StatusNetworkList: %v", err)
391+
}
392+
393+
return err
394+
}
395+
330396
// DelegateAdd ...
331397
func DelegateAdd(exec invoke.Exec, kubeClient *k8s.ClientInfo, pod *v1.Pod, delegate *types.DelegateNetConf, rt *libcni.RuntimeConf, multusNetconf *types.NetConf) (cnitypes.Result, error) {
332398
logging.Debugf("DelegateAdd: %v, %v, %v", exec, delegate, rt)
@@ -456,6 +522,46 @@ func DelegateCheck(exec invoke.Exec, delegateConf *types.DelegateNetConf, rt *li
456522
return err
457523
}
458524

525+
// DelegateStatus ...
526+
func DelegateStatus(exec invoke.Exec, delegateConf *types.DelegateNetConf, rt *libcni.RuntimeConf, multusNetconf *types.NetConf) error {
527+
logging.Debugf("DelegateStatus: %v, %v, %v", exec, delegateConf, rt)
528+
529+
isConfList := delegateConf.ConfListPlugin
530+
if !isConfList && delegateConf.Conf.Type == "" && delegateConf.ConfList.Name != "" {
531+
isConfList = true
532+
}
533+
534+
if logging.GetLoggingLevel() >= logging.VerboseLevel {
535+
var cniConfName string
536+
if isConfList {
537+
cniConfName = delegateConf.ConfList.Name
538+
} else {
539+
cniConfName = delegateConf.Conf.Name
540+
}
541+
logging.Verbosef("Status: %s:%s:%s(%s):%s %s", rt.Args[1][1], rt.Args[2][1], delegateConf.Name, cniConfName, rt.IfName, string(delegateConf.Bytes))
542+
}
543+
544+
var err error
545+
if isConfList {
546+
err = conflistStatus(rt, delegateConf.Bytes, multusNetconf, exec)
547+
} else {
548+
err = confStatus(rt, delegateConf.Bytes, multusNetconf, exec)
549+
}
550+
551+
if err != nil {
552+
var cniErr *cnitypes.Error
553+
if stderrors.As(err, &cniErr) {
554+
return err
555+
}
556+
if isConfList {
557+
return logging.Errorf("DelegateStatus: error invoking ConflistStatus - %q: %v", delegateConf.ConfList.Name, err)
558+
}
559+
return logging.Errorf("DelegateStatus: error invoking ConfStatus - %q: %v", delegateConf.Conf.Type, err)
560+
}
561+
562+
return err
563+
}
564+
459565
// DelegateDel ...
460566
func DelegateDel(exec invoke.Exec, pod *v1.Pod, delegateConf *types.DelegateNetConf, rt *libcni.RuntimeConf, multusNetconf *types.NetConf) error {
461567
logging.Debugf("DelegateDel: %v, %v, %v, %v", exec, pod, delegateConf, rt)
@@ -659,10 +765,10 @@ func CmdAdd(args *skel.CmdArgs, exec invoke.Exec, kubeClient *k8s.ClientInfo) (c
659765

660766
pod, err := GetPod(kubeClient, k8sArgs, false)
661767
if err != nil {
662-
if err == errPodNotFound {
663-
emptyresult := emptyCNIResult(args, "1.0.0")
664-
logging.Verbosef("CmdAdd: Warning: pod [%s/%s] not found, exiting with empty CNI result: %v", k8sArgs.K8S_POD_NAMESPACE, k8sArgs.K8S_POD_NAME, emptyresult)
665-
return emptyresult, nil
768+
if stderrors.Is(err, errPodNotFound) {
769+
emptyResult := emptyCNIResult(args, n.CNIVersion)
770+
logging.Verbosef("CmdAdd: Warning: pod [%s/%s] not found, exiting with empty CNI result: %v", k8sArgs.K8S_POD_NAMESPACE, k8sArgs.K8S_POD_NAME, emptyResult)
771+
return emptyResult, nil
666772
}
667773
return nil, err
668774
}
@@ -1050,17 +1156,26 @@ func CmdStatus(args *skel.CmdArgs, exec invoke.Exec, kubeClient *k8s.ClientInfo)
10501156

10511157
// invoke delegate's STATUS command
10521158
// we only need to check cluster network status
1159+
delegate := n.Delegates[0]
1160+
if !delegate.ConfListPlugin {
1161+
return confStatus(&libcni.RuntimeConf{}, delegate.Bytes, n, exec)
1162+
}
1163+
10531164
binDirs := filepath.SplitList(os.Getenv("CNI_PATH"))
10541165
binDirs = append([]string{n.BinDir}, binDirs...)
10551166
cniNet := libcni.NewCNIConfigWithCacheDir(binDirs, n.CNIDir, exec)
10561167

1057-
conf, err := libcni.ConfListFromBytes(n.Delegates[0].Bytes)
1168+
conf, err := libcni.ConfListFromBytes(delegate.Bytes)
10581169
if err != nil {
10591170
return logging.Errorf("error in converting the raw bytes to conf: %v", err)
10601171
}
10611172

1062-
err = cniNet.GetStatusNetworkList(context.TODO(), conf)
1173+
err = cniNet.GetStatusNetworkList(context.Background(), conf)
10631174
if err != nil {
1175+
var cniErr *cnitypes.Error
1176+
if stderrors.As(err, &cniErr) {
1177+
return err
1178+
}
10641179
return logging.Errorf("error in STATUS command: %v", err)
10651180
}
10661181

@@ -1101,17 +1216,36 @@ func CmdGC(args *skel.CmdArgs, exec invoke.Exec, kubeClient *k8s.ClientInfo) err
11011216
binDirs = append([]string{n.BinDir}, binDirs...)
11021217
cniNet := libcni.NewCNIConfigWithCacheDir(binDirs, n.CNIDir, exec)
11031218

1104-
conf, err := libcni.ConfListFromBytes(n.Delegates[0].Bytes)
1105-
if err != nil {
1106-
return logging.Errorf("error in converting the raw bytes to conf: %v", err)
1219+
delegate := n.Delegates[0]
1220+
isConfList := delegate.ConfListPlugin
1221+
if !isConfList && delegate.Conf.Type == "" && delegate.ConfList.Name != "" {
1222+
isConfList = true
1223+
}
1224+
1225+
var confList *libcni.NetworkConfigList
1226+
if isConfList {
1227+
confList, err = libcni.ConfListFromBytes(delegate.Bytes)
1228+
if err != nil {
1229+
return logging.Errorf("error in converting the raw bytes to conf: %v", err)
1230+
}
1231+
} else {
1232+
conf, err := libcni.ConfFromBytes(delegate.Bytes)
1233+
if err != nil {
1234+
return logging.Errorf("error in converting the raw bytes to conf: %v", err)
1235+
}
1236+
confList = &libcni.NetworkConfigList{
1237+
Name: conf.Network.Name,
1238+
CNIVersion: conf.Network.CNIVersion,
1239+
Plugins: []*libcni.PluginConfig{conf},
1240+
}
11071241
}
11081242

11091243
validAttachments, err := gatherValidAttachmentsFromCache(n.CNIDir)
11101244
if err != nil {
11111245
return logging.Errorf("error in gather valid attachments: %v", err)
11121246
}
11131247

1114-
err = cniNet.GCNetworkList(context.TODO(), conf, &libcni.GCArgs{
1248+
err = cniNet.GCNetworkList(context.TODO(), confList, &libcni.GCArgs{
11151249
ValidAttachments: validAttachments,
11161250
})
11171251
if err != nil {

0 commit comments

Comments
 (0)