diff --git a/go.mod b/go.mod index 1c9082ce0..c75cd3776 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/containernetworking/cni v0.7.1 github.com/containernetworking/plugins v0.8.2 github.com/json-iterator/go v1.1.9 // indirect - github.com/k8snetworkplumbingwg/network-attachment-definition-client v0.0.0-20200626054723-37f83d1996bc + github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.1.1-0.20201119153432-9d213757d22d github.com/onsi/ginkgo v1.11.0 github.com/onsi/gomega v1.7.0 github.com/pkg/errors v0.8.1 diff --git a/go.sum b/go.sum index 387238959..78ca40f49 100644 --- a/go.sum +++ b/go.sum @@ -59,6 +59,7 @@ github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34 github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc= @@ -119,8 +120,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/juju/errors v0.0.0-20180806074554-22422dad46e1/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= github.com/juju/testing v0.0.0-20190613124551-e81189438503/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= -github.com/k8snetworkplumbingwg/network-attachment-definition-client v0.0.0-20200626054723-37f83d1996bc h1:M7bj0RX9dc79YIyptmHm0tPmC/WuIbn+HVeTBDK2KZw= -github.com/k8snetworkplumbingwg/network-attachment-definition-client v0.0.0-20200626054723-37f83d1996bc/go.mod h1:+1DpV8uIwteAhxNO0lgRox8gHkTG6w3OeDfAlg+qqjA= +github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.1.1-0.20201119153432-9d213757d22d h1:9QbZltQGRFe7temwcTDjj8rIbow48Gv6mIKOxuks+OI= +github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.1.1-0.20201119153432-9d213757d22d/go.mod h1:+1DpV8uIwteAhxNO0lgRox8gHkTG6w3OeDfAlg+qqjA= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -134,6 +135,7 @@ github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -303,8 +305,10 @@ k8s.io/apimachinery v0.18.3 h1:pOGcbVAhxADgUYnjS08EFXs9QMl8qaH5U4fr5LGUrSk= k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= k8s.io/client-go v0.18.3 h1:QaJzz92tsN67oorwzmoB0a9r9ZVHuD5ryjbCKP0U22k= k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw= +k8s.io/code-generator v0.18.3 h1:5H57pYEbkMMXCLKD16YQH3yDPAbVLweUsB1M3m70D1c= k8s.io/code-generator v0.18.3/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20200114144118-36b2048a9120 h1:RPscN6KhmG54S33L+lr3GS+oD1jmchIU0ll519K6FA4= k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= diff --git a/k8sclient/k8sclient.go b/k8sclient/k8sclient.go index 858085c28..e0b96067e 100644 --- a/k8sclient/k8sclient.go +++ b/k8sclient/k8sclient.go @@ -285,7 +285,7 @@ func getKubernetesDelegate(client *ClientInfo, net *types.NetworkSelectionElemen return nil, resourceMap, err } - delegate, err := types.LoadDelegateNetConf(configBytes, net, deviceID) + delegate, err := types.LoadDelegateNetConf(configBytes, net, deviceID, resourceName) if err != nil { return nil, resourceMap, err } @@ -495,7 +495,7 @@ func getNetDelegate(client *ClientInfo, pod *v1.Pod, netname, confdir, namespace var configBytes []byte configBytes, err = netutils.GetCNIConfigFromFile(netname, confdir) if err == nil { - delegate, err := types.LoadDelegateNetConf(configBytes, nil, "") + delegate, err := types.LoadDelegateNetConf(configBytes, nil, "", "") if err != nil { return nil, resourceMap, err } @@ -514,7 +514,7 @@ func getNetDelegate(client *ClientInfo, pod *v1.Pod, netname, confdir, namespace var configBytes []byte configBytes, err = netutils.GetCNIConfigFromFile("", netname) if err == nil { - delegate, err := types.LoadDelegateNetConf(configBytes, nil, "") + delegate, err := types.LoadDelegateNetConf(configBytes, nil, "", "") if err != nil { return nil, resourceMap, err } diff --git a/k8sclient/k8sclient_test.go b/k8sclient/k8sclient_test.go index 005598015..8f8ba5550 100644 --- a/k8sclient/k8sclient_test.go +++ b/k8sclient/k8sclient_test.go @@ -1184,10 +1184,10 @@ users: } }` - delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0") + delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0", "") Expect(err).NotTo(HaveOccurred()) - delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin) + delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin, nil) GinkgoT().Logf("delegateNetStatus %+v\n", delegateNetStatus) Expect(err).NotTo(HaveOccurred()) @@ -1266,10 +1266,10 @@ users: } }` - delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0") + delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0", "") Expect(err).NotTo(HaveOccurred()) - delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin) + delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin, nil) GinkgoT().Logf("delegateNetStatus %+v\n", delegateNetStatus) Expect(err).NotTo(HaveOccurred()) @@ -1326,10 +1326,10 @@ users: }` // note that the provided kubeconfig is invalid - delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "") + delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "", "") Expect(err).NotTo(HaveOccurred()) - delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin) + delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin, nil) GinkgoT().Logf("delegateNetStatus %+v\n", delegateNetStatus) Expect(err).NotTo(HaveOccurred()) @@ -1385,10 +1385,10 @@ users: } }` - delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0") + delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0", "") Expect(err).NotTo(HaveOccurred()) - delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin) + delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin, nil) GinkgoT().Logf("delegateNetStatus %+v\n", delegateNetStatus) Expect(err).NotTo(HaveOccurred()) diff --git a/multus/multus.go b/multus/multus.go index 825b2ac38..3152ee650 100644 --- a/multus/multus.go +++ b/multus/multus.go @@ -104,6 +104,20 @@ func getIfname(delegate *types.DelegateNetConf, argif string, idx int) string { return fmt.Sprintf("net%d", idx) } +func getDelegateDeviceInfo(delegate *types.DelegateNetConf, runtimeConf *libcni.RuntimeConf) (*nettypes.DeviceInfo, error) { + // If the DPDeviceInfoFile was created, it was copied to the CNIDeviceInfoFile. + // If the DPDeviceInfoFile was not created, CNI might have created it. So + // either way, load CNIDeviceInfoFile. + if info, ok := runtimeConf.CapabilityArgs["CNIDeviceInfoFile"]; ok { + if infostr, ok := info.(string); ok { + return nadutils.LoadDeviceInfoFromCNI(infostr) + } + } else { + logging.Debugf("getDelegateDeviceInfo(): No CapArgs - info=%v ok=%v", info, ok) + } + return nil, nil +} + func saveDelegates(containerID, dataDir string, delegates []*types.DelegateNetConf) error { logging.Debugf("saveDelegates: %s, %s, %v", containerID, dataDir, delegates) delegatesBytes, err := json.Marshal(delegates) @@ -443,20 +457,31 @@ func delegateDel(exec invoke.Exec, pod *v1.Pod, ifName string, delegateConf *typ return err } -func delPlugins(exec invoke.Exec, pod *v1.Pod, argIfname string, delegates []*types.DelegateNetConf, lastIdx int, rt *libcni.RuntimeConf, binDir string) error { - logging.Debugf("delPlugins: %v, %v, %s, %v, %d, %v, %s", exec, pod, argIfname, delegates, lastIdx, rt, binDir) +// delPlugins deletes plugins in reverse order from lastdIdx +// Uses netRt as base RuntimeConf (coming from NetConf) but merges it +// with each of the delegates' configuration +func delPlugins(exec invoke.Exec, pod *v1.Pod, args *skel.CmdArgs, k8sArgs *types.K8sArgs, delegates []*types.DelegateNetConf, lastIdx int, netRt *types.RuntimeConfig, binDir string) error { + logging.Debugf("delPlugins: %v, %v, %v, %v, %v, %d, %v, %s", exec, pod, args, k8sArgs, delegates, lastIdx, netRt, binDir) if os.Setenv("CNI_COMMAND", "DEL") != nil { - return logging.Errorf("delPlugins: error setting envionment variable CNI_COMMAND to a value of DEL") + return logging.Errorf("delPlugins: error setting environment variable CNI_COMMAND to a value of DEL") } var errorstrings []string for idx := lastIdx; idx >= 0; idx-- { - ifName := getIfname(delegates[idx], argIfname, idx) - rt.IfName = ifName + ifName := getIfname(delegates[idx], args.IfName, idx) + rt, cniDeviceInfoPath := types.CreateCNIRuntimeConf(args, k8sArgs, ifName, netRt, delegates[idx]) // Attempt to delete all but do not error out, instead, collect all errors. if err := delegateDel(exec, pod, ifName, delegates[idx], rt, binDir); err != nil { errorstrings = append(errorstrings, err.Error()) } + if cniDeviceInfoPath != "" { + err := nadutils.CleanDeviceInfoForCNI(cniDeviceInfoPath) + // Even if the filename is set, file may not be present. Ignore error, + // but log and in the future may need to filter on specific errors. + if err != nil { + logging.Debugf("delPlugins: CleanDeviceInfoForCNI returned an error - err=%v", err) + } + } } // Check if we had any errors, and send them all back. @@ -562,9 +587,16 @@ func cmdAdd(args *skel.CmdArgs, exec invoke.Exec, kubeClient *k8s.ClientInfo) (c cniArgs := os.Getenv("CNI_ARGS") for idx, delegate := range n.Delegates { ifName := getIfname(delegate, args.IfName, idx) + rt, cniDeviceInfoPath := types.CreateCNIRuntimeConf(args, k8sArgs, ifName, n.RuntimeConfig, delegate) + if cniDeviceInfoPath != "" { + err = nadutils.CopyDeviceInfoForCNIFromDP(cniDeviceInfoPath, delegate.ResourceName, delegate.DeviceID) + // Even if the filename is set, file may not be present. Ignore error, + // but log and in the future may need to filter on specific errors. + if err != nil { + logging.Debugf("cmdAdd: CopyDeviceInfoForCNIFromDP returned an error - err=%v", err) + } + } - runtimeConfig := types.MergeCNIRuntimeConfig(n.RuntimeConfig, delegate) - rt := types.CreateCNIRuntimeConf(args, k8sArgs, ifName, runtimeConfig) tmpResult, err = delegateAdd(exec, kubeClient, pod, ifName, delegate, rt, n.BinDir, cniArgs) if err != nil { // If the add failed, tear down all networks we already added @@ -573,7 +605,7 @@ func cmdAdd(args *skel.CmdArgs, exec invoke.Exec, kubeClient *k8s.ClientInfo) (c netName = delegate.ConfList.Name } // Ignore errors; DEL must be idempotent anyway - _ = delPlugins(exec, nil, args.IfName, n.Delegates, idx, rt, n.BinDir) + _ = delPlugins(exec, nil, args, k8sArgs, n.Delegates, idx, n.RuntimeConfig, n.BinDir) return nil, cmdPluginErr(k8sArgs, netName, "error adding container to network %q: %v", netName, err) } @@ -612,16 +644,28 @@ func cmdAdd(args *skel.CmdArgs, exec invoke.Exec, kubeClient *k8s.ClientInfo) (c result = tmpResult } + // Read devInfo from CNIDeviceInfoFile if it exists so + // it can be copied to the NetworkStatus. + devinfo, err := getDelegateDeviceInfo(delegate, rt) + if err != nil { + // Even if the filename is set, file may not be present. Ignore error, + // but log and in the future may need to filter on specific errors. + logging.Debugf("cmdAdd: getDelegateDeviceInfo returned an error - err=%v", err) + } + // create the network status, only in case Multus as kubeconfig if n.Kubeconfig != "" && kc != nil { if !types.CheckSystemNamespaces(string(k8sArgs.K8S_POD_NAME), n.SystemNamespaces) { - delegateNetStatus, err := nadutils.CreateNetworkStatus(tmpResult, delegate.Name, delegate.MasterPlugin) + delegateNetStatus, err := nadutils.CreateNetworkStatus(tmpResult, delegate.Name, delegate.MasterPlugin, devinfo) if err != nil { return nil, cmdErr(k8sArgs, "error setting network status: %v", err) } netStatus = append(netStatus, *delegateNetStatus) } + } else if devinfo != nil { + // Warn that devinfo exists but could not add it to downwards API + logging.Errorf("devinfo available, but no kubeConfig so NetworkStatus not modified.") } } @@ -656,8 +700,7 @@ func cmdCheck(args *skel.CmdArgs, exec invoke.Exec, kubeClient *k8s.ClientInfo) for idx, delegate := range in.Delegates { ifName := getIfname(delegate, args.IfName, idx) - runtimeConfig := types.MergeCNIRuntimeConfig(in.RuntimeConfig, delegate) - rt := types.CreateCNIRuntimeConf(args, k8sArgs, ifName, runtimeConfig) + rt, _ := types.CreateCNIRuntimeConf(args, k8sArgs, ifName, in.RuntimeConfig, delegate) err = delegateCheck(exec, ifName, delegate, rt, in.BinDir) if err != nil { return err @@ -808,8 +851,7 @@ func cmdDel(args *skel.CmdArgs, exec invoke.Exec, kubeClient *k8s.ClientInfo) er } } - rt := types.CreateCNIRuntimeConf(args, k8sArgs, "", in.RuntimeConfig) - return delPlugins(exec, pod, args.IfName, in.Delegates, len(in.Delegates)-1, rt, in.BinDir) + return delPlugins(exec, pod, args, k8sArgs, in.Delegates, len(in.Delegates)-1, in.RuntimeConfig, in.BinDir) } func main() { diff --git a/multus/multus_test.go b/multus/multus_test.go index 2934415fa..0184e597b 100644 --- a/multus/multus_test.go +++ b/multus/multus_test.go @@ -2031,7 +2031,7 @@ var _ = Describe("multus operations cniVersion 0.2.0 config", func() { rawnetconflist := []byte(`{"cniVersion":"0.2.0","name":"weave1","type":"weave-net"}`) k8sargs, err := k8sclient.GetK8sArgs(args) n, err := types.LoadNetConf(args.StdinData) - rt := types.CreateCNIRuntimeConf(args, k8sargs, args.IfName, n.RuntimeConfig) + rt, _ := types.CreateCNIRuntimeConf(args, k8sargs, args.IfName, n.RuntimeConfig, nil) err = conflistDel(rt, rawnetconflist, binDir, fExec) Expect(err).To(HaveOccurred()) @@ -3277,7 +3277,7 @@ var _ = Describe("multus operations cniVersion 0.4.0 config", func() { rawnetconflist := []byte(`{"cniVersion":"0.4.0","name":"weave1","type":"weave-net"}`) k8sargs, err := k8sclient.GetK8sArgs(args) n, err := types.LoadNetConf(args.StdinData) - rt := types.CreateCNIRuntimeConf(args, k8sargs, args.IfName, n.RuntimeConfig) + rt, _ := types.CreateCNIRuntimeConf(args, k8sargs, args.IfName, n.RuntimeConfig, nil) err = conflistDel(rt, rawnetconflist, binDir, fExec) Expect(err).To(HaveOccurred()) diff --git a/types/conf.go b/types/conf.go index 0a20df118..16e480707 100644 --- a/types/conf.go +++ b/types/conf.go @@ -24,6 +24,7 @@ import ( "github.com/containernetworking/cni/pkg/skel" "github.com/containernetworking/cni/pkg/types/current" "github.com/containernetworking/cni/pkg/version" + nadutils "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils" "gopkg.in/intel/multus-cni.v3/logging" ) @@ -55,7 +56,7 @@ func LoadDelegateNetConfList(bytes []byte, delegateConf *DelegateNetConf) error } // LoadDelegateNetConf converts raw CNI JSON into a DelegateNetConf structure -func LoadDelegateNetConf(bytes []byte, net *NetworkSelectionElement, deviceID string) (*DelegateNetConf, error) { +func LoadDelegateNetConf(bytes []byte, net *NetworkSelectionElement, deviceID string, resourceName string) (*DelegateNetConf, error) { var err error logging.Debugf("LoadDelegateNetConf: %s, %v, %s", string(bytes), net, deviceID) @@ -87,6 +88,9 @@ func LoadDelegateNetConf(bytes []byte, net *NetworkSelectionElement, deviceID st if err != nil { return nil, logging.Errorf("LoadDelegateNetConf: failed to add deviceID in NetConf bytes: %v", err) } + // Save them for housekeeping + delegateConf.ResourceName = resourceName + delegateConf.DeviceID = deviceID } if net != nil && net.CNIArgs != nil { bytes, err = addCNIArgsInConfig(bytes, net.CNIArgs) @@ -122,6 +126,13 @@ func LoadDelegateNetConf(bytes []byte, net *NetworkSelectionElement, deviceID st if net.InfinibandGUIDRequest != "" { delegateConf.InfinibandGUIDRequest = net.InfinibandGUIDRequest } + if net.DeviceID != "" { + if deviceID != "" { + logging.Debugf("Warning: Both RuntimeConfig and ResourceMap provide deviceID. Ignoring RuntimeConfig") + } else { + delegateConf.DeviceID = net.DeviceID + } + } } delegateConf.Bytes = bytes @@ -129,16 +140,16 @@ func LoadDelegateNetConf(bytes []byte, net *NetworkSelectionElement, deviceID st return delegateConf, nil } -// MergeCNIRuntimeConfig creates CNI runtimeconfig from delegate -func MergeCNIRuntimeConfig(runtimeConfig *RuntimeConfig, delegate *DelegateNetConf) *RuntimeConfig { - logging.Debugf("MergeCNIRuntimeConfig: %v %v", runtimeConfig, delegate) +// mergeCNIRuntimeConfig creates CNI runtimeconfig from delegate +func mergeCNIRuntimeConfig(runtimeConfig *RuntimeConfig, delegate *DelegateNetConf) *RuntimeConfig { + logging.Debugf("mergeCNIRuntimeConfig: %v %v", runtimeConfig, delegate) if runtimeConfig == nil { runtimeConfig = &RuntimeConfig{} } // multus inject RuntimeConfig only in case of non MasterPlugin. if delegate.MasterPlugin != true { - logging.Debugf("MergeCNIRuntimeConfig: add runtimeConfig for net-attach-def: %v", runtimeConfig) + logging.Debugf("mergeCNIRuntimeConfig: add runtimeConfig for net-attach-def: %v", runtimeConfig) if delegate.PortMappingsRequest != nil { runtimeConfig.PortMaps = delegate.PortMappingsRequest } @@ -154,14 +165,31 @@ func MergeCNIRuntimeConfig(runtimeConfig *RuntimeConfig, delegate *DelegateNetCo if delegate.InfinibandGUIDRequest != "" { runtimeConfig.InfinibandGUID = delegate.InfinibandGUIDRequest } + if delegate.DeviceID != "" { + runtimeConfig.DeviceID = delegate.DeviceID + } + logging.Debugf("mergeCNIRuntimeConfig: add runtimeConfig for net-attach-def: %v", runtimeConfig) } return runtimeConfig } -// CreateCNIRuntimeConf create CNI RuntimeConf -func CreateCNIRuntimeConf(args *skel.CmdArgs, k8sArgs *K8sArgs, ifName string, rc *RuntimeConfig) *libcni.RuntimeConf { - logging.Debugf("LoadCNIRuntimeConf: %v, %v, %s, %v", args, k8sArgs, ifName, rc) +// CreateCNIRuntimeConf create CNI RuntimeConf for a delegate. If delegate configuration +// exists, merge data with the runtime config. +func CreateCNIRuntimeConf(args *skel.CmdArgs, k8sArgs *K8sArgs, ifName string, rc *RuntimeConfig, delegate *DelegateNetConf) (*libcni.RuntimeConf, string) { + logging.Debugf("LoadCNIRuntimeConf: %v, %v, %s, %v %v", args, k8sArgs, ifName, rc, delegate) + var cniDeviceInfoFile string + + delegateRc := rc + if delegate != nil { + delegateRc = mergeCNIRuntimeConfig(delegateRc, delegate) + if delegateRc.CNIDeviceInfoFile == "" && delegate.Name != "" { + autoDeviceInfo := fmt.Sprintf("%s-%s_%s", delegate.Name, args.ContainerID, ifName) + delegateRc.CNIDeviceInfoFile = nadutils.GetCNIDeviceInfoPath(autoDeviceInfo) + cniDeviceInfoFile = delegateRc.CNIDeviceInfoFile + logging.Debugf("Adding auto-generated CNIDeviceInfoFile: %s", delegateRc.CNIDeviceInfoFile) + } + } // In part, adapted from K8s pkg/kubelet/dockershim/network/cni/cni.go#buildCNIRuntimeConf // Todo @@ -179,26 +207,32 @@ func CreateCNIRuntimeConf(args *skel.CmdArgs, k8sArgs *K8sArgs, ifName string, r }, } - if rc != nil { + if delegateRc != nil { capabilityArgs := map[string]interface{}{} - if len(rc.PortMaps) != 0 { - capabilityArgs["portMappings"] = rc.PortMaps + if len(delegateRc.PortMaps) != 0 { + capabilityArgs["portMappings"] = delegateRc.PortMaps + } + if delegateRc.Bandwidth != nil { + capabilityArgs["bandwidth"] = delegateRc.Bandwidth + } + if len(delegateRc.IPs) != 0 { + capabilityArgs["ips"] = delegateRc.IPs } - if rc.Bandwidth != nil { - capabilityArgs["bandwidth"] = rc.Bandwidth + if len(delegateRc.Mac) != 0 { + capabilityArgs["mac"] = delegateRc.Mac } - if len(rc.IPs) != 0 { - capabilityArgs["ips"] = rc.IPs + if len(delegateRc.InfinibandGUID) != 0 { + capabilityArgs["infinibandGUID"] = delegateRc.InfinibandGUID } - if len(rc.Mac) != 0 { - capabilityArgs["mac"] = rc.Mac + if delegateRc.DeviceID != "" { + capabilityArgs["deviceID"] = delegateRc.DeviceID } - if len(rc.InfinibandGUID) != 0 { - capabilityArgs["infinibandGUID"] = rc.InfinibandGUID + if delegateRc.CNIDeviceInfoFile != "" { + capabilityArgs["CNIDeviceInfoFile"] = delegateRc.CNIDeviceInfoFile } rt.CapabilityArgs = capabilityArgs } - return rt + return rt, cniDeviceInfoFile } // GetGatewayFromResult retrieves gateway IP addresses from CNI result @@ -292,7 +326,7 @@ func LoadNetConf(bytes []byte) (*NetConf, error) { if err != nil { return nil, logging.Errorf("LoadNetConf: error marshalling delegate %d config: %v", idx, err) } - delegateConf, err := LoadDelegateNetConf(bytes, nil, "") + delegateConf, err := LoadDelegateNetConf(bytes, nil, "", "") if err != nil { return nil, logging.Errorf("LoadNetConf: failed to load delegate %d config: %v", idx, err) } diff --git a/types/conf_test.go b/types/conf_test.go index 6264c964d..1caa915be 100644 --- a/types/conf_test.go +++ b/types/conf_test.go @@ -102,7 +102,7 @@ var _ = Describe("config operations", func() { _, err := LoadNetConf([]byte(conf)) Expect(err).To(HaveOccurred()) - _, err = LoadDelegateNetConf([]byte(conf), nil, "") + _, err = LoadDelegateNetConf([]byte(conf), nil, "", "") Expect(err).To(HaveOccurred()) err = LoadDelegateNetConfList([]byte(conf), &DelegateNetConf{}) Expect(err).To(HaveOccurred()) @@ -280,7 +280,7 @@ var _ = Describe("config operations", func() { DeviceID string `json:"deviceID"` } sriovConf := &sriovNetConf{} - delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0") + delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0", "") Expect(err).NotTo(HaveOccurred()) err = json.Unmarshal(delegateNetConf.Bytes, &sriovConf) @@ -306,7 +306,7 @@ var _ = Describe("config operations", func() { Plugins []*sriovNetConf `json:"plugins"` } sriovConfList := &sriovNetConfList{} - delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.1") + delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.1", "") Expect(err).NotTo(HaveOccurred()) err = json.Unmarshal(delegateNetConf.Bytes, &sriovConfList) @@ -335,7 +335,7 @@ var _ = Describe("config operations", func() { Plugins []*sriovNetConf `json:"plugins"` } sriovConfList := &sriovNetConfList{} - delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.1") + delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.1", "") Expect(err).NotTo(HaveOccurred()) err = json.Unmarshal(delegateNetConf.Bytes, &sriovConfList) @@ -356,7 +356,7 @@ var _ = Describe("config operations", func() { PCIBusID string `json:"pciBusID"` } hostDeviceConf := &hostDeviceNetConf{} - delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.2") + delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.2", "") Expect(err).NotTo(HaveOccurred()) err = json.Unmarshal(delegateNetConf.Bytes, &hostDeviceConf) @@ -382,7 +382,7 @@ var _ = Describe("config operations", func() { Plugins []*hostDeviceNetConf `json:"plugins"` } hostDeviceConfList := &hostDeviceNetConfList{} - delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.3") + delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.3", "") Expect(err).NotTo(HaveOccurred()) err = json.Unmarshal(delegateNetConf.Bytes, &hostDeviceConfList) @@ -411,7 +411,7 @@ var _ = Describe("config operations", func() { Plugins []*hostDeviceNetConf `json:"plugins"` } hostDeviceConfList := &hostDeviceNetConfList{} - delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.3") + delegateNetConf, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.3", "") Expect(err).NotTo(HaveOccurred()) err = json.Unmarshal(delegateNetConf.Bytes, &hostDeviceConfList) @@ -444,7 +444,7 @@ var _ = Describe("config operations", func() { Name: "test-elem", CNIArgs: &args, } - delegateNetConf, err := LoadDelegateNetConf([]byte(conf), net, "") + delegateNetConf, err := LoadDelegateNetConf([]byte(conf), net, "", "") Expect(err).NotTo(HaveOccurred()) bridgeConf := &bridgeNetConf{} err = json.Unmarshal(delegateNetConf.Bytes, bridgeConf) @@ -480,7 +480,7 @@ var _ = Describe("config operations", func() { Name: "test-elem", CNIArgs: &args, } - delegateNetConf, err := LoadDelegateNetConf([]byte(conf), net, "") + delegateNetConf, err := LoadDelegateNetConf([]byte(conf), net, "", "") Expect(err).NotTo(HaveOccurred()) bridgeConf := &bridgeNetConf{} err = json.Unmarshal(delegateNetConf.Bytes, bridgeConf) @@ -518,7 +518,7 @@ var _ = Describe("config operations", func() { Name: "test-elem", CNIArgs: &args, } - delegateNetConf, err := LoadDelegateNetConf([]byte(conf), net, "") + delegateNetConf, err := LoadDelegateNetConf([]byte(conf), net, "", "") Expect(err).NotTo(HaveOccurred()) bridgeConflist := &bridgeNetConfList{} err = json.Unmarshal(delegateNetConf.Bytes, bridgeConflist) @@ -565,7 +565,7 @@ var _ = Describe("config operations", func() { HostIP: "anotherSampleHostIP", } - rt := CreateCNIRuntimeConf(args, k8sArgs, "", rc) + rt, _ := CreateCNIRuntimeConf(args, k8sArgs, "", rc, nil) fmt.Println("rt.ContainerID: ", rt.ContainerID) Expect(rt.ContainerID).To(Equal("123456789")) Expect(rt.NetNS).To(Equal(args.Netns)) @@ -595,10 +595,10 @@ var _ = Describe("config operations", func() { } }` - delegate, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0") + delegate, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0", "") Expect(err).NotTo(HaveOccurred()) - delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin) + delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin, nil) GinkgoT().Logf("delegateNetStatus %+v\n", delegateNetStatus) @@ -628,10 +628,10 @@ var _ = Describe("config operations", func() { } }` - delegate, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0") + delegate, err := LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0", "") Expect(err).NotTo(HaveOccurred()) fmt.Println("result.Version: ", result.Version()) - delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin) + delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin, nil) GinkgoT().Logf("delegateNetStatus %+v\n", delegateNetStatus) @@ -668,7 +668,7 @@ var _ = Describe("config operations", func() { PortMappingsRequest: []*PortMapEntry{portMapEntry1}, } - delegateConf, err := LoadDelegateNetConf([]byte(cniConfig), networkSelection, "") + delegateConf, err := LoadDelegateNetConf([]byte(cniConfig), networkSelection, "", "") Expect(err).NotTo(HaveOccurred()) Expect(delegateConf.IfnameRequest).To(Equal(networkSelection.InterfaceRequest)) Expect(delegateConf.MacRequest).To(Equal(networkSelection.MacRequest)) @@ -678,7 +678,7 @@ var _ = Describe("config operations", func() { Expect(delegateConf.PortMappingsRequest).To(Equal(networkSelection.PortMappingsRequest)) }) - It("test MergeCNIRuntimeConfig with masterPlugin", func() { + It("test mergeCNIRuntimeConfig with masterPlugin", func() { conf := `{ "name": "node-cni-network", "type": "multus", @@ -714,16 +714,16 @@ var _ = Describe("config operations", func() { BandwidthRequest: bandwidthEntry1, PortMappingsRequest: []*PortMapEntry{portMapEntry1}, } - delegate, err := LoadDelegateNetConf([]byte(conf), networkSelection, "") + delegate, err := LoadDelegateNetConf([]byte(conf), networkSelection, "", "") delegate.MasterPlugin = true Expect(err).NotTo(HaveOccurred()) - runtimeConf := MergeCNIRuntimeConfig(&RuntimeConfig{}, delegate) + runtimeConf := mergeCNIRuntimeConfig(&RuntimeConfig{}, delegate) Expect(runtimeConf.PortMaps).To(BeNil()) Expect(runtimeConf.Bandwidth).To(BeNil()) Expect(runtimeConf.InfinibandGUID).To(Equal("")) }) - It("test MergeCNIRuntimeConfig with delegate plugin", func() { + It("test mergeCNIRuntimeConfig with delegate plugin", func() { conf := `{ "name": "weave1", "cniVersion": "0.2.0", @@ -751,9 +751,9 @@ var _ = Describe("config operations", func() { BandwidthRequest: bandwidthEntry1, PortMappingsRequest: []*PortMapEntry{portMapEntry1}, } - delegate, err := LoadDelegateNetConf([]byte(conf), networkSelection, "") + delegate, err := LoadDelegateNetConf([]byte(conf), networkSelection, "", "") Expect(err).NotTo(HaveOccurred()) - runtimeConf := MergeCNIRuntimeConfig(&RuntimeConfig{}, delegate) + runtimeConf := mergeCNIRuntimeConfig(&RuntimeConfig{}, delegate) Expect(runtimeConf.PortMaps).NotTo(BeNil()) Expect(len(runtimeConf.PortMaps)).To(BeEquivalentTo(1)) Expect(runtimeConf.PortMaps[0]).To(Equal(portMapEntry1)) diff --git a/types/types.go b/types/types.go index 450b81f61..d57a02565 100644 --- a/types/types.go +++ b/types/types.go @@ -38,7 +38,6 @@ type NetConf struct { // RawDelegates is private to the NetConf class; use Delegates instead RawDelegates []map[string]interface{} `json:"delegates"` Delegates []*DelegateNetConf `json:"-"` - NetStatus []*NetworkStatus `json:"-"` Kubeconfig string `json:"kubeconfig"` ClusterNetwork string `json:"clusterNetwork"` DefaultNetworks []string `json:"defaultNetworks"` @@ -57,11 +56,13 @@ type NetConf struct { // RuntimeConfig specifies CNI RuntimeConfig type RuntimeConfig struct { - PortMaps []*PortMapEntry `json:"portMappings,omitempty"` - Bandwidth *BandwidthEntry `json:"bandwidth,omitempty"` - IPs []string `json:"ips,omitempty"` - Mac string `json:"mac,omitempty"` - InfinibandGUID string `json:"infinibandGUID,omitempty"` + PortMaps []*PortMapEntry `json:"portMappings,omitempty"` + Bandwidth *BandwidthEntry `json:"bandwidth,omitempty"` + IPs []string `json:"ips,omitempty"` + Mac string `json:"mac,omitempty"` + InfinibandGUID string `json:"infinibandGUID,omitempty"` + DeviceID string `json:"deviceID,omitempty"` + CNIDeviceInfoFile string `json:"CNIDeviceInfoFile,omitempty"` } // PortMapEntry for CNI PortMapEntry @@ -81,16 +82,6 @@ type BandwidthEntry struct { EgressBurst int `json:"egressBurst"` } -// NetworkStatus is for network status annotation for pod -type NetworkStatus struct { - Name string `json:"name"` - Interface string `json:"interface,omitempty"` - IPs []string `json:"ips,omitempty"` - Mac string `json:"mac,omitempty"` - DNS types.DNS `json:"dns,omitempty"` - Gateway []net.IP `json:"default-route,omitempty"` -} - // DelegateNetConf for net-attach-def for pod type DelegateNetConf struct { Conf types.NetConf @@ -108,6 +99,10 @@ type DelegateNetConf struct { MasterPlugin bool `json:"-"` // Conflist plugin is only used internal housekeeping ConfListPlugin bool `json:"-"` + // DeviceID is only used internal housekeeping + DeviceID string `json:"deviceID,omitempty"` + // ResourceName is only used internal housekeeping + ResourceName string `json:"resourceName,omitempty"` // Raw JSON Bytes []byte @@ -143,6 +138,8 @@ type NetworkSelectionElement struct { // BandwidthRequest contains an optional requested bandwidth for // the network BandwidthRequest *BandwidthEntry `json:"bandwidth,omitempty"` + // DeviceID contains an optional requested deviceID the network + DeviceID string `json:"deviceID,omitempty"` // CNIArgs contains additional CNI arguments for the network interface CNIArgs *map[string]interface{} `json:"cni-args"` // GatewayRequest contains default route IP address for the pod diff --git a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go index 0eceddc5c..b5742ab33 100644 --- a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go +++ b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go @@ -38,15 +38,74 @@ type DNS struct { Options []string `json:"options,omitempty"` } +const ( + DeviceInfoTypePCI = "pci" + DeviceInfoTypeVHostUser = "vhost-user" + DeviceInfoTypeMemif = "memif" + DeviceInfoTypeVDPA = "vdpa" + DeviceInfoVersion = "1.0.0" +) + +// DeviceInfo contains the information of the device associated +// with this network (if any) +type DeviceInfo struct { + Type string `json:"type,omitempty"` + Version string `json:"version,omitempty"` + Pci *PciDevice `json:"pci,omitempty"` + Vdpa *VdpaDevice `json:"vdpa,omitempty"` + VhostUser *VhostDevice `json:"vhost-user,omitempty"` + Memif *MemifDevice `json:"memif,omitempty"` +} + +type PciDevice struct { + PciAddress string `json:"pci-address,omitempty"` + Vhostnet string `json:"vhost-net,omitempty"` + RdmaDevice string `json:"rdma-device,omitempty"` + PfPciAddress string `json:"pf-pci-address,omitempty"` +} + +type VdpaDevice struct { + ParentDevice string `json:"parent-device,omitempty"` + Driver string `json:"driver,omitempty"` + Path string `json:"path,omitempty"` + PciAddress string `json:"pci-address,omitempty"` + PfPciAddress string `json:"pf-pci-address,omitempty"` +} + +const ( + VhostDeviceModeClient = "client" + VhostDeviceModeServer = "server" +) + +type VhostDevice struct { + Mode string `json:"mode,omitempty"` + Path string `json:"path,omitempty"` +} + +const ( + MemifDeviceRoleMaster = "master" + MemitDeviceRoleSlave = "slave" + MemifDeviceModeEthernet = "ethernet" + MemitDeviceModeIP = "ip" + MemitDeviceModePunt = "punt" +) + +type MemifDevice struct { + Role string `json:"role,omitempty"` + Path string `json:"path,omitempty"` + Mode string `json:"mode,omitempty"` +} + // NetworkStatus is for network status annotation for pod // +k8s:deepcopy-gen=false type NetworkStatus struct { - Name string `json:"name"` - Interface string `json:"interface,omitempty"` - IPs []string `json:"ips,omitempty"` - Mac string `json:"mac,omitempty"` - Default bool `json:"default,omitempty"` - DNS DNS `json:"dns,omitempty"` + Name string `json:"name"` + Interface string `json:"interface,omitempty"` + IPs []string `json:"ips,omitempty"` + Mac string `json:"mac,omitempty"` + Default bool `json:"default,omitempty"` + DNS DNS `json:"dns,omitempty"` + DeviceInfo *DeviceInfo `json:"device-info,omitempty"` } // PortMapEntry for CNI PortMapEntry diff --git a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/zz_generated.deepcopy.go b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/zz_generated.deepcopy.go index 8f74abde0..80450b73d 100644 --- a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/zz_generated.deepcopy.go +++ b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/zz_generated.deepcopy.go @@ -24,6 +24,58 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeviceInfo) DeepCopyInto(out *DeviceInfo) { + *out = *in + if in.Pci != nil { + in, out := &in.Pci, &out.Pci + *out = new(PciDevice) + **out = **in + } + if in.Vdpa != nil { + in, out := &in.Vdpa, &out.Vdpa + *out = new(VdpaDevice) + **out = **in + } + if in.VhostUser != nil { + in, out := &in.VhostUser, &out.VhostUser + *out = new(VhostDevice) + **out = **in + } + if in.Memif != nil { + in, out := &in.Memif, &out.Memif + *out = new(MemifDevice) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeviceInfo. +func (in *DeviceInfo) DeepCopy() *DeviceInfo { + if in == nil { + return nil + } + out := new(DeviceInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MemifDevice) DeepCopyInto(out *MemifDevice) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemifDevice. +func (in *MemifDevice) DeepCopy() *MemifDevice { + if in == nil { + return nil + } + out := new(MemifDevice) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NetworkAttachmentDefinition) DeepCopyInto(out *NetworkAttachmentDefinition) { *out = *in @@ -99,3 +151,51 @@ func (in *NetworkAttachmentDefinitionSpec) DeepCopy() *NetworkAttachmentDefiniti in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PciDevice) DeepCopyInto(out *PciDevice) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PciDevice. +func (in *PciDevice) DeepCopy() *PciDevice { + if in == nil { + return nil + } + out := new(PciDevice) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VdpaDevice) DeepCopyInto(out *VdpaDevice) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VdpaDevice. +func (in *VdpaDevice) DeepCopy() *VdpaDevice { + if in == nil { + return nil + } + out := new(VdpaDevice) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VhostDevice) DeepCopyInto(out *VhostDevice) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VhostDevice. +func (in *VhostDevice) DeepCopy() *VhostDevice { + if in == nil { + return nil + } + out := new(VhostDevice) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/cniconfig.go b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/cniconfig.go index 174c1658a..f1eaf3797 100644 --- a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/cniconfig.go +++ b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/cniconfig.go @@ -18,11 +18,20 @@ import ( "encoding/json" "fmt" "github.com/containernetworking/cni/libcni" + "io/ioutil" + "os" + "path/filepath" "strings" v1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" ) +const ( + baseDevInfoPath = "/var/run/k8s.cni.cncf.io/devinfo" + dpDevInfoSubDir = "dp" + cniDevInfoSubDir = "cni" +) + // GetCNIConfig (from annotation string to CNI JSON bytes) func GetCNIConfig(net *v1.NetworkAttachmentDefinition, confDir string) (config []byte, err error) { emptySpec := v1.NetworkAttachmentDefinitionSpec{} @@ -117,3 +126,112 @@ func GetCNIConfigFromSpec(configData, netName string) ([]byte, error) { return configBytes, nil } + +// loadDeviceInfo loads a Device Information file +func loadDeviceInfo(path string) (*v1.DeviceInfo, error) { + var devInfo v1.DeviceInfo + + bytes, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + + err = json.Unmarshal(bytes, &devInfo) + if err != nil { + return nil, err + } + + return &devInfo, nil +} + +// cleanDeviceInfo removes a Device Information file +func cleanDeviceInfo(path string) error { + if _, err := os.Stat(path); !os.IsNotExist(err) { + return os.Remove(path) + } + return nil +} + +// saveDeviceInfo writes a Device Information file +func saveDeviceInfo(devInfo *v1.DeviceInfo, path string) error { + if devInfo == nil { + return fmt.Errorf("Device Information is null") + } + + dir := filepath.Dir(path) + if _, err := os.Stat(dir); os.IsNotExist(err) { + if err := os.MkdirAll(dir, os.ModeDir); err != nil { + return err + } + } + + if _, err := os.Stat(path); !os.IsNotExist(err) { + return fmt.Errorf("Device Information file already exists: %s", path) + } + + devInfoJSON, err := json.Marshal(devInfo) + if err != nil { + return err + } + + if err := ioutil.WriteFile(path, devInfoJSON, 0444); err != nil { + return err + } + return nil +} + +// getDPDeviceInfoPath returns the standard Device Plugin DevInfo filename +// This filename is fixed because Device Plugin and NPWG Implementation need +// to both access file and name is not passed between them. So name is generated +// from Resource Name and DeviceID. +func getDPDeviceInfoPath(resourceName string, deviceID string) string { + return filepath.Join(baseDevInfoPath, dpDevInfoSubDir, fmt.Sprintf("%s-%s-device.json", + strings.ReplaceAll(resourceName, "/", "-"), strings.ReplaceAll(deviceID, "/", "-"))) +} + +// GetCNIDeviceInfoPath returns the standard Device Plugin DevInfo filename +// The path is fixed but the filename is flexible and determined by the caller. +func GetCNIDeviceInfoPath(filename string) string { + return filepath.Join(baseDevInfoPath, cniDevInfoSubDir, strings.ReplaceAll(filename, "/", "-")) +} + +// LoadDeviceInfoFromDP loads a DeviceInfo structure from file created by a Device Plugin +// Returns an error if the device information is malformed and (nil, nil) if it does not exist +func LoadDeviceInfoFromDP(resourceName string, deviceID string) (*v1.DeviceInfo, error) { + return loadDeviceInfo(getDPDeviceInfoPath(resourceName, deviceID)) +} + +// SaveDeviceInfoForDP saves a DeviceInfo structure created by a Device Plugin +func SaveDeviceInfoForDP(resourceName string, deviceID string, devInfo *v1.DeviceInfo) error { + return saveDeviceInfo(devInfo, getDPDeviceInfoPath(resourceName, deviceID)) +} + +// CleanDeviceInfoForDP removes a DeviceInfo DP File. +func CleanDeviceInfoForDP(resourceName string, deviceID string) error { + return cleanDeviceInfo(getDPDeviceInfoPath(resourceName, deviceID)) +} + +// LoadDeviceInfoFromCNI loads a DeviceInfo structure from created by a CNI. +// Returns an error if the device information is malformed and (nil, nil) if it does not exist +func LoadDeviceInfoFromCNI(cniPath string) (*v1.DeviceInfo, error) { + return loadDeviceInfo(cniPath) +} + +// SaveDeviceInfoForCNI saves a DeviceInfo structure created by a CNI +func SaveDeviceInfoForCNI(cniPath string, devInfo *v1.DeviceInfo) error { + return saveDeviceInfo(devInfo, cniPath) +} + +// CopyDeviceInfoForCNIFromDP saves a DeviceInfo structure created by a DP to a CNI File. +func CopyDeviceInfoForCNIFromDP(cniPath string, resourceName string, deviceID string) error { + devInfo, err := loadDeviceInfo(getDPDeviceInfoPath(resourceName, deviceID)) + if err != nil { + return err + } + return saveDeviceInfo(devInfo, cniPath) +} + +// CleanDeviceInfoForCNI removes a DeviceInfo CNI File. +func CleanDeviceInfoForCNI(cniPath string) error { + return cleanDeviceInfo(cniPath) +} diff --git a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go index b15c0965d..d8e575cd5 100644 --- a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go +++ b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go @@ -122,7 +122,7 @@ func GetNetworkStatus(pod *corev1.Pod) ([]v1.NetworkStatus, error) { } // CreateNetworkStatus create NetworkStatus from CNI result -func CreateNetworkStatus(r cnitypes.Result, networkName string, defaultNetwork bool) (*v1.NetworkStatus, error) { +func CreateNetworkStatus(r cnitypes.Result, networkName string, defaultNetwork bool, dev *v1.DeviceInfo) (*v1.NetworkStatus, error) { netStatus := &v1.NetworkStatus{} netStatus.Name = networkName netStatus.Default = defaultNetwork @@ -154,6 +154,10 @@ func CreateNetworkStatus(r cnitypes.Result, networkName string, defaultNetwork b v1dns := convertDNS(result.DNS) netStatus.DNS = *v1dns + if dev != nil { + netStatus.DeviceInfo = dev + } + return netStatus, nil } diff --git a/vendor/modules.txt b/vendor/modules.txt index 0a8f14594..2aab810f5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -45,7 +45,7 @@ github.com/hpcloud/tail/winfile github.com/imdario/mergo # github.com/json-iterator/go v1.1.9 github.com/json-iterator/go -# github.com/k8snetworkplumbingwg/network-attachment-definition-client v0.0.0-20200626054723-37f83d1996bc +# github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.1.1-0.20201119153432-9d213757d22d github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1 github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/client/clientset/versioned