Skip to content

Commit 10af98e

Browse files
committed
[kubernetes] Update Kubevirt-CCM
Signed-off-by: Andrei Kvapil <[email protected]>
1 parent 632224a commit 10af98e

5 files changed

Lines changed: 213 additions & 90 deletions

File tree

‎packages/apps/kubernetes/Chart.yaml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ type: application
1616
# This is the chart version. This version number should be incremented each time you make changes
1717
# to the chart and its templates, including the app version.
1818
# Versions are expected to follow Semantic Versioning (https://semver.org/)
19-
version: 0.23.1
19+
version: 0.23.2
2020

2121
# This is the version number of the application being deployed. This version number should be
2222
# incremented each time you make changes to the application. Versions are not expected to

‎packages/apps/kubernetes/images/kubevirt-cloud-provider/Dockerfile‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ ENV GOARCH=$TARGETARCH
88

99
RUN git clone https://github.com/kubevirt/cloud-provider-kubevirt /go/src/kubevirt.io/cloud-provider-kubevirt \
1010
&& cd /go/src/kubevirt.io/cloud-provider-kubevirt \
11-
&& git checkout 443a1fe
11+
&& git checkout a0acf33
1212

1313
WORKDIR /go/src/kubevirt.io/cloud-provider-kubevirt
1414

‎packages/apps/kubernetes/images/kubevirt-cloud-provider/patches/341.diff‎

Lines changed: 67 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ index 74166b5d9..4e744f8de 100644
3737
klog.Infof("Initializing kubevirtEPSController")
3838

3939
diff --git a/pkg/controller/kubevirteps/kubevirteps_controller.go b/pkg/controller/kubevirteps/kubevirteps_controller.go
40-
index 6f6e3d322..b56882c12 100644
40+
index 53388eb8e..b56882c12 100644
4141
--- a/pkg/controller/kubevirteps/kubevirteps_controller.go
4242
+++ b/pkg/controller/kubevirteps/kubevirteps_controller.go
4343
@@ -54,10 +54,10 @@ type Controller struct {
@@ -286,22 +286,6 @@ index 6f6e3d322..b56882c12 100644
286286
for _, eps := range slicesToDelete {
287287
err := c.infraClient.DiscoveryV1().EndpointSlices(eps.Namespace).Delete(context.TODO(), eps.Name, metav1.DeleteOptions{})
288288
if err != nil {
289-
@@ -474,11 +538,11 @@ func (c *Controller) reconcileByAddressType(service *v1.Service, tenantSlices []
290-
// Create the desired port configuration
291-
var desiredPorts []discovery.EndpointPort
292-
293-
- for _, port := range service.Spec.Ports {
294-
+ for i := range service.Spec.Ports {
295-
desiredPorts = append(desiredPorts, discovery.EndpointPort{
296-
- Port: &port.TargetPort.IntVal,
297-
- Protocol: &port.Protocol,
298-
- Name: &port.Name,
299-
+ Port: &service.Spec.Ports[i].TargetPort.IntVal,
300-
+ Protocol: &service.Spec.Ports[i].Protocol,
301-
+ Name: &service.Spec.Ports[i].Name,
302-
})
303-
}
304-
305289
@@ -588,55 +652,114 @@ func ownedBy(endpointSlice *discovery.EndpointSlice, svc *v1.Service) bool {
306290
return false
307291
}
@@ -437,18 +421,10 @@ index 6f6e3d322..b56882c12 100644
437421

438422
return nil
439423
diff --git a/pkg/controller/kubevirteps/kubevirteps_controller_test.go b/pkg/controller/kubevirteps/kubevirteps_controller_test.go
440-
index 1fb86e25f..14d92d340 100644
424+
index 1c97035b4..14d92d340 100644
441425
--- a/pkg/controller/kubevirteps/kubevirteps_controller_test.go
442426
+++ b/pkg/controller/kubevirteps/kubevirteps_controller_test.go
443-
@@ -13,6 +13,7 @@ import (
444-
"k8s.io/apimachinery/pkg/runtime"
445-
"k8s.io/apimachinery/pkg/runtime/schema"
446-
"k8s.io/apimachinery/pkg/util/intstr"
447-
+ "k8s.io/apimachinery/pkg/util/sets"
448-
dfake "k8s.io/client-go/dynamic/fake"
449-
"k8s.io/client-go/kubernetes/fake"
450-
"k8s.io/client-go/testing"
451-
@@ -189,7 +190,7 @@ func setupTestKubevirtEPSController() *testKubevirtEPSController {
427+
@@ -190,7 +190,7 @@ func setupTestKubevirtEPSController() *testKubevirtEPSController {
452428
}: "VirtualMachineInstanceList",
453429
})
454430

@@ -457,83 +433,87 @@ index 1fb86e25f..14d92d340 100644
457433

458434
err := controller.Init()
459435
if err != nil {
460-
@@ -686,5 +687,229 @@ var _ = g.Describe("KubevirtEPSController", g.Ordered, func() {
461-
return false, err
462-
}).Should(BeTrue(), "EndpointSlice in infra cluster should be recreated by the controller after deletion")
463-
})
464-
+
465-
+ g.It("Should correctly handle multiple unique ports in EndpointSlice", func() {
466-
+ // Create a VMI in the infra cluster
467-
+ createAndAssertVMI("worker-0-test", "ip-10-32-5-13", "123.45.67.89")
468-
+
469-
+ // Create an EndpointSlice in the tenant cluster
470-
+ createAndAssertTenantSlice("test-epslice", "tenant-service-name", discoveryv1.AddressTypeIPv4,
471-
+ *createPort("http", 80, v1.ProtocolTCP),
472-
+ []discoveryv1.Endpoint{*createEndpoint("123.45.67.89", "worker-0-test", true, true, false)})
473-
+
436+
@@ -697,51 +697,43 @@ var _ = g.Describe("KubevirtEPSController", g.Ordered, func() {
437+
*createPort("http", 80, v1.ProtocolTCP),
438+
[]discoveryv1.Endpoint{*createEndpoint("123.45.67.89", "worker-0-test", true, true, false)})
439+
440+
- // Define several unique ports for the Service
474441
+ // Define multiple ports for the Service
475-
+ servicePorts := []v1.ServicePort{
476-
+ {
442+
servicePorts := []v1.ServicePort{
443+
{
444+
- Name: "client",
445+
- Protocol: v1.ProtocolTCP,
446+
- Port: 10001,
447+
- TargetPort: intstr.FromInt(30396),
448+
- NodePort: 30396,
449+
- AppProtocol: nil,
477450
+ Name: "client",
478451
+ Protocol: v1.ProtocolTCP,
479452
+ Port: 10001,
480453
+ TargetPort: intstr.FromInt(30396),
481454
+ NodePort: 30396,
482-
+ },
483-
+ {
455+
},
456+
{
457+
- Name: "dashboard",
458+
- Protocol: v1.ProtocolTCP,
459+
- Port: 8265,
460+
- TargetPort: intstr.FromInt(31003),
461+
- NodePort: 31003,
462+
- AppProtocol: nil,
484463
+ Name: "dashboard",
485464
+ Protocol: v1.ProtocolTCP,
486465
+ Port: 8265,
487466
+ TargetPort: intstr.FromInt(31003),
488467
+ NodePort: 31003,
489-
+ },
490-
+ {
468+
},
469+
{
470+
- Name: "metrics",
471+
- Protocol: v1.ProtocolTCP,
472+
- Port: 8080,
473+
- TargetPort: intstr.FromInt(30452),
474+
- NodePort: 30452,
475+
- AppProtocol: nil,
491476
+ Name: "metrics",
492477
+ Protocol: v1.ProtocolTCP,
493478
+ Port: 8080,
494479
+ TargetPort: intstr.FromInt(30452),
495480
+ NodePort: 30452,
496-
+ },
497-
+ }
498-
+
499-
+ createAndAssertInfraServiceLB("infra-multiport-service", "tenant-service-name", "test-cluster",
481+
},
482+
}
483+
484+
- // Create a Service with the first port
485+
createAndAssertInfraServiceLB("infra-multiport-service", "tenant-service-name", "test-cluster",
486+
- servicePorts[0],
487+
- v1.ServiceExternalTrafficPolicyLocal)
500488
+ servicePorts[0], v1.ServiceExternalTrafficPolicyLocal)
501-
+
502-
+ svc, err := testVals.infraClient.CoreV1().Services(infraNamespace).Get(context.TODO(), "infra-multiport-service", metav1.GetOptions{})
503-
+ Expect(err).To(BeNil())
504-
+
505-
+ svc.Spec.Ports = servicePorts
506-
+ _, err = testVals.infraClient.CoreV1().Services(infraNamespace).Update(context.TODO(), svc, metav1.UpdateOptions{})
507-
+ Expect(err).To(BeNil())
508-
+
509-
+ var epsListMultiPort *discoveryv1.EndpointSliceList
510-
+
511-
+ Eventually(func() (bool, error) {
512-
+ epsListMultiPort, err = testVals.infraClient.DiscoveryV1().EndpointSlices(infraNamespace).List(context.TODO(), metav1.ListOptions{})
513-
+ if len(epsListMultiPort.Items) != 1 {
514-
+ return false, err
515-
+ }
516-
+
517-
+ createdSlice := epsListMultiPort.Items[0]
518-
+ expectedPortNames := []string{"client", "dashboard", "metrics"}
519-
+ foundPortNames := []string{}
520-
+
521-
+ for _, port := range createdSlice.Ports {
522-
+ if port.Name != nil {
523-
+ foundPortNames = append(foundPortNames, *port.Name)
524-
+ }
525-
+ }
526-
+
527-
+ if len(foundPortNames) != len(expectedPortNames) {
528-
+ return false, err
529-
+ }
530-
+
531-
+ portSet := sets.NewString(foundPortNames...)
532-
+ expectedPortSet := sets.NewString(expectedPortNames...)
533-
+ return portSet.Equal(expectedPortSet), err
534-
+ }).Should(BeTrue(), "EndpointSlice should contain all unique ports from the Service without duplicates")
535-
+ })
536-
+
489+
490+
- // Update the Service by adding the remaining ports
491+
svc, err := testVals.infraClient.CoreV1().Services(infraNamespace).Get(context.TODO(), "infra-multiport-service", metav1.GetOptions{})
492+
Expect(err).To(BeNil())
493+
494+
svc.Spec.Ports = servicePorts
495+
-
496+
_, err = testVals.infraClient.CoreV1().Services(infraNamespace).Update(context.TODO(), svc, metav1.UpdateOptions{})
497+
Expect(err).To(BeNil())
498+
499+
var epsListMultiPort *discoveryv1.EndpointSliceList
500+
501+
- // Verify that the EndpointSlice is created with correct unique ports
502+
Eventually(func() (bool, error) {
503+
epsListMultiPort, err = testVals.infraClient.DiscoveryV1().EndpointSlices(infraNamespace).List(context.TODO(), metav1.ListOptions{})
504+
if len(epsListMultiPort.Items) != 1 {
505+
@@ -758,7 +750,6 @@ var _ = g.Describe("KubevirtEPSController", g.Ordered, func() {
506+
}
507+
}
508+
509+
- // Verify that all expected ports are present and without duplicates
510+
if len(foundPortNames) != len(expectedPortNames) {
511+
return false, err
512+
}
513+
@@ -769,5 +760,156 @@ var _ = g.Describe("KubevirtEPSController", g.Ordered, func() {
514+
}).Should(BeTrue(), "EndpointSlice should contain all unique ports from the Service without duplicates")
515+
})
516+
537517
+ g.It("Should not panic when Service changes to have a non-nil selector, causing EndpointSlice deletion with no new slices to create", func() {
538518
+ createAndAssertVMI("worker-0-test", "ip-10-32-5-13", "123.45.67.89")
539519
+ createAndAssertTenantSlice("test-epslice", "tenant-service-name", discoveryv1.AddressTypeIPv4,
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
diff --git a/pkg/controller/kubevirteps/kubevirteps_controller.go b/pkg/controller/kubevirteps/kubevirteps_controller.go
2+
index 53388eb8e..28644236f 100644
3+
--- a/pkg/controller/kubevirteps/kubevirteps_controller.go
4+
+++ b/pkg/controller/kubevirteps/kubevirteps_controller.go
5+
@@ -12,7 +12,6 @@ import (
6+
apiequality "k8s.io/apimachinery/pkg/api/equality"
7+
k8serrors "k8s.io/apimachinery/pkg/api/errors"
8+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
- "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
10+
"k8s.io/apimachinery/pkg/runtime"
11+
"k8s.io/apimachinery/pkg/runtime/schema"
12+
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
13+
@@ -669,35 +668,50 @@ func (c *Controller) getDesiredEndpoints(service *v1.Service, tenantSlices []*di
14+
for _, slice := range tenantSlices {
15+
for _, endpoint := range slice.Endpoints {
16+
// find all unique nodes that correspond to an endpoint in a tenant slice
17+
+ if endpoint.NodeName == nil {
18+
+ klog.Warningf("Skipping endpoint without NodeName in slice %s/%s", slice.Namespace, slice.Name)
19+
+ continue
20+
+ }
21+
nodeSet.Insert(*endpoint.NodeName)
22+
}
23+
}
24+
25+
- klog.Infof("Desired nodes for service %s in namespace %s: %v", service.Name, service.Namespace, sets.List(nodeSet))
26+
+ klog.Infof("Desired nodes for service %s/%s: %v", service.Namespace, service.Name, sets.List(nodeSet))
27+
28+
for _, node := range sets.List(nodeSet) {
29+
// find vmi for node name
30+
- obj := &unstructured.Unstructured{}
31+
- vmi := &kubevirtv1.VirtualMachineInstance{}
32+
-
33+
- obj, err := c.infraDynamic.Resource(kubevirtv1.VirtualMachineInstanceGroupVersionKind.GroupVersion().WithResource("virtualmachineinstances")).Namespace(c.infraNamespace).Get(context.TODO(), node, metav1.GetOptions{})
34+
+ obj, err := c.infraDynamic.
35+
+ Resource(kubevirtv1.VirtualMachineInstanceGroupVersionKind.GroupVersion().WithResource("virtualmachineinstances")).
36+
+ Namespace(c.infraNamespace).
37+
+ Get(context.TODO(), node, metav1.GetOptions{})
38+
if err != nil {
39+
- klog.Errorf("Failed to get VirtualMachineInstance %s in namespace %s:%v", node, c.infraNamespace, err)
40+
+ klog.Errorf("Failed to get VMI %q in namespace %q: %v", node, c.infraNamespace, err)
41+
continue
42+
}
43+
44+
+ vmi := &kubevirtv1.VirtualMachineInstance{}
45+
err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, vmi)
46+
if err != nil {
47+
klog.Errorf("Failed to convert Unstructured to VirtualMachineInstance: %v", err)
48+
- klog.Fatal(err)
49+
+ continue
50+
}
51+
52+
+ if vmi.Status.NodeName == "" {
53+
+ klog.Warningf("Skipping VMI %s/%s: NodeName is empty", vmi.Namespace, vmi.Name)
54+
+ continue
55+
+ }
56+
+ nodeNamePtr := &vmi.Status.NodeName
57+
+
58+
ready := vmi.Status.Phase == kubevirtv1.Running
59+
serving := vmi.Status.Phase == kubevirtv1.Running
60+
terminating := vmi.Status.Phase == kubevirtv1.Failed || vmi.Status.Phase == kubevirtv1.Succeeded
61+
62+
for _, i := range vmi.Status.Interfaces {
63+
if i.Name == "default" {
64+
+ if i.IP == "" {
65+
+ klog.Warningf("VMI %s/%s interface %q has no IP, skipping", vmi.Namespace, vmi.Name, i.Name)
66+
+ continue
67+
+ }
68+
desiredEndpoints = append(desiredEndpoints, &discovery.Endpoint{
69+
Addresses: []string{i.IP},
70+
Conditions: discovery.EndpointConditions{
71+
@@ -705,9 +719,9 @@ func (c *Controller) getDesiredEndpoints(service *v1.Service, tenantSlices []*di
72+
Serving: &serving,
73+
Terminating: &terminating,
74+
},
75+
- NodeName: &vmi.Status.NodeName,
76+
+ NodeName: nodeNamePtr,
77+
})
78+
- continue
79+
+ break
80+
}
81+
}
82+
}
83+
diff --git a/pkg/controller/kubevirteps/kubevirteps_controller_test.go b/pkg/controller/kubevirteps/kubevirteps_controller_test.go
84+
index 1c97035b4..d205d0bed 100644
85+
--- a/pkg/controller/kubevirteps/kubevirteps_controller_test.go
86+
+++ b/pkg/controller/kubevirteps/kubevirteps_controller_test.go
87+
@@ -771,3 +771,55 @@ var _ = g.Describe("KubevirtEPSController", g.Ordered, func() {
88+
89+
})
90+
})
91+
+
92+
+var _ = g.Describe("getDesiredEndpoints", func() {
93+
+ g.It("should skip endpoints without NodeName and VMIs without NodeName or IP", func() {
94+
+ // Setup controller
95+
+ ctrl := setupTestKubevirtEPSController().controller
96+
+
97+
+ // Manually inject dynamic client content (1 VMI with missing NodeName)
98+
+ vmi := createUnstructuredVMINode("vmi-without-node", "", "10.0.0.1") // empty NodeName
99+
+ _, err := ctrl.infraDynamic.
100+
+ Resource(kubevirtv1.VirtualMachineInstanceGroupVersionKind.GroupVersion().WithResource("virtualmachineinstances")).
101+
+ Namespace(infraNamespace).
102+
+ Create(context.TODO(), vmi, metav1.CreateOptions{})
103+
+ Expect(err).To(BeNil())
104+
+
105+
+ // Create service
106+
+ svc := createInfraServiceLB("test-svc", "test-svc", "test-cluster",
107+
+ v1.ServicePort{
108+
+ Name: "http",
109+
+ Port: 80,
110+
+ TargetPort: intstr.FromInt(8080),
111+
+ Protocol: v1.ProtocolTCP,
112+
+ },
113+
+ v1.ServiceExternalTrafficPolicyLocal,
114+
+ )
115+
+
116+
+ // One endpoint has nil NodeName, another is valid
117+
+ nodeName := "vmi-without-node"
118+
+ tenantSlice := &discoveryv1.EndpointSlice{
119+
+ ObjectMeta: metav1.ObjectMeta{
120+
+ Name: "slice",
121+
+ Namespace: tenantNamespace,
122+
+ Labels: map[string]string{
123+
+ discoveryv1.LabelServiceName: "test-svc",
124+
+ },
125+
+ },
126+
+ AddressType: discoveryv1.AddressTypeIPv4,
127+
+ Endpoints: []discoveryv1.Endpoint{
128+
+ { // should be skipped due to nil NodeName
129+
+ Addresses: []string{"10.1.1.1"},
130+
+ NodeName: nil,
131+
+ },
132+
+ { // will hit VMI without NodeName and also be skipped
133+
+ Addresses: []string{"10.1.1.2"},
134+
+ NodeName: &nodeName,
135+
+ },
136+
+ },
137+
+ }
138+
+
139+
+ endpoints := ctrl.getDesiredEndpoints(svc, []*discoveryv1.EndpointSlice{tenantSlice})
140+
+ Expect(endpoints).To(HaveLen(0), "Expected no endpoints due to missing NodeName or IP")
141+
+ })
142+
+})

‎packages/apps/versions_map‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ kubernetes 0.19.0 93bdf411
7171
kubernetes 0.20.0 609e7ede
7272
kubernetes 0.20.1 f9f8bb2f
7373
kubernetes 0.21.0 6130f43d
74-
kubernetes 0.23.1 HEAD
74+
kubernetes 0.23.1 632224a3
75+
kubernetes 0.23.2 HEAD
7576
mysql 0.1.0 263e47be
7677
mysql 0.2.0 c24a103f
7778
mysql 0.3.0 53f2365e

0 commit comments

Comments
 (0)