• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In
Build has been canceled!

kubevirt / containerized-data-importer / #5676

17 Nov 2025 10:06PM UTC coverage: 58.665% (-0.08%) from 58.748%
#5676

push

travis-ci

web-flow
Copy Events from tmp PVCs during Clone (#3933)

* move CopyEvents to common package so it can be called from other controllers

Signed-off-by: dsanatar <dsanatar@redhat.com>

* copy events from tmp clone pvcs to their target pvc

Signed-off-by: dsanatar <dsanatar@redhat.com>

---------

Signed-off-by: dsanatar <dsanatar@redhat.com>

19 of 64 new or added lines in 6 files covered. (29.69%)

7 existing lines in 1 file now uncovered.

17389 of 29641 relevant lines covered (58.67%)

0.65 hits per line

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

74.68
/pkg/controller/clone/csi-clone.go
1
package clone
2

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

8
        "github.com/go-logr/logr"
9

10
        corev1 "k8s.io/api/core/v1"
11
        "k8s.io/client-go/tools/record"
12

13
        "sigs.k8s.io/controller-runtime/pkg/client"
14
        "sigs.k8s.io/controller-runtime/pkg/reconcile"
15

16
        cdiv1 "kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1"
17
        cc "kubevirt.io/containerized-data-importer/pkg/controller/common"
18
)
19

20
// CSIClonePhaseName is the name of the csi clone phase
21
const CSIClonePhaseName = "CSIClone"
22

23
// CSIClonePhase is responsible for csi cloning a pvc
24
type CSIClonePhase struct {
25
        Owner          client.Object
26
        Namespace      string
27
        SourceName     string
28
        DesiredClaim   *corev1.PersistentVolumeClaim
29
        OwnershipLabel string
30
        Client         client.Client
31
        Log            logr.Logger
32
        Recorder       record.EventRecorder
33
}
34

35
var _ Phase = &CSIClonePhase{}
36

37
// Name returns the name of the phase
38
func (p *CSIClonePhase) Name() string {
×
39
        return CSIClonePhaseName
×
40
}
×
41

42
// Reconcile ensures a csi cloned pvc is created correctly
43
func (p *CSIClonePhase) Reconcile(ctx context.Context) (*reconcile.Result, error) {
1✔
44
        pvc := &corev1.PersistentVolumeClaim{}
1✔
45
        exists, err := getResource(ctx, p.Client, p.Namespace, p.DesiredClaim.Name, pvc)
1✔
46
        if err != nil {
1✔
47
                return nil, err
×
48
        }
×
49

50
        if !exists {
2✔
51
                args := &IsSourceClaimReadyArgs{
1✔
52
                        Target:          p.Owner,
1✔
53
                        SourceNamespace: p.Namespace,
1✔
54
                        SourceName:      p.SourceName,
1✔
55
                        Client:          p.Client,
1✔
56
                        Log:             p.Log,
1✔
57
                        Recorder:        p.Recorder,
1✔
58
                }
1✔
59

1✔
60
                ready, err := IsSourceClaimReady(ctx, args)
1✔
61
                if err != nil {
1✔
62
                        return nil, err
×
63
                }
×
64

65
                if !ready {
2✔
66
                        // TODO - maybe make this event based
1✔
67
                        return &reconcile.Result{RequeueAfter: 2 * time.Second}, nil
1✔
68
                }
1✔
69

70
                pvc, err = p.createClaim(ctx)
1✔
71
                if err != nil {
1✔
72
                        return nil, err
×
73
                }
×
74
        }
75

76
        targetPvc, err := cc.GetAnnotatedEventSource(ctx, p.Client, pvc)
1✔
77
        if err != nil {
1✔
NEW
78
                return nil, err
×
NEW
79
        }
×
80
        cc.CopyEvents(pvc, targetPvc, p.Client, p.Recorder)
1✔
81

1✔
82
        done, err := isClaimBoundOrWFFC(ctx, p.Client, pvc)
1✔
83
        if err != nil {
1✔
84
                return nil, err
×
85
        }
×
86

87
        if !done {
2✔
88
                return &reconcile.Result{}, nil
1✔
89
        }
1✔
90

91
        return nil, nil
1✔
92
}
93

94
func (p *CSIClonePhase) createClaim(ctx context.Context) (*corev1.PersistentVolumeClaim, error) {
1✔
95
        sourceClaim := &corev1.PersistentVolumeClaim{}
1✔
96
        exists, err := getResource(ctx, p.Client, p.Namespace, p.SourceName, sourceClaim)
1✔
97
        if err != nil {
1✔
98
                return nil, err
×
99
        }
×
100

101
        if !exists {
1✔
102
                return nil, fmt.Errorf("source claim does not exist")
×
103
        }
×
104

105
        desiredClaim := p.DesiredClaim.DeepCopy()
1✔
106
        desiredClaim.Namespace = sourceClaim.Namespace
1✔
107
        desiredClaim.Spec.DataSourceRef = &corev1.TypedObjectReference{
1✔
108
                Kind: "PersistentVolumeClaim",
1✔
109
                Name: sourceClaim.Name,
1✔
110
        }
1✔
111

1✔
112
        sourceSize := sourceClaim.Status.Capacity[corev1.ResourceStorage]
1✔
113
        p.Log.V(3).Info("setting desired pvc request size to", "restoreSize", sourceSize)
1✔
114
        desiredClaim.Spec.Resources.Requests[corev1.ResourceStorage] = sourceSize
1✔
115

1✔
116
        cc.AddAnnotation(desiredClaim, cc.AnnPopulatorKind, cdiv1.VolumeCloneSourceRef)
1✔
117
        cc.AddAnnotation(desiredClaim, cc.AnnEventSourceKind, p.Owner.GetObjectKind().GroupVersionKind().Kind)
1✔
118
        cc.AddAnnotation(desiredClaim, cc.AnnEventSource, fmt.Sprintf("%s/%s", p.Owner.GetNamespace(), p.Owner.GetName()))
1✔
119

1✔
120
        if p.OwnershipLabel != "" {
2✔
121
                AddOwnershipLabel(p.OwnershipLabel, desiredClaim, p.Owner)
1✔
122
        }
1✔
123
        cc.AddLabel(desiredClaim, cc.LabelExcludeFromVeleroBackup, "true")
1✔
124

1✔
125
        if err := p.Client.Create(ctx, desiredClaim); err != nil {
1✔
126
                checkQuotaExceeded(p.Recorder, p.Owner, err)
×
127
                return nil, err
×
128
        }
×
129

130
        return desiredClaim, nil
1✔
131
}
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

© 2025 Coveralls, Inc