mirror of
https://github.com/k8snetworkplumbingwg/multus-cni.git
synced 2025-09-17 15:07:14 +00:00
[significant] first CNI ADD using DRA that succeeds
This commit is contained in:
@@ -1,2 +1,8 @@
|
||||
# DRA Multus Driver.
|
||||
|
||||
## TODO!
|
||||
|
||||
* Plurality is a mess all over the place.
|
||||
* I tested with only one attachment, and I focused on it.
|
||||
* Things might belong on one side or the other DRA vs. CNI
|
||||
* And I just chucked it where convenient at the time.
|
@@ -57,8 +57,8 @@ metadata:
|
||||
spec:
|
||||
containers:
|
||||
- name: app
|
||||
image: ubuntu:22.04
|
||||
command: ["bash", "-c"]
|
||||
image: alpine
|
||||
command: ["/bin/ash", "-c", "trap : TERM INT; sleep infinity & wait"]
|
||||
args: ["export; trap 'exit 0' TERM; sleep 9999 & wait"]
|
||||
resources:
|
||||
claims:
|
||||
|
@@ -115,7 +115,7 @@ func StartPlugin(ctx context.Context, config *Config) error {
|
||||
return fmt.Errorf("path for cdi file generation is not a directory: '%v'", err)
|
||||
}
|
||||
|
||||
klog.Infof("Starting %s", DriverName)
|
||||
klog.Infof("Starting %s (version 0.0.0)", DriverName)
|
||||
driver, err := NewDriver(ctx, config)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@@ -6,8 +6,10 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/containernetworking/cni/libcni"
|
||||
resourceapi "k8s.io/api/resource/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -18,7 +20,6 @@ import (
|
||||
configapi "gopkg.in/k8snetworkplumbingwg/multus-cni.v4/pkg/dra/api/multus-cni.io/resource/net/v1alpha1"
|
||||
multusk8sutils "gopkg.in/k8snetworkplumbingwg/multus-cni.v4/pkg/k8sclient"
|
||||
"gopkg.in/k8snetworkplumbingwg/multus-cni.v4/pkg/types"
|
||||
multustypes "gopkg.in/k8snetworkplumbingwg/multus-cni.v4/pkg/types"
|
||||
|
||||
cdiapi "tags.cncf.io/container-device-interface/pkg/cdi"
|
||||
cdispec "tags.cncf.io/container-device-interface/specs-go"
|
||||
@@ -248,36 +249,80 @@ func (s *DeviceState) applyConfig(
|
||||
claimUID string,
|
||||
) (PerDeviceCDIContainerEdits, error) {
|
||||
perDeviceEdits := make(PerDeviceCDIContainerEdits)
|
||||
var delegates []*types.DelegateNetConf
|
||||
|
||||
// --- Add the cluster default network as the first delegate ---
|
||||
multusConfPath := "/host/etc/cni/net.d/00-multus.conf"
|
||||
multusConfBytes, err := os.ReadFile(multusConfPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read multus config from %s: %w", multusConfPath, err)
|
||||
}
|
||||
|
||||
var multusConf struct {
|
||||
ClusterNetwork string `json:"clusterNetwork"`
|
||||
}
|
||||
if err := json.Unmarshal(multusConfBytes, &multusConf); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse multus config json: %w", err)
|
||||
}
|
||||
if multusConf.ClusterNetwork == "" {
|
||||
return nil, fmt.Errorf("no clusterNetwork field found in multus config")
|
||||
}
|
||||
|
||||
// Load the default network CNI config
|
||||
var defaultConfBytes []byte
|
||||
isconflist := false
|
||||
if strings.HasSuffix(multusConf.ClusterNetwork, ".conflist") {
|
||||
confList, err := libcni.ConfListFromFile(multusConf.ClusterNetwork)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load CNI conflist from %s: %w", multusConf.ClusterNetwork, err)
|
||||
}
|
||||
isconflist = true
|
||||
defaultConfBytes = confList.Bytes
|
||||
} else {
|
||||
conf, err := libcni.ConfFromFile(multusConf.ClusterNetwork)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load CNI config from %s: %w", multusConf.ClusterNetwork, err)
|
||||
}
|
||||
if conf.Network.Type == "" {
|
||||
return nil, fmt.Errorf("CNI config in %s missing type field", multusConf.ClusterNetwork)
|
||||
}
|
||||
defaultConfBytes = conf.Bytes
|
||||
}
|
||||
|
||||
// Create and append the default delegate
|
||||
defaultDelegate, err := types.LoadDelegateNetConf(defaultConfBytes, nil, "", "")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load delegate from default CNI config: %w", err)
|
||||
}
|
||||
defaultDelegate.MasterPlugin = true
|
||||
defaultDelegate.ConfListPlugin = isconflist
|
||||
delegates = append(delegates, defaultDelegate)
|
||||
|
||||
// --- Add the user-defined network attachments ---
|
||||
parsedNets, err := multusk8sutils.ParsePodNetworkAnnotation(config.Networks, podNamespace)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse networks string: %w", err)
|
||||
}
|
||||
|
||||
var delegates []*types.DelegateNetConf
|
||||
|
||||
for _, net := range parsedNets {
|
||||
nad, err := s.nadClient.K8sCniCncfIoV1().NetworkAttachmentDefinitions(net.Namespace).Get(context.TODO(), net.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch NAD %s/%s: %w", net.Namespace, net.Name, err)
|
||||
}
|
||||
|
||||
klog.Infof("!bang: Whole net-attach-def: %+v", nad)
|
||||
|
||||
delegate, err := multustypes.LoadDelegateNetConf([]byte(nad.Spec.Config), net, "", "")
|
||||
delegate, err := types.LoadDelegateNetConf([]byte(nad.Spec.Config), net, "", "")
|
||||
if err != nil {
|
||||
// Handle error loading delegate
|
||||
return nil, fmt.Errorf("failed to load delegate netconf from NAD %s/%s: %w", net.Namespace, net.Name, err)
|
||||
}
|
||||
|
||||
// Preserve ifname from network selection
|
||||
if net.InterfaceRequest != "" {
|
||||
delegate.IfnameRequest = net.InterfaceRequest
|
||||
}
|
||||
|
||||
delegates = append(delegates, delegate)
|
||||
}
|
||||
|
||||
klog.Infof("Delegate information for pod %s/%s: %+v", podNamespace, podName, delegates)
|
||||
|
||||
// Save delegates to a file
|
||||
delegatesPath := filepath.Join("/run/k8s.cni.cncf.io/dra", fmt.Sprintf("%s_%s.json", podNamespace, podName))
|
||||
if err := os.MkdirAll(filepath.Dir(delegatesPath), 0755); err != nil {
|
||||
|
@@ -97,6 +97,8 @@ spec:
|
||||
mountPath: /var/run/cdi
|
||||
- name: host-run-k8s-cni-cncf-io
|
||||
mountPath: /run/k8s.cni.cncf.io
|
||||
- name: cni
|
||||
mountPath: /host/etc/cni/net.d
|
||||
volumes:
|
||||
- name: plugins-registry
|
||||
hostPath:
|
||||
@@ -110,4 +112,7 @@ spec:
|
||||
- name: host-run-k8s-cni-cncf-io
|
||||
hostPath:
|
||||
path: /run/k8s.cni.cncf.io
|
||||
- name: cni
|
||||
hostPath:
|
||||
path: /etc/cni/net.d
|
||||
|
||||
|
@@ -110,9 +110,9 @@ type DelegateNetConf struct {
|
||||
IsFilterV4Gateway bool
|
||||
IsFilterV6Gateway bool
|
||||
// MasterPlugin is only used internal housekeeping
|
||||
MasterPlugin bool `json:"-"`
|
||||
MasterPlugin bool `json:"masterPlugin"`
|
||||
// Conflist plugin is only used internal housekeeping
|
||||
ConfListPlugin bool `json:"-"`
|
||||
ConfListPlugin bool `json:"confListPlugin"`
|
||||
// DeviceID is only used internal housekeeping
|
||||
DeviceID string `json:"deviceID,omitempty"`
|
||||
// ResourceName is only used internal housekeeping
|
||||
|
Reference in New Issue
Block a user