diff --git a/internal/operands/metrics/resources.go b/internal/operands/metrics/resources.go index b6ac1b91a..cc4b6e196 100644 --- a/internal/operands/metrics/resources.go +++ b/internal/operands/metrics/resources.go @@ -166,10 +166,10 @@ func getAlertRules() ([]promv1.Rule, error) { }, { Alert: "VMStorageClassWarning", - Expr: intstr.FromString("(count(kubevirt_ssp_vm_rbd_block_volume_without_rxbounce > 0) or vector(0)) > 0"), + Expr: intstr.FromString("(count(kubevirt_ssp_vm_rbd_block_volume_without_rxbounce * on(name, namespace) (kubevirt_vmi_info{guest_os_name=\"Microsoft Windows\"} > 0 or kubevirt_vmi_info{os=~\"windows.*\"} > 0) > 0) or vector(0)) > 0"), Annotations: map[string]string{ - "description": "{{ $value }} Virtual Machines are in risk of causing CRC errors and major service outages", - "summary": "When running VMs using ODF storage with 'rbd' mounter or 'rbd.csi.ceph.com provisioner', it will report bad crc/signature errors and cluster performance will be severely degraded if krbd:rxbounce is not set.", + "description": "When running Windows VMs using ODF storage with 'rbd' mounter or 'rbd.csi.ceph.com provisioner', VMs may cause reports of bad crc/signature errors due to certain I/O patterns. Cluster performance can be severely degraded if the number of re-transmissions due to crc errors causes network saturation.", + "summary": "{{ $value }} Windows Virtual Machines may cause reports of bad crc/signature errors due to certain I/O patterns.", "runbook_url": fmt.Sprintf(runbookURLTemplate, "VMStorageClassWarning"), }, Labels: map[string]string{ diff --git a/tests/monitoring_test.go b/tests/monitoring_test.go index 0aee5fcfc..254757944 100644 --- a/tests/monitoring_test.go +++ b/tests/monitoring_test.go @@ -11,6 +11,8 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "gomodules.xyz/jsonpatch/v2" + routev1 "github.com/openshift/api/route/v1" templatev1 "github.com/openshift/api/template/v1" promApi "github.com/prometheus/client_golang/api" @@ -19,11 +21,11 @@ import ( apps "k8s.io/api/apps/v1" authnv1 "k8s.io/api/authentication/v1" core "k8s.io/api/core/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/rand" - "k8s.io/utils/pointer" kubevirtv1 "kubevirt.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -245,6 +247,17 @@ var _ = Describe("Prometheus Alerts", func() { var createResources = func(createDataVolume bool, rxbounceEnabled bool) string { vmName := fmt.Sprintf("testvmi-%v", rand.String(10)) + vmi := NewMinimalVMIWithNS(strategy.GetNamespace(), vmName) + vm = NewVirtualMachine(vmi) + runStrategyAlways := kubevirtv1.RunStrategyAlways + vm.Spec.RunStrategy = &runStrategyAlways + vm.Spec.Template.ObjectMeta.Annotations = map[string]string{ + "vm.kubevirt.io/os": "windows-10", + } + + eventuallyCreateVm(vm) + waitForSeriesToBeDetected(fmt.Sprintf("kubevirt_vmi_info{name='%s', os='windows-10'} == 1", vmi.Name)) + var volumes []kubevirtv1.Volume if createDataVolume { @@ -259,13 +272,10 @@ var _ = Describe("Prometheus Alerts", func() { }) } - vmi := NewMinimalVMIWithNS(strategy.GetNamespace(), vmName) - vmi.Spec = kubevirtv1.VirtualMachineInstanceSpec{ - Volumes: volumes, - } - vm = NewVirtualMachine(vmi) - vm.Spec.Running = pointer.Bool(false) - eventuallyCreateVm(vm) + operation := jsonpatch.NewOperation("add", "/spec/template/spec/volumes", volumes) + patch := encodePatch([]jsonpatch.Operation{operation}) + err := apiClient.Patch(ctx, vm, patch) + Expect(err).NotTo(HaveOccurred()) return vmName } @@ -285,8 +295,8 @@ var _ = Describe("Prometheus Alerts", func() { Expect(err).ToNot(HaveOccurred()) Eventually(func(g Gomega) error { - return apiClient.Get(ctx, types.NamespacedName{Name: vmName, Namespace: strategy.GetNamespace()}, vm) - }).Should(MatchError(ContainSubstring(fmt.Sprintf("virtualmachines.kubevirt.io \"%s\" not found", vmName)))) + return apiClient.Get(ctx, types.NamespacedName{Name: vm.Name, Namespace: vm.Namespace}, vm) + }, 1*time.Minute, 5*time.Second).Should(MatchError(k8serrors.IsNotFound)) waitForSeriesToBeDetected(fmt.Sprintf("kubevirt_ssp_vm_rbd_block_volume_without_rxbounce{name='%s'} == 0", vmName)) alertShouldNotBeActive("VMStorageClassWarning") diff --git a/tests/tests_common_test.go b/tests/tests_common_test.go index 0c1570c96..04ee35948 100644 --- a/tests/tests_common_test.go +++ b/tests/tests_common_test.go @@ -362,7 +362,7 @@ func NewMinimalVMIWithNS(namespace, name string) *kubevirtv1.VirtualMachineInsta } func NewVirtualMachine(vmi *kubevirtv1.VirtualMachineInstance) *kubevirtv1.VirtualMachine { - running := false + runStrategyHalted := kubevirtv1.RunStrategyHalted name := vmi.Name namespace := vmi.Namespace vm := &kubevirtv1.VirtualMachine{ @@ -371,7 +371,7 @@ func NewVirtualMachine(vmi *kubevirtv1.VirtualMachineInstance) *kubevirtv1.Virtu Namespace: namespace, }, Spec: kubevirtv1.VirtualMachineSpec{ - Running: &running, + RunStrategy: &runStrategyHalted, Template: &kubevirtv1.VirtualMachineInstanceTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{"kubevirt.io/vm": name},