• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kubevirt / hyperconverged-cluster-operator / 27945355651

22 Jun 2026 10:11AM UTC coverage: 80.636% (+0.06%) from 80.575%
27945355651

Pull #4329

github

web-flow
Merge f0789aa13 into a20f54fbc
Pull Request #4329: Set the default architecture in the KubeVirt CR

67 of 67 new or added lines in 4 files covered. (100.0%)

2 existing lines in 1 file now uncovered.

10544 of 13076 relevant lines covered (80.64%)

2.12 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.78
/pkg/internal/nodeinfo/nodeinfo.go
1
package nodeinfo
2

3
import (
4
        "context"
5
        "fmt"
6

7
        "github.com/go-logr/logr"
8
        corev1 "k8s.io/api/core/v1"
9
        "sigs.k8s.io/controller-runtime/pkg/client"
10

11
        hcov1 "github.com/kubevirt/hyperconverged-cluster-operator/api/v1"
12
)
13

14
func HandleNodeChanges(ctx context.Context, cl client.Client, hc *hcov1.HyperConverged, logger logr.Logger) (bool, error) {
1✔
15
        logger.Info("reading cluster nodes")
1✔
16
        nodes, err := getNodes(ctx, cl)
1✔
17
        if err != nil {
1✔
UNCOV
18
                return false, fmt.Errorf("failed to read the cluster nodes; %v", err)
×
19
        }
×
20

21
        return processNodeInfo(nodes, hc), nil
1✔
22
}
23

24
func getNodes(ctx context.Context, cl client.Client) ([]corev1.Node, error) {
1✔
25
        nodesList := &corev1.NodeList{}
1✔
26
        err := cl.List(ctx, nodesList)
1✔
27
        if err != nil {
1✔
UNCOV
28
                return nil, err
×
29
        }
×
30

31
        return nodesList.Items, nil
1✔
32
}
33

34
func processNodeInfo(nodes []corev1.Node, hc *hcov1.HyperConverged) bool {
1✔
35
        workerNodeCount := 0
1✔
36
        cpNodeCount := 0
1✔
37
        arbiterNodeCount := 0
1✔
38

1✔
39
        workloadArchMap := map[string]int{}
1✔
40
        cpArchMap := map[string]int{}
1✔
41

1✔
42
        isWorkloadNode := isWorkloadNodeFunc(hc)
1✔
43

1✔
44
        for _, node := range nodes {
2✔
45
                arch := node.Status.NodeInfo.Architecture
1✔
46
                if isWorkerNode(node) {
2✔
47
                        workerNodeCount++
1✔
48
                }
1✔
49

50
                if isWorkloadNode(node) {
2✔
51
                        workloadArchMap[arch]++
1✔
52
                }
1✔
53

54
                _, masterLabelExists := node.Labels[LabelNodeRoleMaster]
1✔
55
                _, cpLabelExists := node.Labels[LabelNodeRoleControlPlane]
1✔
56
                if masterLabelExists || cpLabelExists {
2✔
57
                        cpNodeCount++
1✔
58
                        cpArchMap[arch]++
1✔
59
                }
1✔
60

61
                if _, arbiterLabelExists := node.Labels[LabelNodeRoleArbiter]; arbiterLabelExists {
2✔
62
                        arbiterNodeCount++
1✔
63
                }
1✔
64
        }
65

66
        // remove empty architectures
67
        delete(workloadArchMap, "")
1✔
68
        delete(cpArchMap, "")
1✔
69

1✔
70
        newValue := cpNodeCount >= 3 || (cpNodeCount >= 2 && arbiterNodeCount >= 1)
1✔
71
        changed := controlPlaneHighlyAvailable.Swap(newValue) != newValue
1✔
72

1✔
73
        newValue = cpNodeCount >= 1
1✔
74
        changed = controlPlaneNodeExist.Swap(newValue) != newValue || changed
1✔
75

1✔
76
        newValue = workerNodeCount >= 2
1✔
77
        changed = infrastructureHighlyAvailable.Swap(newValue) != newValue || changed
1✔
78

1✔
79
        changed = workloadArchitectures.set(workloadArchMap) || changed
1✔
80
        changed = controlPlaneArchitectures.set(cpArchMap) || changed
1✔
81

1✔
82
        return changed
1✔
83
}
84

85
func isWorkerNode(node corev1.Node) bool {
1✔
86
        _, exists := node.Labels[LabelNodeRoleWorker]
1✔
87
        return exists
1✔
88
}
1✔
89

90
func isWorkloadNodeFunc(hc *hcov1.HyperConverged) func(corev1.Node) bool {
1✔
91
        if hasWorkloadRequirements(hc) {
2✔
92

1✔
93
                workloadMatcher := getWorkloadMatcher(hc)
1✔
94

1✔
95
                return func(node corev1.Node) bool {
2✔
96
                        matches, err := workloadMatcher.Match(&node)
1✔
97
                        if err != nil { // should not happen, because the validation webhook checks it, but just in case
1✔
98
                                return false
×
99
                        }
×
100
                        return matches
1✔
101
                }
102
        }
103

104
        return isWorkerNode
1✔
105
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc