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

kubevirt / hyperconverged-cluster-operator / 16414937357

21 Jul 2025 10:48AM UTC coverage: 75.155% (-0.003%) from 75.158%
16414937357

Pull #3601

github

web-flow
Merge 8f7b170b0 into 9213ca4f1
Pull Request #3601: network,passt: Deploy Passt required objects

382 of 502 new or added lines in 10 files covered. (76.1%)

37 existing lines in 1 file now uncovered.

6909 of 9193 relevant lines covered (75.16%)

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) *appsv1.DaemonSet
18

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

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

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

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

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

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

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

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

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

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

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

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

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