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

kubevirt / containerized-data-importer / #4907

23 Aug 2024 07:08PM UTC coverage: 59.122% (-0.05%) from 59.176%
#4907

push

travis-ci

web-flow
Run bazelisk run //robots/cmd/uploader:uploader -- -workspace /home/prow/go/src/github.com/kubevirt/project-infra/../containerized-data-importer/WORKSPACE -dry-run=false (#3407)

Signed-off-by: kubevirt-bot <kubevirtbot@redhat.com>

16599 of 28076 relevant lines covered (59.12%)

0.65 hits per line

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

83.45
/pkg/controller/clone/prep-claim.go
1
package clone
2

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

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

9
        corev1 "k8s.io/api/core/v1"
10
        metav1 "k8s.io/apimachinery/pkg/apis/meta/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
        "kubevirt.io/containerized-data-importer/pkg/common"
17
        cc "kubevirt.io/containerized-data-importer/pkg/controller/common"
18
        "kubevirt.io/containerized-data-importer/pkg/util"
19
)
20

21
// PrepClaimPhaseName is the name of the prep claim phase
22
const PrepClaimPhaseName = "PrepClaim"
23

24
// PrepClaimPhase is responsible for prepping a PVC for rebind
25
type PrepClaimPhase struct {
26
        Owner           client.Object
27
        DesiredClaim    *corev1.PersistentVolumeClaim
28
        Image           string
29
        PullPolicy      corev1.PullPolicy
30
        InstallerLabels map[string]string
31
        OwnershipLabel  string
32
        Client          client.Client
33
        Log             logr.Logger
34
        Recorder        record.EventRecorder
35
}
36

37
var _ Phase = &PrepClaimPhase{}
38

39
// Name returns the name of the phase
40
func (p *PrepClaimPhase) Name() string {
×
41
        return PrepClaimPhaseName
×
42
}
×
43

44
// Reconcile ensures that a pvc is bound and resized if necessary
45
func (p *PrepClaimPhase) Reconcile(ctx context.Context) (*reconcile.Result, error) {
1✔
46
        actualClaim := &corev1.PersistentVolumeClaim{}
1✔
47
        pvcExists, err := getResource(ctx, p.Client, p.DesiredClaim.Namespace, p.DesiredClaim.Name, actualClaim)
1✔
48
        if err != nil {
1✔
49
                return nil, err
×
50
        }
×
51

52
        if !pvcExists {
2✔
53
                return nil, fmt.Errorf("claim %s/%s does not exist", p.DesiredClaim.Namespace, p.DesiredClaim.Name)
1✔
54
        }
1✔
55

56
        podName := fmt.Sprintf("prep-%s", string(p.Owner.GetUID()))
1✔
57
        pod := &corev1.Pod{}
1✔
58
        podExists, err := getResource(ctx, p.Client, p.DesiredClaim.Namespace, podName, pod)
1✔
59
        if err != nil {
1✔
60
                return nil, err
×
61
        }
×
62

63
        podRequired := false
1✔
64
        requestedSize, hasRequested := p.DesiredClaim.Spec.Resources.Requests[corev1.ResourceStorage]
1✔
65
        currentSize, hasCurrent := actualClaim.Spec.Resources.Requests[corev1.ResourceStorage]
1✔
66
        actualSize, hasActual := actualClaim.Status.Capacity[corev1.ResourceStorage]
1✔
67
        if !hasRequested || !hasCurrent {
2✔
68
                return nil, fmt.Errorf("requested PVC sizes missing")
1✔
69
        }
1✔
70

71
        p.Log.V(3).Info("Expand sizes", "req", requestedSize, "cur", currentSize, "act", actualSize)
1✔
72

1✔
73
        if !hasActual {
2✔
74
                if cc.IsBound(actualClaim) {
2✔
75
                        return nil, fmt.Errorf("actual PVC size missing")
1✔
76
                }
1✔
77

78
                p.Log.V(3).Info("prep pod required to force bind")
1✔
79
                podRequired = true
1✔
80
        } else {
1✔
81
                if currentSize.Cmp(requestedSize) < 0 {
2✔
82
                        p.Log.V(3).Info("Updating resource requests to", "size", requestedSize)
1✔
83

1✔
84
                        actualClaim.Spec.Resources.Requests[corev1.ResourceStorage] = requestedSize
1✔
85
                        if err := p.Client.Update(ctx, actualClaim); err != nil {
1✔
86
                                return nil, err
×
87
                        }
×
88

89
                        // come back once pvc is updated
90
                        return &reconcile.Result{}, nil
1✔
91
                }
92

93
                if actualSize.Cmp(requestedSize) < 0 {
2✔
94
                        p.Log.V(3).Info("prep pod required to do resize")
1✔
95
                        podRequired = true
1✔
96
                }
1✔
97
        }
98

99
        p.Log.V(3).Info("Prep status", "podRequired", podRequired, "podExists", podExists)
1✔
100

1✔
101
        if !podRequired && !podExists {
2✔
102
                // all done finally
1✔
103
                return nil, nil
1✔
104
        }
1✔
105

106
        if podExists && pod.Status.Phase == corev1.PodSucceeded {
2✔
107
                p.Log.V(3).Info("Prep pod succeeded, deleting")
1✔
108

1✔
109
                if err := p.Client.Delete(ctx, pod); err != nil {
1✔
110
                        return nil, err
×
111
                }
×
112
        }
113

114
        if podRequired && !podExists {
2✔
115
                p.Log.V(3).Info("creating prep pod")
1✔
116

1✔
117
                if err := p.createPod(ctx, podName, actualClaim); err != nil {
1✔
118
                        return nil, err
×
119
                }
×
120
        }
121

122
        // pod is running
123
        return &reconcile.Result{}, nil
1✔
124
}
125

126
func (p *PrepClaimPhase) createPod(ctx context.Context, name string, pvc *corev1.PersistentVolumeClaim) error {
1✔
127
        resourceRequirements, err := cc.GetDefaultPodResourceRequirements(p.Client)
1✔
128
        if err != nil {
1✔
129
                return err
×
130
        }
×
131

132
        imagePullSecrets, err := cc.GetImagePullSecrets(p.Client)
1✔
133
        if err != nil {
1✔
134
                return err
×
135
        }
×
136

137
        workloadNodePlacement, err := cc.GetWorkloadNodePlacement(ctx, p.Client)
1✔
138
        if err != nil {
1✔
139
                return err
×
140
        }
×
141

142
        pod := &corev1.Pod{
1✔
143
                ObjectMeta: metav1.ObjectMeta{
1✔
144
                        Name:      name,
1✔
145
                        Namespace: pvc.Namespace,
1✔
146
                        Annotations: map[string]string{
1✔
147
                                cc.AnnCreatedBy: "yes",
1✔
148
                        },
1✔
149
                        Labels: map[string]string{
1✔
150
                                common.CDILabelKey:       common.CDILabelValue,
1✔
151
                                common.CDIComponentLabel: "cdi-populator-prep",
1✔
152
                        },
1✔
153
                },
1✔
154
                Spec: corev1.PodSpec{
1✔
155
                        Containers: []corev1.Container{
1✔
156
                                {
1✔
157
                                        Name:            "dummy",
1✔
158
                                        Image:           p.Image,
1✔
159
                                        ImagePullPolicy: p.PullPolicy,
1✔
160
                                        Command:         []string{"/bin/bash"},
1✔
161
                                        Args:            []string{"-c", "echo", "'hello cdi'"},
1✔
162
                                },
1✔
163
                        },
1✔
164
                        ImagePullSecrets: imagePullSecrets,
1✔
165
                        RestartPolicy:    corev1.RestartPolicyOnFailure,
1✔
166
                        Volumes: []corev1.Volume{
1✔
167
                                {
1✔
168
                                        Name: cc.DataVolName,
1✔
169
                                        VolumeSource: corev1.VolumeSource{
1✔
170
                                                PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
1✔
171
                                                        ClaimName: pvc.Name,
1✔
172
                                                },
1✔
173
                                        },
1✔
174
                                },
1✔
175
                        },
1✔
176
                        NodeSelector: workloadNodePlacement.NodeSelector,
1✔
177
                        Tolerations:  workloadNodePlacement.Tolerations,
1✔
178
                        Affinity:     workloadNodePlacement.Affinity,
1✔
179
                },
1✔
180
        }
1✔
181
        util.SetRecommendedLabels(pod, p.InstallerLabels, "cdi-controller")
1✔
182

1✔
183
        if pvc.Spec.VolumeMode != nil && *pvc.Spec.VolumeMode == corev1.PersistentVolumeBlock {
1✔
184
                pod.Spec.Containers[0].VolumeDevices = cc.AddVolumeDevices()
×
185
        } else {
1✔
186
                pod.Spec.Containers[0].VolumeMounts = []corev1.VolumeMount{
1✔
187
                        {
1✔
188
                                Name:      cc.DataVolName,
1✔
189
                                MountPath: common.ClonerMountPath,
1✔
190
                        },
1✔
191
                }
1✔
192
        }
1✔
193

194
        if resourceRequirements != nil {
1✔
195
                pod.Spec.Containers[0].Resources = *resourceRequirements
×
196
        }
×
197

198
        if pvc.Annotations[cc.AnnSelectedNode] != "" {
2✔
199
                pod.Spec.NodeName = pvc.Annotations[cc.AnnSelectedNode]
1✔
200
        }
1✔
201

202
        if p.OwnershipLabel != "" {
2✔
203
                AddOwnershipLabel(p.OwnershipLabel, pod, p.Owner)
1✔
204
        }
1✔
205

206
        cc.CopyAllowedAnnotations(pvc, pod)
1✔
207
        cc.SetRestrictedSecurityContext(&pod.Spec)
1✔
208

1✔
209
        if err := p.Client.Create(ctx, pod); err != nil {
1✔
210
                return err
×
211
        }
×
212

213
        return nil
1✔
214
}
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