mirror of
https://github.com/kubevirt/containerized-data-importer.git
synced 2025-06-03 06:30:22 +00:00

* touch up zero restoresize snapshot Signed-off-by: Michael Henriksen <mhenriks@redhat.com> * clone populator only supports PVC source now snapshot coming soon Signed-off-by: Michael Henriksen <mhenriks@redhat.com> * more unit tests Signed-off-by: Michael Henriksen <mhenriks@redhat.com> * unit test for clone populator Signed-off-by: Michael Henriksen <mhenriks@redhat.com> * func tests for clone populator Signed-off-by: Michael Henriksen <mhenriks@redhat.com> * move clone populator cleanup function to planner other review comments verifier pod should bount readonly Signed-off-by: Michael Henriksen <mhenriks@redhat.com> * add readonly flag to test executor pods synchronize get hash calls Signed-off-by: Michael Henriksen <mhenriks@redhat.com> * increase linter timeout Signed-off-by: Michael Henriksen <mhenriks@redhat.com> * better/explicit readonly support for test pods Signed-off-by: Michael Henriksen <mhenriks@redhat.com> * check pv for driver info before looking up storageclass as it may not exist Signed-off-by: Michael Henriksen <mhenriks@redhat.com> * addressed review comments Signed-off-by: Michael Henriksen <mhenriks@redhat.com> * chooseStrategy shoud generate more events Signed-off-by: Michael Henriksen <mhenriks@redhat.com> --------- Signed-off-by: Michael Henriksen <mhenriks@redhat.com>
132 lines
3.4 KiB
Go
132 lines
3.4 KiB
Go
package clone
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/go-logr/logr"
|
|
corev1 "k8s.io/api/core/v1"
|
|
"k8s.io/client-go/tools/record"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
|
|
|
cdiv1 "kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1"
|
|
cc "kubevirt.io/containerized-data-importer/pkg/controller/common"
|
|
)
|
|
|
|
// HostClonePhase creates and monitors a dumb clone operation
|
|
type HostClonePhase struct {
|
|
Owner client.Object
|
|
Namespace string
|
|
SourceName string
|
|
DesiredClaim *corev1.PersistentVolumeClaim
|
|
ImmediateBind bool
|
|
OwnershipLabel string
|
|
Preallocation bool
|
|
PriorityClassName string
|
|
Client client.Client
|
|
Log logr.Logger
|
|
Recorder record.EventRecorder
|
|
}
|
|
|
|
var _ Phase = &HostClonePhase{}
|
|
|
|
var _ ProgressReporter = &HostClonePhase{}
|
|
|
|
var httpClient *http.Client
|
|
|
|
func init() {
|
|
httpClient = cc.BuildHTTPClient(httpClient)
|
|
}
|
|
|
|
// Name returns the name of the phase
|
|
func (p *HostClonePhase) Name() string {
|
|
return "HostClone"
|
|
}
|
|
|
|
// Progress returns the progress of the operation as a percentage
|
|
func (p *HostClonePhase) Progress(ctx context.Context) (string, error) {
|
|
pvc := &corev1.PersistentVolumeClaim{}
|
|
exists, err := getResource(ctx, p.Client, p.Namespace, p.DesiredClaim.Name, pvc)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
podName := pvc.Annotations[cc.AnnCloneSourcePod]
|
|
if !exists || podName == "" {
|
|
return "", nil
|
|
}
|
|
|
|
args := &cc.ProgressFromClaimArgs{
|
|
Client: p.Client,
|
|
HTTPClient: httpClient,
|
|
Claim: pvc,
|
|
PodNamespace: p.Namespace,
|
|
PodName: podName,
|
|
OwnerUID: string(p.Owner.GetUID()),
|
|
}
|
|
|
|
progress, err := cc.ProgressFromClaim(ctx, args)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return progress, nil
|
|
}
|
|
|
|
// Reconcile creates the desired pvc and waits for the operation to complete
|
|
func (p *HostClonePhase) Reconcile(ctx context.Context) (*reconcile.Result, error) {
|
|
actualClaim := &corev1.PersistentVolumeClaim{}
|
|
exists, err := getResource(ctx, p.Client, p.Namespace, p.DesiredClaim.Name, actualClaim)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if !exists {
|
|
actualClaim, err = p.createClaim(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
if !hostCloneComplete(actualClaim) {
|
|
// requeue to update status
|
|
return &reconcile.Result{RequeueAfter: 3 * time.Second}, nil
|
|
}
|
|
|
|
return nil, nil
|
|
}
|
|
|
|
func (p *HostClonePhase) createClaim(ctx context.Context) (*corev1.PersistentVolumeClaim, error) {
|
|
claim := p.DesiredClaim.DeepCopy()
|
|
|
|
claim.Namespace = p.Namespace
|
|
cc.AddAnnotation(claim, cc.AnnPreallocationRequested, fmt.Sprintf("%t", p.Preallocation))
|
|
cc.AddAnnotation(claim, cc.AnnOwnerUID, string(p.Owner.GetUID()))
|
|
cc.AddAnnotation(claim, cc.AnnPodRestarts, "0")
|
|
cc.AddAnnotation(claim, cc.AnnCloneRequest, fmt.Sprintf("%s/%s", p.Namespace, p.SourceName))
|
|
cc.AddAnnotation(claim, cc.AnnPopulatorKind, cdiv1.VolumeCloneSourceRef)
|
|
if p.OwnershipLabel != "" {
|
|
AddOwnershipLabel(p.OwnershipLabel, claim, p.Owner)
|
|
}
|
|
if p.ImmediateBind {
|
|
cc.AddAnnotation(claim, cc.AnnImmediateBinding, "")
|
|
}
|
|
if p.PriorityClassName != "" {
|
|
cc.AddAnnotation(claim, cc.AnnPriorityClassName, p.PriorityClassName)
|
|
}
|
|
|
|
if err := p.Client.Create(ctx, claim); err != nil {
|
|
checkQuotaExceeded(p.Recorder, p.Owner, err)
|
|
return nil, err
|
|
}
|
|
|
|
return claim, nil
|
|
}
|
|
|
|
func hostCloneComplete(pvc *corev1.PersistentVolumeClaim) bool {
|
|
return pvc.Annotations[cc.AnnPodPhase] == string(cdiv1.Succeeded)
|
|
}
|