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

kubevirt / hyperconverged-cluster-operator / 16339590247

17 Jul 2025 08:01AM UTC coverage: 75.103% (-0.02%) from 75.124%
16339590247

Pull #3601

github

web-flow
Merge bcff6906b into cb8d4dd66
Pull Request #3601: network,passt: Deploy Passt required objects

391 of 521 new or added lines in 10 files covered. (75.05%)

97 existing lines in 2 files now uncovered.

6908 of 9198 relevant lines covered (75.1%)

1.77 hits per line

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

77.14
/controllers/operands/daemonSetHandler.go
1
package operands
2

3
import (
4
        "errors"
5
        "reflect"
6
        "sync"
7

8
        appsv1 "k8s.io/api/apps/v1"
9
        "k8s.io/apimachinery/pkg/runtime"
10
        "sigs.k8s.io/controller-runtime/pkg/client"
11

12
        hcov1beta1 "github.com/kubevirt/hyperconverged-cluster-operator/api/v1beta1"
13
        "github.com/kubevirt/hyperconverged-cluster-operator/controllers/common"
14
        "github.com/kubevirt/hyperconverged-cluster-operator/pkg/util"
15
)
16

17
type newDaemonSetFunc func(hc *hcov1beta1.HyperConverged, isOpenShift bool) *appsv1.DaemonSet
18

19
func NewDaemonSetHandler(Client client.Client, Scheme *runtime.Scheme, isOpenShift bool, newCrFunc newDaemonSetFunc) *GenericOperand {
3✔
20
        return NewGenericOperand(Client, Scheme, "DaemonSet", &daemonSetHooks{newCrFunc: newCrFunc, isOpenShift: isOpenShift}, false)
3✔
21
}
3✔
22

23
type daemonSetHooks struct {
24
        sync.Mutex
25
        newCrFunc   newDaemonSetFunc
26
        isOpenShift bool
27
        cache       *appsv1.DaemonSet
28
}
29

30
func (h *daemonSetHooks) GetFullCr(hc *hcov1beta1.HyperConverged) (client.Object, error) {
1✔
31
        h.Lock()
1✔
32
        defer h.Unlock()
1✔
33

1✔
34
        if h.cache == nil {
2✔
35
                h.cache = h.newCrFunc(hc, h.isOpenShift)
1✔
36
        }
1✔
37
        return h.cache, nil
1✔
38
}
39

40
func (*daemonSetHooks) GetEmptyCr() client.Object {
1✔
41
        return &appsv1.DaemonSet{}
1✔
42
}
1✔
43

44
func (h *daemonSetHooks) Reset() {
2✔
45
        h.Lock()
2✔
46
        defer h.Unlock()
2✔
47

2✔
48
        h.cache = nil
2✔
49
}
2✔
50

51
func (*daemonSetHooks) JustBeforeComplete(_ *common.HcoRequest) { /* no implementation */ }
1✔
52

53
func (*daemonSetHooks) UpdateCR(req *common.HcoRequest, Client client.Client, exists runtime.Object, required runtime.Object) (bool, bool, error) {
1✔
54
        return updateDaemonSet(req, Client, exists, required)
1✔
55
}
1✔
56

57
func updateDaemonSet(req *common.HcoRequest, Client client.Client, exists runtime.Object, required runtime.Object) (bool, bool, error) {
1✔
58
        daemonSet, ok1 := required.(*appsv1.DaemonSet)
1✔
59
        found, ok2 := exists.(*appsv1.DaemonSet)
1✔
60
        if !ok1 || !ok2 {
1✔
NEW
61
                return false, false, errors.New("can't convert to DaemonSet")
×
NEW
62
        }
×
63

64
        if !hasCorrectDaemonSetFields(found, daemonSet) {
2✔
65
                if req.HCOTriggered {
2✔
66
                        req.Logger.Info("Updating existing DaemonSet to new opinionated values", "name", daemonSet.Name)
1✔
67
                } else {
1✔
NEW
68
                        req.Logger.Info("Reconciling an externally updated DaemonSet to its opinionated values", "name", daemonSet.Name)
×
NEW
69
                }
×
70
                if shouldRecreateDaemonSet(found, daemonSet) {
1✔
NEW
71
                        err := Client.Delete(req.Ctx, found, &client.DeleteOptions{})
×
NEW
72
                        if err != nil {
×
NEW
73
                                return false, false, err
×
NEW
74
                        }
×
NEW
75
                        err = Client.Create(req.Ctx, daemonSet, &client.CreateOptions{})
×
NEW
76
                        if err != nil {
×
NEW
77
                                return false, false, err
×
NEW
78
                        }
×
NEW
79
                        return true, !req.HCOTriggered, nil
×
80
                }
81
                util.MergeLabels(&daemonSet.ObjectMeta, &found.ObjectMeta)
1✔
82
                daemonSet.Spec.DeepCopyInto(&found.Spec)
1✔
83
                err := Client.Update(req.Ctx, found)
1✔
84
                if err != nil {
1✔
NEW
85
                        return false, false, err
×
NEW
86
                }
×
87
                return true, !req.HCOTriggered, nil
1✔
88
        }
NEW
89
        return false, false, nil
×
90
}
91

92
// hasCorrectDaemonSetFields compares only the fields that are intentionally set by HCO,
93
// ignoring fields that are automatically set by Kubernetes
94
func hasCorrectDaemonSetFields(found *appsv1.DaemonSet, required *appsv1.DaemonSet) bool {
1✔
95
        return util.CompareLabels(required, found) &&
1✔
96
                reflect.DeepEqual(found.Spec.Selector, required.Spec.Selector) &&
1✔
97
                reflect.DeepEqual(found.Spec.UpdateStrategy, required.Spec.UpdateStrategy) &&
1✔
98
                reflect.DeepEqual(found.Spec.Template.Spec.Containers, required.Spec.Template.Spec.Containers) &&
1✔
99
                reflect.DeepEqual(found.Spec.Template.Spec.ServiceAccountName, required.Spec.Template.Spec.ServiceAccountName) &&
1✔
100
                reflect.DeepEqual(found.Spec.Template.Spec.PriorityClassName, required.Spec.Template.Spec.PriorityClassName) &&
1✔
101
                reflect.DeepEqual(found.Spec.Template.Spec.Volumes, required.Spec.Template.Spec.Volumes) &&
1✔
102
                reflect.DeepEqual(found.Spec.Template.Spec.Affinity, required.Spec.Template.Spec.Affinity) &&
1✔
103
                reflect.DeepEqual(found.Spec.Template.Spec.NodeSelector, required.Spec.Template.Spec.NodeSelector) &&
1✔
104
                reflect.DeepEqual(found.Spec.Template.Spec.Tolerations, required.Spec.Template.Spec.Tolerations)
1✔
105
}
1✔
106

107
func shouldRecreateDaemonSet(found, required *appsv1.DaemonSet) bool {
1✔
108
        // updating LabelSelector (it's immutable) would be rejected by API server; create new DaemonSet instead
1✔
109
        return !reflect.DeepEqual(found.Spec.Selector, required.Spec.Selector)
1✔
110
}
1✔
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