@@ -61,33 +61,15 @@ func (u *OperatorUninstall) Run(ctx context.Context) error {
6161 }
6262 }
6363 if sub == nil {
64- return fmt .Errorf ("operator package %q not found" , u .Package )
65- }
66-
67- var subObj , csvObj client.Object
68- var crds []client.Object
69- if sub != nil {
70- subObj = sub
71- // CSV name may either be the installed or current name in a subscription's status,
72- // depending on installation state.
73- csvKey := types.NamespacedName {
74- Name : sub .Status .InstalledCSV ,
75- Namespace : u .config .Namespace ,
76- }
77- if csvKey .Name == "" {
78- csvKey .Name = sub .Status .CurrentCSV
79- }
64+ return & ErrPackageNotFound {u .Package }
65+ }
8066
81- // This value can be empty which will cause errors.
82- if csvKey .Name != "" {
83- csv := & v1alpha1.ClusterServiceVersion {}
84- if err := u .config .Client .Get (ctx , csvKey , csv ); err != nil && ! apierrors .IsNotFound (err ) {
85- return fmt .Errorf ("error getting installed CSV %q: %v" , csvKey .Name , err )
86- } else if err == nil {
87- crds = getCRDs (csv )
88- }
89- csvObj = csv
67+ csv , csvName , err := u .getSubscriptionCSV (ctx , sub )
68+ if err != nil && ! apierrors .IsNotFound (err ) {
69+ if csvName == "" {
70+ return fmt .Errorf ("get subscription CSV: %v" , err )
9071 }
72+ return fmt .Errorf ("get subscription CSV %q: %v" , csvName , err )
9173 }
9274
9375 // Deletion order:
@@ -98,23 +80,26 @@ func (u *OperatorUninstall) Run(ctx context.Context) error {
9880 // and an owner label on every cluster scoped resource so they get gc'd on deletion.
9981
10082 // Subscriptions can be deleted asynchronously.
101- if err := u .deleteObjects (ctx , subObj ); err != nil {
83+ if err := u .deleteObjects (ctx , sub ); err != nil {
10284 return err
10385 }
10486
105- if u . DeleteCRDs {
87+ if csv != nil {
10688 // Ensure CustomResourceDefinitions are deleted next, so that the operator
10789 // has a chance to handle CRs that have finalizers.
108- if err := u .deleteObjects (ctx , crds ... ); err != nil {
109- return err
90+ if u .DeleteCRDs {
91+ crds := getCRDs (csv )
92+ if err := u .deleteObjects (ctx , crds ... ); err != nil {
93+ return err
94+ }
11095 }
111- }
11296
113- // OLM puts an ownerref on every namespaced resource to the CSV,
114- // and an owner label on every cluster scoped resource. When CSV is deleted
115- // kube and olm gc will remove all the referenced resources.
116- if err := u .deleteObjects (ctx , csvObj ); err != nil {
117- return err
97+ // OLM puts an ownerref on every namespaced resource to the CSV,
98+ // and an owner label on every cluster scoped resource. When CSV is deleted
99+ // kube and olm gc will remove all the referenced resources.
100+ if err := u .deleteObjects (ctx , csv ); err != nil {
101+ return err
102+ }
118103 }
119104
120105 if u .DeleteOperatorGroups {
@@ -138,12 +123,6 @@ func (u *OperatorUninstall) Run(ctx context.Context) error {
138123 }
139124 }
140125 }
141-
142- // If no objects were cleaned up, it means the package was not found
143- if subObj == nil && csvObj == nil && len (crds ) == 0 {
144- return & ErrPackageNotFound {u .Package }
145- }
146-
147126 return nil
148127}
149128
@@ -160,6 +139,37 @@ func (u *OperatorUninstall) deleteObjects(ctx context.Context, objs ...client.Ob
160139 return waitForDeletion (ctx , u .config .Client , objs ... )
161140}
162141
142+ // getSubscriptionCSV looks up the installed CSV name from the provided subscription and fetches it.
143+ func (u * OperatorUninstall ) getSubscriptionCSV (ctx context.Context , subscription * v1alpha1.Subscription ) (* v1alpha1.ClusterServiceVersion , string , error ) {
144+ name := csvNameFromSubscription (subscription )
145+
146+ // If we could not find a name in the subscription, that likely
147+ // means there is no CSV associated with it yet. This should
148+ // not be treated as an error, so return a nil CSV with a nil error.
149+ if name == "" {
150+ return nil , "" , nil
151+ }
152+
153+ key := types.NamespacedName {
154+ Name : name ,
155+ Namespace : subscription .GetNamespace (),
156+ }
157+
158+ csv := & v1alpha1.ClusterServiceVersion {}
159+ if err := u .config .Client .Get (ctx , key , csv ); err != nil {
160+ return nil , name , err
161+ }
162+ csv .SetGroupVersionKind (v1alpha1 .SchemeGroupVersion .WithKind (csvKind ))
163+ return csv , name , nil
164+ }
165+
166+ func csvNameFromSubscription (subscription * v1alpha1.Subscription ) string {
167+ if subscription .Status .InstalledCSV != "" {
168+ return subscription .Status .InstalledCSV
169+ }
170+ return subscription .Status .CurrentCSV
171+ }
172+
163173// getCRDs returns the list of CRDs required by a CSV.
164174func getCRDs (csv * v1alpha1.ClusterServiceVersion ) (crds []client.Object ) {
165175 for _ , resource := range csv .Status .RequirementStatus {
0 commit comments