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

kubevirt / hyperconverged-cluster-operator / 15999493596

01 Jul 2025 12:36PM UTC coverage: 75.441% (-0.1%) from 75.563%
15999493596

Pull #3594

github

web-flow
Merge 09933433c into fd650c52c
Pull Request #3594: Monitor the cluster architectures

246 of 351 new or added lines in 8 files covered. (70.09%)

3 existing lines in 2 files now uncovered.

6586 of 8730 relevant lines covered (75.44%)

1.5 hits per line

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

91.3
/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
        "github.com/kubevirt/hyperconverged-cluster-operator/api/v1beta1"
13
)
14

15
func HandleNodeChanges(ctx context.Context, cl client.Client, hc *v1beta1.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✔
NEW
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 *v1beta1.HyperConverged) bool {
1✔
36
        workerNodeCount := 0
1✔
37
        cpNodeCount := 0
1✔
38

1✔
39
        workloadArchs := sets.New[string]()
1✔
40
        cpArchs := sets.New[string]()
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
                        workloadArchs.Insert(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
                        cpArchs.Insert(arch)
1✔
59
                }
1✔
60
        }
61

62
        // remove empty architectures
63
        workloadArchs.Delete("")
1✔
64
        cpArchs.Delete("")
1✔
65

1✔
66
        newValue := cpNodeCount >= 3
1✔
67
        changed := controlPlaneHighlyAvailable.Swap(newValue) != newValue
1✔
68

1✔
69
        newValue = cpNodeCount >= 1
1✔
70
        changed = controlPlaneNodeExist.Swap(newValue) != newValue || changed
1✔
71

1✔
72
        newValue = workerNodeCount >= 2
1✔
73
        changed = infrastructureHighlyAvailable.Swap(newValue) != newValue || changed
1✔
74

1✔
75
        changed = workloadArchitectures.set(workloadArchs) || changed
1✔
76
        changed = controlPlaneArchitectures.set(cpArchs) || changed
1✔
77

1✔
78
        return changed
1✔
79
}
80

81
func isWorkerNode(node corev1.Node) bool {
1✔
82
        _, exists := node.Labels[LabelNodeRoleWorker]
1✔
83
        return exists
1✔
84
}
1✔
85

86
func isWorkloadNodeFunc(hc *v1beta1.HyperConverged) func(corev1.Node) bool {
1✔
87
        if hasWorkloadRequirements(hc) {
2✔
88

1✔
89
                workloadMatcher := getWorkloadMatcher(hc)
1✔
90

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

100
        return isWorkerNode
1✔
101
}
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