@@ -116,6 +116,9 @@ func (p *PackageRevision) GetPackageRevision(ctx context.Context) (*api.PackageR
116
116
repoPkgRev .Labels [api .LatestPackageRevisionKey ] = api .LatestPackageRevisionValue
117
117
}
118
118
repoPkgRev .Annotations = p .packageRevisionMeta .Annotations
119
+ repoPkgRev .Finalizers = p .packageRevisionMeta .Finalizers
120
+ repoPkgRev .OwnerReferences = p .packageRevisionMeta .OwnerReferences
121
+ repoPkgRev .DeletionTimestamp = p .packageRevisionMeta .DeletionTimestamp
119
122
return repoPkgRev , nil
120
123
}
121
124
@@ -330,12 +333,14 @@ func (cad *cadEngine) CreatePackageRevision(ctx context.Context, repositoryObj *
330
333
return nil , err
331
334
}
332
335
pkgRevMeta := meta.PackageRevisionMeta {
333
- Name : repoPkgRev .KubeObjectName (),
334
- Namespace : repoPkgRev .KubeObjectNamespace (),
335
- Labels : obj .Labels ,
336
- Annotations : obj .Annotations ,
337
- }
338
- pkgRevMeta , err = cad .metadataStore .Create (ctx , pkgRevMeta , repositoryObj )
336
+ Name : repoPkgRev .KubeObjectName (),
337
+ Namespace : repoPkgRev .KubeObjectNamespace (),
338
+ Labels : obj .Labels ,
339
+ Annotations : obj .Annotations ,
340
+ Finalizers : obj .Finalizers ,
341
+ OwnerReferences : obj .OwnerReferences ,
342
+ }
343
+ pkgRevMeta , err = cad .metadataStore .Create (ctx , pkgRevMeta , repositoryObj .Name , repoPkgRev .UID ())
339
344
if err != nil {
340
345
return nil , err
341
346
}
@@ -534,6 +539,26 @@ func (cad *cadEngine) UpdatePackageRevision(ctx context.Context, repositoryObj *
534
539
return nil , err
535
540
}
536
541
542
+ // Check if the PackageRevision is in the terminating state and
543
+ // and this request removes the last finalizer.
544
+ repoPkgRev := oldPackage .repoPackageRevision
545
+ pkgRevMetaNN := types.NamespacedName {
546
+ Name : repoPkgRev .KubeObjectName (),
547
+ Namespace : repoPkgRev .KubeObjectNamespace (),
548
+ }
549
+ pkgRevMeta , err := cad .metadataStore .Get (ctx , pkgRevMetaNN )
550
+ if err != nil {
551
+ return nil , err
552
+ }
553
+ // If this is in the terminating state and we are removing the last finalizer,
554
+ // we delete the resource instead of updating it.
555
+ if pkgRevMeta .DeletionTimestamp != nil && len (newObj .Finalizers ) == 0 {
556
+ if err := cad .deletePackageRevision (ctx , repo , repoPkgRev , pkgRevMeta ); err != nil {
557
+ return nil , err
558
+ }
559
+ return ToPackageRevision (repoPkgRev , pkgRevMeta ), nil
560
+ }
561
+
537
562
// Validate package lifecycle. Can only update a draft.
538
563
switch lifecycle := oldObj .Spec .Lifecycle ; lifecycle {
539
564
default :
@@ -542,21 +567,13 @@ func (cad *cadEngine) UpdatePackageRevision(ctx context.Context, repositoryObj *
542
567
// Draft or proposed can be updated.
543
568
case api .PackageRevisionLifecyclePublished :
544
569
// Only metadata (currently labels and annotations) can be updated for published packages.
545
- repoPkgRev := oldPackage .repoPackageRevision
546
-
547
- pkgRevMeta := meta.PackageRevisionMeta {
548
- Name : repoPkgRev .KubeObjectName (),
549
- Namespace : repoPkgRev .KubeObjectNamespace (),
550
- Labels : newObj .Labels ,
551
- Annotations : newObj .Annotations ,
570
+ pkgRevMeta , err = cad .updatePkgRevMeta (ctx , repoPkgRev , newObj )
571
+ if err != nil {
572
+ return nil , err
552
573
}
553
- cad .metadataStore .Update (ctx , pkgRevMeta )
554
574
555
575
cad .watcherManager .NotifyPackageRevisionChange (watch .Modified , repoPkgRev , pkgRevMeta )
556
- return & PackageRevision {
557
- repoPackageRevision : repoPkgRev ,
558
- packageRevisionMeta : pkgRevMeta ,
559
- }, nil
576
+ return ToPackageRevision (repoPkgRev , pkgRevMeta ), nil
560
577
}
561
578
switch lifecycle := newObj .Spec .Lifecycle ; lifecycle {
562
579
default :
@@ -575,19 +592,13 @@ func (cad *cadEngine) UpdatePackageRevision(ctx context.Context, repositoryObj *
575
592
return nil , err
576
593
}
577
594
578
- pkgRevMeta := meta.PackageRevisionMeta {
579
- Name : repoPkgRev .KubeObjectName (),
580
- Namespace : repoPkgRev .KubeObjectNamespace (),
581
- Labels : newObj .Labels ,
582
- Annotations : newObj .Annotations ,
595
+ pkgRevMeta , err = cad .updatePkgRevMeta (ctx , repoPkgRev , newObj )
596
+ if err != nil {
597
+ return nil , err
583
598
}
584
- cad .metadataStore .Update (ctx , pkgRevMeta )
585
599
586
600
cad .watcherManager .NotifyPackageRevisionChange (watch .Modified , repoPkgRev , pkgRevMeta )
587
- return & PackageRevision {
588
- repoPackageRevision : repoPkgRev ,
589
- packageRevisionMeta : pkgRevMeta ,
590
- }, nil
601
+ return ToPackageRevision (repoPkgRev , pkgRevMeta ), nil
591
602
}
592
603
593
604
var mutations []mutation
@@ -676,24 +687,30 @@ func (cad *cadEngine) UpdatePackageRevision(ctx context.Context, repositoryObj *
676
687
}
677
688
678
689
// Updates are done.
679
- repoPkgRev , err : = draft .Close (ctx )
690
+ repoPkgRev , err = draft .Close (ctx )
680
691
if err != nil {
681
692
return nil , err
682
693
}
683
694
684
- pkgRevMeta := meta.PackageRevisionMeta {
685
- Name : repoPkgRev .KubeObjectName (),
686
- Namespace : repoPkgRev .KubeObjectNamespace (),
687
- Labels : newObj .Labels ,
688
- Annotations : newObj .Annotations ,
695
+ pkgRevMeta , err = cad .updatePkgRevMeta (ctx , repoPkgRev , newObj )
696
+ if err != nil {
697
+ return nil , err
689
698
}
690
- cad .metadataStore .Update (ctx , pkgRevMeta )
691
699
692
700
cad .watcherManager .NotifyPackageRevisionChange (watch .Modified , repoPkgRev , pkgRevMeta )
693
- return & PackageRevision {
694
- repoPackageRevision : repoPkgRev ,
695
- packageRevisionMeta : pkgRevMeta ,
696
- }, nil
701
+ return ToPackageRevision (repoPkgRev , pkgRevMeta ), nil
702
+ }
703
+
704
+ func (cad * cadEngine ) updatePkgRevMeta (ctx context.Context , repoPkgRev repository.PackageRevision , apiPkgRev * api.PackageRevision ) (meta.PackageRevisionMeta , error ) {
705
+ pkgRevMeta := meta.PackageRevisionMeta {
706
+ Name : repoPkgRev .KubeObjectName (),
707
+ Namespace : repoPkgRev .KubeObjectNamespace (),
708
+ Labels : apiPkgRev .Labels ,
709
+ Annotations : apiPkgRev .Annotations ,
710
+ Finalizers : apiPkgRev .Finalizers ,
711
+ OwnerReferences : apiPkgRev .OwnerReferences ,
712
+ }
713
+ return cad .metadataStore .Update (ctx , pkgRevMeta )
697
714
}
698
715
699
716
func createKptfilePatchTask (ctx context.Context , oldPackage repository.PackageRevision , newObj * api.PackageRevision ) (* api.Task , bool , error ) {
@@ -814,19 +831,49 @@ func (cad *cadEngine) DeletePackageRevision(ctx context.Context, repositoryObj *
814
831
return err
815
832
}
816
833
817
- if err := repo .DeletePackageRevision (ctx , oldPackage .repoPackageRevision ); err != nil {
818
- return err
819
- }
820
-
834
+ // We delete the PackageRev regardless of any finalizers, since it
835
+ // will always have the same finalizers as the PackageRevision. This
836
+ // will put the PackageRev, and therefore the PackageRevision in the
837
+ // terminating state.
838
+ // But we only delete the PackageRevision from the repo once all finalizers
839
+ // have been removed.
821
840
namespacedName := types.NamespacedName {
822
841
Name : oldPackage .repoPackageRevision .KubeObjectName (),
823
842
Namespace : oldPackage .repoPackageRevision .KubeObjectNamespace (),
824
843
}
825
- if _ , err := cad .metadataStore .Delete (ctx , namespacedName ); err != nil {
844
+ pkgRevMeta , err := cad .metadataStore .Delete (ctx , namespacedName , false )
845
+ if err != nil {
826
846
return err
827
847
}
828
848
829
- cad .watcherManager .NotifyPackageRevisionChange (watch .Deleted , oldPackage .repoPackageRevision , oldPackage .packageRevisionMeta )
849
+ if len (pkgRevMeta .Finalizers ) > 0 {
850
+ klog .Infof ("PackageRevision %s deleted, but still have finalizers: %s" , oldPackage .KubeObjectName (), strings .Join (pkgRevMeta .Finalizers , "," ))
851
+ cad .watcherManager .NotifyPackageRevisionChange (watch .Modified , oldPackage .repoPackageRevision , oldPackage .packageRevisionMeta )
852
+ return nil
853
+ }
854
+ klog .Infof ("PackageRevision %s deleted for real since no finalizers" , oldPackage .KubeObjectName ())
855
+
856
+ return cad .deletePackageRevision (ctx , repo , oldPackage .repoPackageRevision , oldPackage .packageRevisionMeta )
857
+ }
858
+
859
+ func (cad * cadEngine ) deletePackageRevision (ctx context.Context , repo repository.Repository , repoPkgRev repository.PackageRevision , pkgRevMeta meta.PackageRevisionMeta ) error {
860
+ ctx , span := tracer .Start (ctx , "cadEngine::deletePackageRevision" , trace .WithAttributes ())
861
+ defer span .End ()
862
+
863
+ if err := repo .DeletePackageRevision (ctx , repoPkgRev ); err != nil {
864
+ return err
865
+ }
866
+
867
+ nn := types.NamespacedName {
868
+ Name : pkgRevMeta .Name ,
869
+ Namespace : pkgRevMeta .Namespace ,
870
+ }
871
+ if _ , err := cad .metadataStore .Delete (ctx , nn , true ); err != nil {
872
+ // If this fails, the CR will be cleaned up by the background job.
873
+ klog .Warningf ("Error deleting PkgRevMeta %s: %v" , nn .String (), err )
874
+ }
875
+
876
+ cad .watcherManager .NotifyPackageRevisionChange (watch .Deleted , repoPkgRev , pkgRevMeta )
830
877
return nil
831
878
}
832
879
0 commit comments