Skip to content

Commit ac646af

Browse files
committed
bug(daemon): Reset the configuration when disableDrain: true
After commit [1], when the config-daemon is asked to drain and `SriovOperatorConfig.Spec.DisableDrain: true`, the configuration is not applied and the SriovNetworkNodeState SyncStatus field gets stuck in `InProgress`. Handle the DisableDrain properly. [1] openshift@683101d#diff-a53b7b593d3d778e62eaeeafa40088656f9212bfa2c2b7991df15fa78e60b0f0R271 Signed-off-by: Andrea Panattoni <[email protected]>
1 parent 986221b commit ac646af

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

pkg/daemon/daemon.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,10 @@ func (dn *NodeReconciler) prepareNMUdevRule() error {
644644

645645
// isDrainCompleted returns true if the current-state annotation is drain completed
646646
func (dn *NodeReconciler) isDrainCompleted(reqDrain bool, desiredNodeState *sriovnetworkv1.SriovNetworkNodeState) bool {
647+
if vars.DisableDrain {
648+
return true
649+
}
650+
647651
// if we need to drain check the drain status
648652
if reqDrain {
649653
return utils.ObjectHasAnnotation(desiredNodeState, consts.NodeStateDrainAnnotationCurrent, consts.DrainComplete)

pkg/daemon/daemon_test.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,90 @@ var _ = Describe("Daemon Controller", Ordered, func() {
262262

263263
Expect(nodeState.Status.LastSyncError).To(Equal(""))
264264
})
265+
266+
It("Should apply the reset configuration when disableDrain is true", func() {
267+
DeferCleanup(func(x bool) { vars.DisableDrain = x }, vars.DisableDrain)
268+
vars.DisableDrain = true
269+
270+
By("Init mock functions")
271+
hostHelper.EXPECT().DiscoverSriovDevices(hostHelper).DoAndReturn(func(helpersInterface helper.HostHelpersInterface) ([]sriovnetworkv1.InterfaceExt, error) {
272+
interfaceExtList := []sriovnetworkv1.InterfaceExt{
273+
{
274+
Name: "eno1",
275+
Driver: "ice",
276+
PciAddress: "0000:16:00.0",
277+
DeviceID: "1593",
278+
Vendor: "8086",
279+
EswitchMode: "legacy",
280+
LinkAdminState: "up",
281+
LinkSpeed: "10000 Mb/s",
282+
LinkType: "ETH",
283+
Mac: "aa:bb:cc:dd:ee:ff",
284+
Mtu: 1500,
285+
TotalVfs: 2,
286+
NumVfs: 2,
287+
VFs: []sriovnetworkv1.VirtualFunction{
288+
{
289+
Name: "eno1f0",
290+
PciAddress: "0000:16:00.1",
291+
VfID: 0,
292+
},
293+
{
294+
Name: "eno1f1",
295+
PciAddress: "0000:16:00.2",
296+
VfID: 1,
297+
}},
298+
},
299+
}
300+
301+
return interfaceExtList, nil
302+
}).AnyTimes()
303+
304+
hostHelper.EXPECT().LoadPfsStatus("0000:16:00.0").Return(&sriovnetworkv1.Interface{ExternallyManaged: false}, true, nil).AnyTimes()
305+
306+
hostHelper.EXPECT().ClearPCIAddressFolder().Return(nil).AnyTimes()
307+
hostHelper.EXPECT().DiscoverRDMASubsystem().Return("shared", nil).AnyTimes()
308+
hostHelper.EXPECT().GetCurrentKernelArgs().Return("", nil).AnyTimes()
309+
hostHelper.EXPECT().IsKernelArgsSet("", constants.KernelArgPciRealloc).Return(true).AnyTimes()
310+
hostHelper.EXPECT().IsKernelArgsSet("", constants.KernelArgIntelIommu).Return(true).AnyTimes()
311+
hostHelper.EXPECT().IsKernelArgsSet("", constants.KernelArgIommuPt).Return(true).AnyTimes()
312+
hostHelper.EXPECT().IsKernelArgsSet("", constants.KernelArgRdmaExclusive).Return(false).AnyTimes()
313+
hostHelper.EXPECT().IsKernelArgsSet("", constants.KernelArgRdmaShared).Return(false).AnyTimes()
314+
hostHelper.EXPECT().SetRDMASubsystem("").Return(nil).AnyTimes()
315+
316+
hostHelper.EXPECT().ConfigSriovInterfaces(gomock.Any(), gomock.Any(), gomock.Any(), false).Return(nil).AnyTimes()
317+
318+
_, nodeState := createNode("node1")
319+
nodeState.Spec.Interfaces = []sriovnetworkv1.Interface{
320+
{Name: "eno1",
321+
PciAddress: "0000:16:00.0",
322+
LinkType: "eth",
323+
NumVfs: 2,
324+
VfGroups: []sriovnetworkv1.VfGroup{
325+
{ResourceName: "test",
326+
DeviceType: "netdevice",
327+
PolicyName: "test-policy",
328+
VfRange: "eno1#0-1"},
329+
}},
330+
}
331+
err := k8sClient.Update(ctx, nodeState)
332+
Expect(err).ToNot(HaveOccurred())
333+
334+
featureGates := featuregate.New()
335+
featureGates.Init(map[string]bool{})
336+
dc := createDaemon(hostHelper, platformHelper, featureGates, []string{})
337+
startDaemon(dc)
338+
339+
eventuallySyncStatusEqual(nodeState, constants.SyncStatusSucceeded)
340+
341+
By("Simulate node policy removal")
342+
nodeState.Spec.Interfaces = []sriovnetworkv1.Interface{}
343+
err = k8sClient.Update(ctx, nodeState)
344+
Expect(err).ToNot(HaveOccurred())
345+
346+
eventuallySyncStatusEqual(nodeState, constants.SyncStatusSucceeded)
347+
assertLastStatusTransitionsContains(nodeState, 2, constants.SyncStatusInProgress)
348+
})
265349
})
266350
})
267351

@@ -329,3 +413,30 @@ func createDaemon(
329413

330414
return configController
331415
}
416+
417+
func eventuallySyncStatusEqual(nodeState *sriovnetworkv1.SriovNetworkNodeState, expectedState string) {
418+
EventuallyWithOffset(1, func(g Gomega) {
419+
g.Expect(k8sClient.Get(context.Background(), types.NamespacedName{Namespace: nodeState.Namespace, Name: nodeState.Name}, nodeState)).
420+
ToNot(HaveOccurred())
421+
g.Expect(nodeState.Status.SyncStatus).To(Equal(expectedState))
422+
}, 10*time.Second, 100*time.Millisecond).Should(Succeed())
423+
}
424+
425+
func assertLastStatusTransitionsContains(nodeState *sriovnetworkv1.SriovNetworkNodeState, numberOfTransitions int, status string) {
426+
events := &corev1.EventList{}
427+
err := k8sClient.List(
428+
context.Background(),
429+
events,
430+
client.MatchingFields{
431+
"involvedObject.name": nodeState.Name,
432+
"reason": "SyncStatusChanged",
433+
},
434+
client.Limit(numberOfTransitions),
435+
)
436+
Expect(err).ToNot(HaveOccurred())
437+
438+
// Status transition events are in the form
439+
// `Status changed from: Succeed to: InProgress`
440+
Expect(events.Items).To(ContainElement(
441+
HaveField("Message", ContainSubstring("to: "+status))))
442+
}

0 commit comments

Comments
 (0)