From 75b0a7da07bdfd0c652b5c8a8b6b8fd7ec76bbbc Mon Sep 17 00:00:00 2001 From: Isteb4k Date: Thu, 27 Jun 2024 17:30:27 +0200 Subject: [PATCH] fix(vd,vi,cvi): fix object ref datasource Signed-off-by: Isteb4k --- .../cvi/internal/source/object_ref.go | 21 +++++++++-- .../pkg/controller/dvcr_data_source.go | 37 ++++++++++--------- .../pkg/controller/monitoring/final_report.go | 4 ++ .../controller/service/protection_service.go | 36 +++++++++++------- .../vd/internal/source/object_ref.go | 32 +++++++++++----- .../vi/internal/source/object_ref.go | 20 ++++++++-- 6 files changed, 102 insertions(+), 48 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref.go b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref.go index b9f0bdbb0..5e2237f8b 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref.go @@ -92,7 +92,6 @@ func (ds ObjectRefDataSource) Sync(ctx context.Context, cvi *virtv2.ClusterVirtu return CleanUp(ctx, cvi, ds) case common.IsTerminating(pod): - cvi.Status.Phase = virtv2.ImagePending ds.logger.Info("Cleaning up...", "cvi", cvi.Name) @@ -137,9 +136,23 @@ func (ds ObjectRefDataSource) Sync(ctx context.Context, cvi *virtv2.ClusterVirtu condition.Message = "" cvi.Status.Phase = virtv2.ImageReady - cvi.Status.Size = ds.statService.GetSize(pod) - cvi.Status.CDROM = ds.statService.GetCDROM(pod) - cvi.Status.Format = ds.statService.GetFormat(pod) + + var dvcrDataSource controller.DVCRDataSource + dvcrDataSource, err = controller.NewDVCRDataSourcesForCVMI(ctx, cvi.Spec.DataSource, ds.client) + if err != nil { + return false, err + } + + if !dvcrDataSource.IsReady() { + condition.Status = metav1.ConditionFalse + condition.Reason = cvicondition.ProvisioningFailed + condition.Message = "Failed to get stats from non-ready datasource: waiting for the DataSource to be ready." + return false, nil + } + + cvi.Status.Size = dvcrDataSource.GetSize() + cvi.Status.CDROM = dvcrDataSource.IsCDROM() + cvi.Status.Format = dvcrDataSource.GetFormat() cvi.Status.Progress = "100%" cvi.Status.Target.RegistryURL = ds.dvcrSettings.RegistryImageForCVMI(cvi.Name) diff --git a/images/virtualization-artifact/pkg/controller/dvcr_data_source.go b/images/virtualization-artifact/pkg/controller/dvcr_data_source.go index 338b0677c..2ff697937 100644 --- a/images/virtualization-artifact/pkg/controller/dvcr_data_source.go +++ b/images/virtualization-artifact/pkg/controller/dvcr_data_source.go @@ -24,12 +24,11 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/deckhouse/virtualization-controller/pkg/imageformat" "github.com/deckhouse/virtualization-controller/pkg/sdk/framework/helper" virtv2 "github.com/deckhouse/virtualization/api/core/v1alpha2" ) -const FailureReasonCannotBeProcessed = "The resource cannot be processed." - type DVCRDataSource struct { size virtv2.ImageStatusSize meta metav1.Object @@ -38,9 +37,9 @@ type DVCRDataSource struct { isReady bool } -func NewDVCRDataSourcesForCVMI(ctx context.Context, ds virtv2.ClusterVirtualImageDataSource, client client.Client) (*DVCRDataSource, error) { +func NewDVCRDataSourcesForCVMI(ctx context.Context, ds virtv2.ClusterVirtualImageDataSource, client client.Client) (DVCRDataSource, error) { if ds.ObjectRef == nil { - return nil, nil + return DVCRDataSource{}, nil } var dsDVCR DVCRDataSource @@ -52,7 +51,7 @@ func NewDVCRDataSourcesForCVMI(ctx context.Context, ds virtv2.ClusterVirtualImag if vmiName != "" && vmiNS != "" { vmi, err := helper.FetchObject(ctx, types.NamespacedName{Name: vmiName, Namespace: vmiNS}, client, &virtv2.VirtualImage{}) if err != nil { - return nil, err + return DVCRDataSource{}, err } if vmi != nil { @@ -68,7 +67,7 @@ func NewDVCRDataSourcesForCVMI(ctx context.Context, ds virtv2.ClusterVirtualImag if cvmiName != "" { cvmi, err := helper.FetchObject(ctx, types.NamespacedName{Name: cvmiName}, client, &virtv2.ClusterVirtualImage{}) if err != nil { - return nil, err + return DVCRDataSource{}, err } if cvmi != nil { @@ -81,12 +80,12 @@ func NewDVCRDataSourcesForCVMI(ctx context.Context, ds virtv2.ClusterVirtualImag } } - return &dsDVCR, nil + return dsDVCR, nil } -func NewDVCRDataSourcesForVMI(ctx context.Context, ds virtv2.VirtualImageDataSource, obj metav1.Object, client client.Client) (*DVCRDataSource, error) { +func NewDVCRDataSourcesForVMI(ctx context.Context, ds virtv2.VirtualImageDataSource, obj metav1.Object, client client.Client) (DVCRDataSource, error) { if ds.ObjectRef == nil { - return nil, nil + return DVCRDataSource{}, nil } var dsDVCR DVCRDataSource @@ -98,7 +97,7 @@ func NewDVCRDataSourcesForVMI(ctx context.Context, ds virtv2.VirtualImageDataSou if vmiName != "" && vmiNS != "" { vmi, err := helper.FetchObject(ctx, types.NamespacedName{Name: vmiName, Namespace: vmiNS}, client, &virtv2.VirtualImage{}) if err != nil { - return nil, err + return DVCRDataSource{}, err } if vmi != nil { @@ -114,7 +113,7 @@ func NewDVCRDataSourcesForVMI(ctx context.Context, ds virtv2.VirtualImageDataSou if cvmiName != "" { cvmi, err := helper.FetchObject(ctx, types.NamespacedName{Name: cvmiName}, client, &virtv2.ClusterVirtualImage{}) if err != nil { - return nil, err + return DVCRDataSource{}, err } if cvmi != nil { @@ -127,12 +126,12 @@ func NewDVCRDataSourcesForVMI(ctx context.Context, ds virtv2.VirtualImageDataSou } } - return &dsDVCR, nil + return dsDVCR, nil } -func NewDVCRDataSourcesForVMD(ctx context.Context, ds *virtv2.VirtualDiskDataSource, obj metav1.Object, client client.Client) (*DVCRDataSource, error) { +func NewDVCRDataSourcesForVMD(ctx context.Context, ds *virtv2.VirtualDiskDataSource, obj metav1.Object, client client.Client) (DVCRDataSource, error) { if ds == nil || ds.ObjectRef == nil { - return nil, nil + return DVCRDataSource{}, nil } var dsDVCR DVCRDataSource @@ -144,7 +143,7 @@ func NewDVCRDataSourcesForVMD(ctx context.Context, ds *virtv2.VirtualDiskDataSou if vmiName != "" && vmiNS != "" { vmi, err := helper.FetchObject(ctx, types.NamespacedName{Name: vmiName, Namespace: vmiNS}, client, &virtv2.VirtualImage{}) if err != nil { - return nil, err + return DVCRDataSource{}, err } if vmi != nil { @@ -161,7 +160,7 @@ func NewDVCRDataSourcesForVMD(ctx context.Context, ds *virtv2.VirtualDiskDataSou if cvmiName != "" { cvmi, err := helper.FetchObject(ctx, types.NamespacedName{Name: cvmiName}, client, &virtv2.ClusterVirtualImage{}) if err != nil { - return nil, err + return DVCRDataSource{}, err } if cvmi != nil { @@ -174,7 +173,7 @@ func NewDVCRDataSourcesForVMD(ctx context.Context, ds *virtv2.VirtualDiskDataSou } } - return &dsDVCR, nil + return dsDVCR, nil } func (ds *DVCRDataSource) Validate() error { @@ -189,6 +188,10 @@ func (ds *DVCRDataSource) GetSize() virtv2.ImageStatusSize { return ds.size } +func (ds *DVCRDataSource) IsCDROM() bool { + return imageformat.IsISO(ds.format) +} + func (ds *DVCRDataSource) GetFormat() string { return ds.format } diff --git a/images/virtualization-artifact/pkg/controller/monitoring/final_report.go b/images/virtualization-artifact/pkg/controller/monitoring/final_report.go index d5669f796..f447bf766 100644 --- a/images/virtualization-artifact/pkg/controller/monitoring/final_report.go +++ b/images/virtualization-artifact/pkg/controller/monitoring/final_report.go @@ -64,6 +64,10 @@ func GetFinalReportFromPod(pod *corev1.Pod) (*FinalReport, error) { message := pod.Status.ContainerStatuses[0].State.Terminated.Message + if message == "" { + return nil, ErrTerminationMessageNotFound + } + var report FinalReport err := json.Unmarshal([]byte(message), &report) if err != nil { diff --git a/images/virtualization-artifact/pkg/controller/service/protection_service.go b/images/virtualization-artifact/pkg/controller/service/protection_service.go index 8f6d2dffa..89c8157d4 100644 --- a/images/virtualization-artifact/pkg/controller/service/protection_service.go +++ b/images/virtualization-artifact/pkg/controller/service/protection_service.go @@ -21,8 +21,11 @@ import ( "fmt" "reflect" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + + "github.com/deckhouse/virtualization-controller/pkg/sdk/framework/helper" ) type ProtectionService struct { @@ -42,25 +45,23 @@ func (s ProtectionService) AddOwnerRef(ctx context.Context, owner client.Object, return nil } + ownerRef := MakeOwnerReference(owner) + for _, obj := range objs { if obj == nil || reflect.ValueOf(obj).IsNil() { continue } - err := controllerutil.SetOwnerReference(owner, obj, s.client.Scheme()) - if err != nil { - return err - } - - var patch client.Patch - patch, err = GetPatchOwnerReferences(obj.GetOwnerReferences()) - if err != nil { - return err - } + if helper.SetOwnerRef(obj, ownerRef) { + patch, err := GetPatchOwnerReferences(obj.GetOwnerReferences()) + if err != nil { + return err + } - err = s.client.Patch(ctx, obj, patch) - if err != nil { - return err + err = s.client.Patch(ctx, obj, patch) + if err != nil { + return err + } } } @@ -112,3 +113,12 @@ func (s ProtectionService) RemoveProtection(ctx context.Context, objs ...client. return nil } + +func MakeOwnerReference(owner client.Object) metav1.OwnerReference { + return metav1.OwnerReference{ + APIVersion: owner.GetObjectKind().GroupVersionKind().Version, + Kind: owner.GetObjectKind().GroupVersionKind().Kind, + Name: owner.GetName(), + UID: owner.GetUID(), + } +} diff --git a/images/virtualization-artifact/pkg/controller/vd/internal/source/object_ref.go b/images/virtualization-artifact/pkg/controller/vd/internal/source/object_ref.go index 53c53e55c..8b8316711 100644 --- a/images/virtualization-artifact/pkg/controller/vd/internal/source/object_ref.go +++ b/images/virtualization-artifact/pkg/controller/vd/internal/source/object_ref.go @@ -35,6 +35,7 @@ import ( "github.com/deckhouse/virtualization-controller/pkg/controller/supplements" virtv2 "github.com/deckhouse/virtualization/api/core/v1alpha2" "github.com/deckhouse/virtualization/api/core/v1alpha2/vdcondition" + "github.com/deckhouse/virtualization/api/core/v1alpha2/vicondition" ) type ObjectRefDataSource struct { @@ -113,14 +114,27 @@ func (ds ObjectRefDataSource) Sync(ctx context.Context, vd *virtv2.VirtualDisk) ds.logger.Info("Cleaning up...", "vd", vd.Name) case dv == nil: + var dvcrDataSource controller.DVCRDataSource + dvcrDataSource, err = controller.NewDVCRDataSourcesForVMD(ctx, vd.Spec.DataSource, vd, ds.client) + if err != nil { + return false, err + } + + if !dvcrDataSource.IsReady() { + condition.Status = metav1.ConditionFalse + condition.Reason = vicondition.ProvisioningFailed + condition.Message = "Failed to get stats from non-ready datasource: waiting for the DataSource to be ready." + return false, nil + } + var diskSize resource.Quantity - diskSize, err = ds.getPVCSize(ctx, vd) + diskSize, err = ds.getPVCSize(vd, dvcrDataSource) if err != nil { return false, err } var source *cdiv1.DataVolumeSource - source, err = ds.getSource(ctx, vd, supgen) + source, err = ds.getSource(supgen, dvcrDataSource) if err != nil { return false, err } @@ -243,10 +257,9 @@ func (ds ObjectRefDataSource) Validate(ctx context.Context, vd *virtv2.VirtualDi } } -func (ds ObjectRefDataSource) getSource(ctx context.Context, vd *virtv2.VirtualDisk, sup *supplements.Generator) (*cdiv1.DataVolumeSource, error) { - dvcrDataSource, err := controller.NewDVCRDataSourcesForVMD(ctx, vd.Spec.DataSource, vd, ds.client) - if err != nil { - return nil, err +func (ds ObjectRefDataSource) getSource(sup *supplements.Generator, dvcrDataSource controller.DVCRDataSource) (*cdiv1.DataVolumeSource, error) { + if !dvcrDataSource.IsReady() { + return nil, errors.New("dvcr data source is not ready") } url := common2.DockerRegistrySchemePrefix + dvcrDataSource.GetTarget() @@ -262,10 +275,9 @@ func (ds ObjectRefDataSource) getSource(ctx context.Context, vd *virtv2.VirtualD }, nil } -func (ds ObjectRefDataSource) getPVCSize(ctx context.Context, vd *virtv2.VirtualDisk) (resource.Quantity, error) { - dvcrDataSource, err := controller.NewDVCRDataSourcesForVMD(ctx, vd.Spec.DataSource, vd, ds.client) - if err != nil { - return resource.Quantity{}, err +func (ds ObjectRefDataSource) getPVCSize(vd *virtv2.VirtualDisk, dvcrDataSource controller.DVCRDataSource) (resource.Quantity, error) { + if !dvcrDataSource.IsReady() { + return resource.Quantity{}, errors.New("dvcr data source is not ready") } unpackedSize, err := resource.ParseQuantity(dvcrDataSource.GetSize().UnpackedBytes) diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go index 58557eea4..1f7c6fa29 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref.go @@ -89,7 +89,6 @@ func (ds ObjectRefDataSource) Sync(ctx context.Context, vi *virtv2.VirtualImage) return CleanUp(ctx, vi, ds) case cc.IsTerminating(pod): - vi.Status.Phase = virtv2.ImagePending ds.logger.Info("Cleaning up...", "vi", vi.Name) @@ -129,14 +128,27 @@ func (ds ObjectRefDataSource) Sync(ctx context.Context, vi *virtv2.VirtualImage) } } + var dvcrDataSource controller.DVCRDataSource + dvcrDataSource, err = controller.NewDVCRDataSourcesForVMI(ctx, vi.Spec.DataSource, vi, ds.client) + if err != nil { + return false, err + } + + if !dvcrDataSource.IsReady() { + condition.Status = metav1.ConditionFalse + condition.Reason = vicondition.ProvisioningFailed + condition.Message = "Failed to get stats from non-ready datasource: waiting for the DataSource to be ready." + return false, nil + } + condition.Status = metav1.ConditionTrue condition.Reason = vicondition.Ready condition.Message = "" vi.Status.Phase = virtv2.ImageReady - vi.Status.Size = ds.statService.GetSize(pod) - vi.Status.CDROM = ds.statService.GetCDROM(pod) - vi.Status.Format = ds.statService.GetFormat(pod) + vi.Status.Size = dvcrDataSource.GetSize() + vi.Status.CDROM = dvcrDataSource.IsCDROM() + vi.Status.Format = dvcrDataSource.GetFormat() vi.Status.Progress = "100%" vi.Status.Target.RegistryURL = ds.dvcrSettings.RegistryImageForVMI(vi.Name, vi.Namespace)