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

reduce unnecessary update and add context deadline to API server call #172

Merged
merged 3 commits into from
Jan 15, 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
12 changes: 9 additions & 3 deletions controllers/cidr_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,9 @@ func (h *CIDRHandler) DeleteCIDR(cidr multinicv1.CIDR) error {
}
instance, err := h.GetCIDR(name)
if err == nil {
err = h.Client.Delete(context.Background(), instance)
ctx, cancel := context.WithTimeout(context.Background(), vars.ContextTimeout)
defer cancel()
err = h.Client.Delete(ctx, instance)
}
if err != nil {
errorMsg = errorMsg + fmt.Sprintf("%v,", err)
Expand Down Expand Up @@ -525,14 +527,18 @@ func (h *CIDRHandler) updateCIDR(cidrSpec multinicv1.CIDRSpec, new bool) (bool,
if err == nil {
updatedCIDR := existCIDR.DeepCopy()
updatedCIDR.Spec = spec
err = h.Client.Update(context.TODO(), updatedCIDR)
ctx, cancel := context.WithTimeout(context.Background(), vars.ContextTimeout)
defer cancel()
err = h.Client.Update(ctx, updatedCIDR)
if err == nil {
h.SafeCache.SetCache(def.Name, updatedCIDR.Spec)
}
h.CleanPendingIPPools(ippoolSnapshot, def.Name, updatedCIDR.Spec)
} else {
if new {
err = h.Client.Create(context.TODO(), mapObj)
ctx, cancel := context.WithTimeout(context.Background(), vars.ContextTimeout)
defer cancel()
err = h.Client.Create(ctx, mapObj)
if err == nil {
h.SafeCache.SetCache(def.Name, mapObj.Spec)
}
Expand Down
16 changes: 12 additions & 4 deletions controllers/hostinterface_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ func (h *HostInterfaceHandler) initHostInterface(hostName string, interfaces []m
// CreateHostInterface creates new HostInterface from an interface list get from daemon pods
func (h *HostInterfaceHandler) CreateHostInterface(hostName string, interfaces []multinicv1.InterfaceInfoType) error {
newHif := h.initHostInterface(hostName, interfaces)
return h.Client.Create(context.TODO(), newHif)
ctx, cancel := context.WithTimeout(context.Background(), vars.ContextTimeout)
defer cancel()
return h.Client.Create(ctx, newHif)
}

// UpdateHostInterface updates HostInterface
Expand All @@ -73,7 +75,9 @@ func (h *HostInterfaceHandler) UpdateHostInterface(oldObj multinicv1.HostInterfa
Interfaces: interfaces,
},
}
return updateHif, h.Client.Update(context.TODO(), updateHif)
ctx, cancel := context.WithTimeout(context.Background(), vars.ContextTimeout)
defer cancel()
return updateHif, h.Client.Update(ctx, updateHif)
}

// GetHostInterface gets HostInterface from hostname
Expand All @@ -83,7 +87,9 @@ func (h *HostInterfaceHandler) GetHostInterface(name string) (*multinicv1.HostIn
Name: name,
Namespace: metav1.NamespaceAll,
}
err := h.Client.Get(context.TODO(), namespacedName, instance)
ctx, cancel := context.WithTimeout(context.Background(), vars.ContextTimeout)
defer cancel()
err := h.Client.Get(ctx, namespacedName, instance)
return instance, err
}

Expand All @@ -107,7 +113,9 @@ func (h *HostInterfaceHandler) ListHostInterface() (map[string]multinicv1.HostIn
func (h *HostInterfaceHandler) DeleteHostInterface(name string) error {
instance, err := h.GetHostInterface(name)
if err == nil {
err = h.Client.Delete(context.TODO(), instance)
ctx, cancel := context.WithTimeout(context.Background(), vars.ContextTimeout)
defer cancel()
err = h.Client.Delete(ctx, instance)
}
return err
}
Expand Down
20 changes: 15 additions & 5 deletions controllers/ippool_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ func (h *IPPoolHandler) DeleteIPPool(netAttachDef string, podCIDR string) error
name := h.GetIPPoolName(netAttachDef, podCIDR)
instance, err := h.GetIPPool(name)
if err == nil {
err = h.Client.Delete(context.TODO(), instance)
ctx, cancel := context.WithTimeout(context.Background(), vars.ContextTimeout)
defer cancel()
err = h.Client.Delete(ctx, instance)
}
return err
}
Expand Down Expand Up @@ -132,7 +134,9 @@ func (h *IPPoolHandler) UpdateIPPool(netAttachDef string, podCIDR string, vlanCI
ippool.Spec = spec
ippool.Spec.Allocations = prevSpec.Allocations
ippool.ObjectMeta.Labels = labels
err = h.Client.Update(context.TODO(), ippool)
ctx, cancel := context.WithTimeout(context.Background(), vars.ContextTimeout)
defer cancel()
err = h.Client.Update(ctx, ippool)
if !reflect.DeepEqual(prevSpec.Excludes, excludesInterface) {
// report if allocated ip addresses have conflicts with the new IPPool (for example, in exclude list)
invalidAllocations := h.checkPoolValidity(excludesInterface, prevSpec.Allocations)
Expand All @@ -154,7 +158,9 @@ func (h *IPPoolHandler) UpdateIPPool(netAttachDef string, podCIDR string, vlanCI
},
Spec: spec,
}
err = h.Client.Create(context.Background(), newIPPool)
ctx, cancel := context.WithTimeout(context.Background(), vars.ContextTimeout)
defer cancel()
err = h.Client.Create(ctx, newIPPool)
vars.IPPoolLog.V(5).Info(fmt.Sprintf("New IPPool %s: %v, %v", ippoolName, newIPPool, err))
}
return err
Expand Down Expand Up @@ -192,7 +198,9 @@ func (h *IPPoolHandler) PatchIPPoolAllocations(ippoolName string, newAllocations
}
patch := client.MergeFrom(ippool.DeepCopy())
ippool.Spec.Allocations = newAllocations
return h.Client.Patch(context.Background(), ippool, patch)
ctx, cancel := context.WithTimeout(context.Background(), vars.ContextTimeout)
defer cancel()
return h.Client.Patch(ctx, ippool, patch)
}

func (h *IPPoolHandler) UpdateIPPools(defName string, entries []multinicv1.CIDREntry, excludes []compute.IPValue) {
Expand Down Expand Up @@ -234,6 +242,8 @@ func (h *IPPoolHandler) AddLabel(ippool *multinicv1.IPPool) error {
labels := map[string]string{vars.HostNameLabel: hostName, vars.DefNameLabel: netAttachDef}
patch := client.MergeFrom(ippool.DeepCopy())
ippool.ObjectMeta.Labels = labels
err := h.Client.Patch(context.Background(), ippool, patch)
ctx, cancel := context.WithTimeout(context.Background(), vars.ContextTimeout)
defer cancel()
err := h.Client.Patch(ctx, ippool, patch)
return err
}
40 changes: 37 additions & 3 deletions controllers/multinicnetwork_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ func (h *MultiNicNetworkHandler) GetNetwork(name string) (*multinicv1.MultiNicNe
Name: name,
Namespace: metav1.NamespaceAll,
}
err := h.Client.Get(context.TODO(), namespacedName, instance)
ctx, cancel := context.WithTimeout(context.Background(), vars.ContextTimeout)
defer cancel()
err := h.Client.Get(ctx, namespacedName, instance)
return instance, err
}

Expand Down Expand Up @@ -111,8 +113,16 @@ func (h *MultiNicNetworkHandler) updateStatus(instance *multinicv1.MultiNicNetwo
RouteStatus: status,
}

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

vars.NetworkLog.V(2).Info(fmt.Sprintf("Update %s status", instance.Name))
instance.Status = netStatus
err := h.Client.Status().Update(context.Background(), instance)
ctx, cancel := context.WithTimeout(context.Background(), vars.ContextTimeout)
defer cancel()
err := h.Client.Status().Update(ctx, instance)
if err != nil {
vars.NetworkLog.V(2).Info(fmt.Sprintf("Failed to update %s status: %v", instance.Name, err))
} else {
Expand All @@ -121,6 +131,28 @@ func (h *MultiNicNetworkHandler) updateStatus(instance *multinicv1.MultiNicNetwo
return netStatus, err
}

func NetStatusUpdated(instance *multinicv1.MultiNicNetwork, newStatus multinicv1.MultiNicNetworkStatus) bool {
prevStatus := instance.Status
if prevStatus.Message != newStatus.Message || prevStatus.RouteStatus != newStatus.RouteStatus || prevStatus.NetConfigStatus != newStatus.NetConfigStatus || prevStatus.DiscoverStatus != newStatus.DiscoverStatus {
return true
}
if len(prevStatus.ComputeResults) != len(newStatus.ComputeResults) {
return true
}
prevComputeMap := make(map[string]int)
for _, status := range prevStatus.ComputeResults {
prevComputeMap[status.NetAddress] = status.NumOfHost
}
for _, status := range newStatus.ComputeResults {
if numOfHost, found := prevComputeMap[status.NetAddress]; !found {
return true
} else if numOfHost != status.NumOfHost {
return true
}
}
return false
}

func (h *MultiNicNetworkHandler) UpdateNetConfigStatus(instance *multinicv1.MultiNicNetwork, netConfigStatus multinicv1.NetConfigStatus, message string) error {
if message != "" {
instance.Status.Message = message
Expand All @@ -129,7 +161,9 @@ func (h *MultiNicNetworkHandler) UpdateNetConfigStatus(instance *multinicv1.Mult
instance.Status.ComputeResults = []multinicv1.NicNetworkResult{}
}
instance.Status.NetConfigStatus = netConfigStatus
err := h.Client.Status().Update(context.Background(), instance)
ctx, cancel := context.WithTimeout(context.Background(), vars.ContextTimeout)
defer cancel()
err := h.Client.Status().Update(ctx, instance)
if err != nil {
vars.NetworkLog.V(2).Info(fmt.Sprintf("Failed to update %s status: %v", instance.Name, err))
} else {
Expand Down
25 changes: 18 additions & 7 deletions daemon/src/backend/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import (
)

const (
API_VERSION = "multinic.fms.io/v1"
API_VERSION = "multinic.fms.io/v1"
APISERVER_TIMEOUT = 2 * time.Minute
)

type DynamicHandler struct {
Expand Down Expand Up @@ -71,7 +72,9 @@ func (h *DynamicHandler) Create(mapObj map[string]interface{}, namespace string,
gvr, _ := schema.ParseResourceArg(h.ResourceName)
log.Println(fmt.Sprintf("Create %s/%s", h.ResourceName, mapObj["metadata"].(map[string]interface{})["name"]))
start := time.Now()
res, err := h.DYN.Resource(*gvr).Namespace(namespace).Create(context.TODO(), obj, options)
ctx, cancel := context.WithTimeout(context.Background(), APISERVER_TIMEOUT)
defer cancel()
res, err := h.DYN.Resource(*gvr).Namespace(namespace).Create(ctx, obj, options)
elapsed := time.Since(start)
log.Println(fmt.Sprintf("Create%s elapsed: %d us", h.Kind, int64(elapsed/time.Microsecond)))
return res, err
Expand All @@ -82,7 +85,9 @@ func (h *DynamicHandler) Update(mapObj map[string]interface{}, namespace string,
gvr, _ := schema.ParseResourceArg(h.ResourceName)
log.Println(fmt.Sprintf("Update %s/%s", h.ResourceName, mapObj["metadata"].(map[string]interface{})["name"]))
start := time.Now()
res, err := h.DYN.Resource(*gvr).Namespace(namespace).Update(context.TODO(), obj, options)
ctx, cancel := context.WithTimeout(context.Background(), APISERVER_TIMEOUT)
defer cancel()
res, err := h.DYN.Resource(*gvr).Namespace(namespace).Update(ctx, obj, options)
elapsed := time.Since(start)
log.Println(fmt.Sprintf("Update%s elapsed: %d us", h.Kind, int64(elapsed/time.Microsecond)))
return res, err
Expand All @@ -91,7 +96,7 @@ func (h *DynamicHandler) Update(mapObj map[string]interface{}, namespace string,
func (h *DynamicHandler) List(namespace string, options metav1.ListOptions) (*unstructured.UnstructuredList, error) {
gvr, _ := schema.ParseResourceArg(h.ResourceName)
start := time.Now()
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
ctx, cancel := context.WithTimeout(context.Background(), APISERVER_TIMEOUT)
defer cancel()
res, err := h.DYN.Resource(*gvr).Namespace(namespace).List(ctx, options)
elapsed := time.Since(start)
Expand All @@ -102,7 +107,9 @@ func (h *DynamicHandler) List(namespace string, options metav1.ListOptions) (*un
func (h *DynamicHandler) Get(name string, namespace string, options metav1.GetOptions) (*unstructured.Unstructured, error) {
gvr, _ := schema.ParseResourceArg(h.ResourceName)
start := time.Now()
res, err := h.DYN.Resource(*gvr).Namespace(namespace).Get(context.TODO(), name, options)
ctx, cancel := context.WithTimeout(context.Background(), APISERVER_TIMEOUT)
defer cancel()
res, err := h.DYN.Resource(*gvr).Namespace(namespace).Get(ctx, name, options)
elapsed := time.Since(start)
log.Println(fmt.Sprintf("Get%s elapsed: %d us", h.Kind, int64(elapsed/time.Microsecond)))
return res, err
Expand All @@ -112,7 +119,9 @@ func (h *DynamicHandler) Delete(name string, namespace string, options metav1.De
gvr, _ := schema.ParseResourceArg(h.ResourceName)
log.Println(fmt.Sprintf("Delete %s/%s", h.ResourceName, name))
start := time.Now()
err := h.DYN.Resource(*gvr).Namespace(namespace).Delete(context.TODO(), name, options)
ctx, cancel := context.WithTimeout(context.Background(), APISERVER_TIMEOUT)
defer cancel()
err := h.DYN.Resource(*gvr).Namespace(namespace).Delete(ctx, name, options)
elapsed := time.Since(start)
log.Println(fmt.Sprintf("Delete%s elapsed: %d us", h.Kind, int64(elapsed/time.Microsecond)))
return err
Expand All @@ -122,7 +131,9 @@ func (h *DynamicHandler) Patch(name string, namespace string, pt types.PatchType
gvr, _ := schema.ParseResourceArg(h.ResourceName)
log.Println(fmt.Sprintf("Patch %s/%s - %s", h.ResourceName, name, string(data)))
start := time.Now()
res, err := h.DYN.Resource(*gvr).Namespace(namespace).Patch(context.TODO(), name, pt, data, options)
ctx, cancel := context.WithTimeout(context.Background(), APISERVER_TIMEOUT)
defer cancel()
res, err := h.DYN.Resource(*gvr).Namespace(namespace).Patch(ctx, name, pt, data, options)
elapsed := time.Since(start)
log.Println(fmt.Sprintf("Patch%s elapsed: %d us", h.Kind, int64(elapsed/time.Microsecond)))
return res, err
Expand Down
87 changes: 56 additions & 31 deletions plugin/net_attach_def.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,18 @@ func GetNetAttachDefHandler(config *rest.Config) (*NetAttachDefHandler, error) {
}, nil
}

func CheckDefChanged(def, existingDef *NetworkAttachmentDefinition) bool {
if def.Spec.Config != existingDef.Spec.Config || len(def.Annotations) != len(existingDef.Annotations) {
return true
}
for k, v := range existingDef.Annotations {
if def.Annotations[k] != v {
return true
}
}
return false
}

// CreateOrUpdate creates new NetworkAttachmentDefinition resource if not exists, otherwise update
func (h *NetAttachDefHandler) CreateOrUpdate(net *multinicv1.MultiNicNetwork, pluginStr string, annotations map[string]string) error {
defs, err := h.generate(net, pluginStr, annotations)
Expand All @@ -122,9 +134,14 @@ func (h *NetAttachDefHandler) CreateOrUpdate(net *multinicv1.MultiNicNetwork, pl
if h.IsExist(name, namespace) {
existingDef, _ := h.Get(name, namespace)
def.ObjectMeta = existingDef.ObjectMeta
err := h.DynamicHandler.Update(namespace, def, result)
if err != nil {
errMsg = fmt.Sprintf("%s\n%s: %v", errMsg, namespace, err)
if CheckDefChanged(def, existingDef) {
if namespace == "default" {
vars.NetworkLog.V(2).Info(fmt.Sprintf("Update net-attach-def %s", def.Name))
}
err := h.DynamicHandler.Update(namespace, def, result)
if err != nil {
errMsg = fmt.Sprintf("%s\n%s: %v", errMsg, namespace, err)
}
}
} else {
err := h.DynamicHandler.Create(namespace, def, result)
Expand Down Expand Up @@ -159,6 +176,40 @@ func (h *NetAttachDefHandler) getNamespace(net *multinicv1.MultiNicNetwork) ([]s
return namespaces, nil
}

// NetToDef generates net-attach-def from multinicnetwork on specific namespace called by generate function
func NetToDef(namespace string, net *multinicv1.MultiNicNetwork, pluginStr string, annotations map[string]string) (*NetworkAttachmentDefinition, error) {
name := net.GetName()
config := &NetConf{
NetConf: types.NetConf{
CNIVersion: CNI_VERSION,
Name: name,
Type: vars.TargetCNI,
},
Subnet: net.Spec.Subnet,
MasterNetAddrs: net.Spec.MasterNetAddrs,
IsMultiNICIPAM: net.Spec.IsMultiNICIPAM,
DaemonPort: vars.DaemonPort,
}
var ipamObj map[string]interface{}
configBytes, _ := json.Marshal(config)
configStr := string(configBytes)
err := json.Unmarshal([]byte(net.Spec.IPAM), &ipamObj)
if err != nil {
return nil, err
}
ipamBytes, _ := json.Marshal(ipamObj)
pluginValue := fmt.Sprintf("\"plugin\":%s", pluginStr)
ipamValue := fmt.Sprintf("\"ipam\":%s", string(ipamBytes))
configStr = strings.ReplaceAll(configStr, "\"ipam\":{}", ipamValue)
configStr = strings.ReplaceAll(configStr, "\"plugin\":null", pluginValue)
metaObj := GetMetaObject(name, namespace, annotations)
spec := NetworkAttachmentDefinitionSpec{
Config: configStr,
}
netattachdef := NewNetworkAttachmentDefinition(metaObj, spec)
return &netattachdef, nil
}

// generate initializes NetworkAttachmentDefinition objects from MultiNicNetwork and unmarshal plugin
func (h *NetAttachDefHandler) generate(net *multinicv1.MultiNicNetwork, pluginStr string, annotations map[string]string) ([]*NetworkAttachmentDefinition, error) {
defs := []*NetworkAttachmentDefinition{}
Expand All @@ -168,37 +219,11 @@ func (h *NetAttachDefHandler) generate(net *multinicv1.MultiNicNetwork, pluginSt
}
vars.NetworkLog.V(2).Info(fmt.Sprintf("generate net-attach-def config on %d namespaces", len(namespaces)))
for _, ns := range namespaces {
name := net.GetName()
namespace := ns
config := &NetConf{
NetConf: types.NetConf{
CNIVersion: CNI_VERSION,
Name: name,
Type: vars.TargetCNI,
},
Subnet: net.Spec.Subnet,
MasterNetAddrs: net.Spec.MasterNetAddrs,
IsMultiNICIPAM: net.Spec.IsMultiNICIPAM,
DaemonPort: vars.DaemonPort,
}
var ipamObj map[string]interface{}
configBytes, _ := json.Marshal(config)
configStr := string(configBytes)
err := json.Unmarshal([]byte(net.Spec.IPAM), &ipamObj)
def, err := NetToDef(ns, net, pluginStr, annotations)
if err != nil {
return defs, err
}
ipamBytes, _ := json.Marshal(ipamObj)
pluginValue := fmt.Sprintf("\"plugin\":%s", pluginStr)
ipamValue := fmt.Sprintf("\"ipam\":%s", string(ipamBytes))
configStr = strings.ReplaceAll(configStr, "\"ipam\":{}", ipamValue)
configStr = strings.ReplaceAll(configStr, "\"plugin\":null", pluginValue)
metaObj := GetMetaObject(name, namespace, annotations)
spec := NetworkAttachmentDefinitionSpec{
Config: configStr,
}
netattachdef := NewNetworkAttachmentDefinition(metaObj, spec)
defs = append(defs, &netattachdef)
defs = append(defs, def)
}
return defs, nil
}
Expand Down
Loading
Loading