Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move to v1.2.3 and add namespace watcher #186

Merged
merged 3 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build_push_concheck.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ name: Build and push connection check image
on:
push:
branches:
- v1.2.0
- v1.2.3
paths:
- connection-check/**

env:
IMAGE_VERSION: '1.2.0'
IMAGE_VERSION: '1.2.3'
IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }}

jobs:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build_push_controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Build and push controller and its bundle image
on:
push:
branches:
- v1.2.0
- v1.2.3
paths:
- controllers/**
- compute/**
Expand All @@ -16,7 +16,7 @@ on:
- ./Makefile

env:
VERSION: '1.2.0'
VERSION: '1.2.3'
IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }}
DAEMON_REGISTRY: ghcr.io/${{ github.repository_owner }}

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build_push_daemon.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ name: Build and push daemon image
on:
push:
branches:
- v1.2.0
- v1.2.3
paths:
- daemon/**
- cni/**
- Makefile

env:
IMAGE_VERSION: '1.2.0'
IMAGE_VERSION: '1.2.3'
DAEMON_REGISTRY: ghcr.io/${{ github.repository_owner }}

jobs:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/daemon_unittest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Perform unittest for daemon
on:
pull_request:
branches:
- v1.2.0
- v1.2.3
push:
paths:
- daemon/**
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/integration_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: e2e test
on:
pull_request:
branches:
- v1.2.0
- v1.2.3
push:
paths:
- controllers/**
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/unittest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Perform unittest for controller
on:
pull_request:
branches:
- v1.2.0
- v1.2.3
push:
paths:
- controllers/**
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ endif
# - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2)
# - use environment variables to overwrite this value (e.g export VERSION=0.0.2)
# VERSION ?= 0.0.1
VERSION ?= 1.2.0
VERSION ?= 1.2.3
export CHANNELS = "beta"

# CHANNELS define the bundle channels used in the bundle.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ Recommended to deploy in the same default namespace for [health check service](.
```
##### by bundle with operator-sdk
```bash
operator-sdk run bundle ghcr.io/foundation-model-stack/multi-nic-cni-bundle:v1.2.0 -n multi-nic-cni-operator
operator-sdk run bundle ghcr.io/foundation-model-stack/multi-nic-cni-bundle:v1.2.3 -n multi-nic-cni-operator
```
#### Deploy MultiNicNetwork resource
1. Prepare `network.yaml` as shown in the [example](#multinicnetwork)
Expand Down
13 changes: 5 additions & 8 deletions api/v1/hostinterface_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,13 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.

type InterfaceInfoType struct {
InterfaceName string `json:"interfaceName"`
NetAddress string `json:"netAddress"`
HostIP string `json:"hostIP"`
Vendor string `json:"vendor"`
Product string `json:"product"`
PciAddress string `json:"pciAddress"`
NetAddress string `json:"netAddress,omitempty"`
HostIP string `json:"hostIP,omitempty"`
Vendor string `json:"vendor,omitempty"`
Product string `json:"product,omitempty"`
PciAddress string `json:"pciAddress,omitempty"`
}

func (i InterfaceInfoType) Equal(cmp InterfaceInfoType) bool {
Expand Down
5 changes: 0 additions & 5 deletions config/crd/bases/multinic.fms.io_hostinterfaces.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,7 @@ spec:
vendor:
type: string
required:
- hostIP
- interfaceName
- netAddress
- pciAddress
- product
- vendor
type: object
type: array
required:
Expand Down
2 changes: 1 addition & 1 deletion config/manager/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ kind: Kustomization
images:
- name: controller
newName: ghcr.io/foundation-model-stack/multi-nic-cni-controller
newTag: v1.2.0
newTag: v1.2.3
2 changes: 2 additions & 0 deletions config/manager/manager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ spec:
replicas: 1
template:
metadata:
annotations:
kubectl.kubernetes.io/default-container: manager
labels:
control-plane: controller-manager
spec:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,4 @@ spec:
provider:
name: Foundation Model Stack
version: 0.0.0
replaces: multi-nic-cni-operator.v1.1.0
replaces: multi-nic-cni-operator.v1.2.0
2 changes: 1 addition & 1 deletion config/samples/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ spec:
value: "11000"
- name: RT_TABLE_PATH
value: /opt/rt_tables
image: ghcr.io/foundation-model-stack/multi-nic-cni-daemon:v1.2.0
image: ghcr.io/foundation-model-stack/multi-nic-cni-daemon:v1.2.3
imagePullPolicy: Always
mounts:
- hostpath: /var/lib/cni/bin
Expand Down
2 changes: 1 addition & 1 deletion config/samples/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ kind: Kustomization
images:
- name: multi-nic-cni-daemon
newName: ghcr.io/foundation-model-stack/multi-nic-cni-daemon
newTag: v1.2.0
newTag: v1.2.3
2 changes: 1 addition & 1 deletion connection-check/concheck.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ spec:
serviceAccountName: multi-nic-concheck-account
containers:
- name: concheck
image: ghcr.io/foundation-model-stack/multi-nic-cni-concheck:v1.2.0
image: ghcr.io/foundation-model-stack/multi-nic-cni-concheck:v1.2.3
imagePullPolicy: Always
securityContext:
privileged: true
36 changes: 30 additions & 6 deletions controllers/multinicnetwork_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,6 @@ func (r *MultiNicNetworkReconciler) Reconcile(ctx context.Context, req ctrl.Requ
instance.Status.DiscoverStatus.ExistDaemon = daemonSize
instance.Status.InterfaceInfoAvailable = infoAvailableSize

// Get main plugin
mainPlugin, annotations, err := r.GetMainPluginConf(instance)
multinicnetworkName := instance.GetName()
if err != nil {
message := fmt.Sprintf("Failed to get main config %s: %v", multinicnetworkName, err)
Expand All @@ -143,10 +141,7 @@ func (r *MultiNicNetworkReconciler) Reconcile(ctx context.Context, req ctrl.Requ
}
vars.NetworkLog.V(2).Info(message)
} else {
mainPlugin = plugin.RemoveEmpty(instance.Spec.MainPlugin.CNIArgs, mainPlugin)
vars.NetworkLog.V(2).Info(fmt.Sprintf("main plugin: %s", mainPlugin))
// Create net attach def
err = r.NetAttachDefHandler.CreateOrUpdate(instance, mainPlugin, annotations)
err = r.GenerateNetAttachDef(instance)
if err != nil {
message := fmt.Sprintf("Failed to create %s: %v", multinicnetworkName, err)
err = r.CIDRHandler.MultiNicNetworkHandler.UpdateNetConfigStatus(instance, multinicv1.ConfigFailed, message)
Expand Down Expand Up @@ -204,6 +199,18 @@ func (r *MultiNicNetworkReconciler) Reconcile(ctx context.Context, req ctrl.Requ
return ctrl.Result{}, nil
}

func (r *MultiNicNetworkReconciler) GenerateNetAttachDef(instance *multinicv1.MultiNicNetwork) error {
// Get main plugin
mainPlugin, annotations, err := r.GetMainPluginConf(instance)
if err == nil {
mainPlugin = plugin.RemoveEmpty(instance.Spec.MainPlugin.CNIArgs, mainPlugin)
vars.NetworkLog.V(2).Info(fmt.Sprintf("main plugin: %s", mainPlugin))
// Create net attach def
err = r.NetAttachDefHandler.CreateOrUpdate(instance, mainPlugin, annotations)
}
return err
}

func (r *MultiNicNetworkReconciler) GetMainPluginConf(instance *multinicv1.MultiNicNetwork) (string, map[string]string, error) {
spec := instance.Spec.MainPlugin
if p, exist := r.PluginMap[spec.Type]; exist {
Expand Down Expand Up @@ -291,3 +298,20 @@ func (r *MultiNicNetworkReconciler) callFinalizer(reqLogger logr.Logger, instanc
r.CIDRHandler.MultiNicNetworkHandler.SafeCache.UnsetCache(instance.Name)
return nil
}

// HandleNewNamespace handles new namespace
// - generate NAD
func (r *MultiNicNetworkReconciler) HandleNewNamespace(namespace string) {
multinicnetworks := r.CIDRHandler.MultiNicNetworkHandler.FilterNetworksByNamespace(namespace)
for _, net := range multinicnetworks {
// Get main plugin
mainPlugin, annotations, err := r.GetMainPluginConf(&net)
if err == nil {
mainPlugin = plugin.RemoveEmpty(net.Spec.MainPlugin.CNIArgs, mainPlugin)
err = r.NetAttachDefHandler.CreateOrUpdateOnNamespace(namespace, &net, mainPlugin, annotations)
}
if err != nil {
vars.NetworkLog.V(2).Info(fmt.Sprintf("Failed to create networkAttachementDefinition for %s on %s: %v", net.Name, namespace, err))
}
}
}
36 changes: 31 additions & 5 deletions controllers/multinicnetwork_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ func (h *MultiNicNetworkHandler) updateStatus(instance *multinicv1.MultiNicNetwo

if !NetStatusUpdated(instance, netStatus) {
vars.NetworkLog.V(2).Info(fmt.Sprintf("No status update %s", instance.Name))
h.SetCache(instance.Name, *instance)
return netStatus, nil
}

Expand All @@ -126,7 +127,7 @@ func (h *MultiNicNetworkHandler) updateStatus(instance *multinicv1.MultiNicNetwo
if err != nil {
vars.NetworkLog.V(2).Info(fmt.Sprintf("Failed to update %s status: %v", instance.Name, err))
} else {
h.SetStatusCache(instance.Name, instance.Status)
h.SetCache(instance.Name, *instance)
}
return netStatus, err
}
Expand Down Expand Up @@ -171,12 +172,12 @@ func (h *MultiNicNetworkHandler) UpdateNetConfigStatus(instance *multinicv1.Mult
if err != nil {
vars.NetworkLog.V(2).Info(fmt.Sprintf("Failed to update %s status: %v", instance.Name, err))
} else {
h.SetStatusCache(instance.Name, instance.Status)
h.SetCache(instance.Name, *instance)
}
return err
}

func (h *MultiNicNetworkHandler) SetStatusCache(key string, value multinicv1.MultiNicNetworkStatus) {
func (h *MultiNicNetworkHandler) SetCache(key string, value multinicv1.MultiNicNetwork) {
h.SafeCache.SetCache(key, value)
}

Expand All @@ -185,15 +186,40 @@ func (h *MultiNicNetworkHandler) GetStatusCache(key string) (multinicv1.MultiNic
if value == nil {
return multinicv1.MultiNicNetworkStatus{}, fmt.Errorf(vars.NotFoundError)
}
return value.(multinicv1.MultiNicNetworkStatus), nil
return value.(multinicv1.MultiNicNetwork).Status, nil
}

func (h *MultiNicNetworkHandler) ListStatusCache() map[string]multinicv1.MultiNicNetworkStatus {
snapshot := make(map[string]multinicv1.MultiNicNetworkStatus)
h.SafeCache.Lock()
for key, value := range h.cache {
snapshot[key] = value.(multinicv1.MultiNicNetworkStatus)
snapshot[key] = value.(multinicv1.MultiNicNetwork).Status
}
h.SafeCache.Unlock()
return snapshot
}

func (h *MultiNicNetworkHandler) FilterNetworksByNamespace(target string) []multinicv1.MultiNicNetwork {
filteredNetworks := []multinicv1.MultiNicNetwork{}
h.SafeCache.Lock()
for _, value := range h.cache {
net := value.(multinicv1.MultiNicNetwork)
namespaces := net.Spec.Namespaces
if len(namespaces) == 0 {
vars.NetworkLog.V(2).Info(fmt.Sprintf("FilterNetworksByNamespace %s has no namespace set", net.Name))
// NOTE: if namespace list is not specified, append
filteredNetworks = append(filteredNetworks, net)
} else {
vars.NetworkLog.V(2).Info(fmt.Sprintf("FilterNetworksByNamespace %s set %v", net.Name, namespaces))
// NOTE: if namespace list is specified and target is in the list, append
for _, ns := range namespaces {
if ns == target {
filteredNetworks = append(filteredNetworks, net)
break
}
}
}
}
h.SafeCache.Unlock()
return filteredNetworks
}
59 changes: 59 additions & 0 deletions controllers/namespace_watcher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright 2022- IBM Inc. All rights reserved
* SPDX-License-Identifier: Apache2.0
*/

package controllers

import (
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache"
"sigs.k8s.io/controller-runtime/pkg/client"
)

// NamespaceWatcher watches new namespace and generate net-attach-def
type NamespaceWatcher struct {
*kubernetes.Clientset
NamespaceQueue chan string
Quit chan struct{}
*MultiNicNetworkReconciler
}

// NewNamespaceWatcher creates new namespace watcher
func NewNamespaceWatcher(client client.Client, config *rest.Config, multinicnetworkReconciler *MultiNicNetworkReconciler, quit chan struct{}) *NamespaceWatcher {
clientset, _ := kubernetes.NewForConfig(config)
watcher := &NamespaceWatcher{
Clientset: clientset,
NamespaceQueue: make(chan string),
Quit: quit,
MultiNicNetworkReconciler: multinicnetworkReconciler,
}
factory := informers.NewSharedInformerFactory(clientset, 0)
nsInformer := factory.Core().V1().Namespaces()

nsInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
if ns, ok := obj.(*v1.Namespace); ok {
watcher.NamespaceQueue <- ns.Name
}
},
})
factory.Start(watcher.Quit)

return watcher
}

// Run executes namespace watcher routine until get quit signal
func (w *NamespaceWatcher) Run() {
defer close(w.NamespaceQueue)
wait.Until(w.ProcessNamespaceQueue, 0, w.Quit)
}

func (w *NamespaceWatcher) ProcessNamespaceQueue() {
ns := <-w.NamespaceQueue
w.MultiNicNetworkReconciler.HandleNewNamespace(ns)
}
4 changes: 3 additions & 1 deletion controllers/vars/vars.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const (
DefaultOperatorNamespace = "multi-nic-cni-operator"
DefaultCNIType = "multi-nic"
DefaultIPAMType = "multi-nic-ipam"
DefaultDaemonImage = "ghcr.io/foundation-model-stack/multi-nic-cni-daemon:v1.2.0"
DefaultDaemonImage = "ghcr.io/foundation-model-stack/multi-nic-cni-daemon:v1.2.3"
DefaultJoinPath = "/join"
DefaultInterfacePath = "/interface"
DefaultAddRoutePath = "/addl3"
Expand Down Expand Up @@ -77,6 +77,7 @@ var (

// logger options to change log level on the fly
ZapOpts *zap.Options
SetupLog logr.Logger
DaemonLog logr.Logger
DefLog logr.Logger
CIDRLog logr.Logger
Expand All @@ -103,6 +104,7 @@ func SetLog() {
zapp := zap.New(zap.UseFlagOptions(ZapOpts))
dlog := logf.NewDelegatingLogSink(zapp.GetSink())
ctrl.Log = logr.New(dlog)
SetupLog = ctrl.Log.WithName("setup")
DaemonLog = ctrl.Log.WithName("controllers").WithName("Daemon")
DefLog = ctrl.Log.WithName("controllers").WithName("NetAttachDef")
CIDRLog = ctrl.Log.WithName("controllers").WithName("CIDR")
Expand Down
Loading
Loading