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

kubevirt / hyperconverged-cluster-operator / 27899504438

21 Jun 2026 09:03AM UTC coverage: 80.478% (+0.05%) from 80.433%
27899504438

Pull #4329

github

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

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

1 existing line in 1 file now uncovered.

10508 of 13057 relevant lines covered (80.48%)

2.05 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
        "k8s.io/apimachinery/pkg/util/sets"
10
        "sigs.k8s.io/controller-runtime/pkg/client"
11

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

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

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

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

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

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

1✔
40
        workloadArchs := sets.New[string]()
1✔
41
        cpArchs := sets.New[string]()
1✔
42

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

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

51
                if isWorkloadNode(node) {
2✔
52
                        workloadArchs.Insert(arch)
1✔
53
                }
1✔
54

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

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

67
        // remove empty architectures
68
        workloadArchs.Delete("")
1✔
69
        cpArchs.Delete("")
1✔
70

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

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

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

1✔
80
        changed = workloadArchitectures.set(workloadArchs) || changed
1✔
81
        changed = controlPlaneArchitectures.set(cpArchs) || changed
1✔
82

1✔
83
        return changed
1✔
84
}
85

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

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

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

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

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

© 2026 Coveralls, Inc