77 "errors"
88 "fmt"
99 "reflect"
10- "strings"
11- "time"
1210
1311 "github.com/hashicorp/go-multierror"
1412 operatorv1 "github.com/openshift/api/operator/v1"
@@ -23,7 +21,6 @@ import (
2321 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2422 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2523 "k8s.io/apimachinery/pkg/runtime/schema"
26- "k8s.io/apimachinery/pkg/util/wait"
2724 "sigs.k8s.io/controller-runtime/pkg/client"
2825
2926 kfdefv1 "github.com/opendatahub-io/opendatahub-operator/apis/kfdef.apps.kubeflow.org/v1"
@@ -44,7 +41,6 @@ import (
4441 "github.com/opendatahub-io/opendatahub-operator/v2/components/workbenches"
4542 "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster"
4643 "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster/gvk"
47- "github.com/opendatahub-io/opendatahub-operator/v2/pkg/metadata/labels"
4844)
4945
5046type ResourceSpec struct {
@@ -178,95 +174,6 @@ func CreateDefaultDSCI(ctx context.Context, cli client.Client, _ cluster.Platfor
178174 return nil
179175}
180176
181- func UpdateFromLegacyVersion (cli client.Client , platform cluster.Platform , appNS string , montNamespace string ) error {
182- // If platform is Managed, remove Kfdefs and create default dsc
183- if platform == cluster .ManagedRhods {
184- fmt .Println ("starting deletion of Deployment in managed cluster" )
185- if err := deleteResource (cli , appNS , "deployment" ); err != nil {
186- return err
187- }
188- // this is for the modelmesh monitoring part from v1 to v2
189- if err := deleteResource (cli , montNamespace , "deployment" ); err != nil {
190- return err
191- }
192- if err := deleteResource (cli , montNamespace , "statefulset" ); err != nil {
193- return err
194- }
195- // only for downstream since ODH has a different way to create this CR by dashboard
196- if err := unsetOwnerReference (cli , "odh-dashboard-config" , appNS ); err != nil {
197- return err
198- }
199-
200- // remove label created by previous v2 release which is problematic for Managed cluster
201- fmt .Println ("removing labels on Operator Namespace" )
202- operatorNamespace , err := cluster .GetOperatorNamespace ()
203- if err != nil {
204- return err
205- }
206- if err := RemoveLabel (cli , operatorNamespace , labels .SecurityEnforce ); err != nil {
207- return err
208- }
209-
210- fmt .Println ("creating default DSC CR" )
211- if err := CreateDefaultDSC (context .TODO (), cli ); err != nil {
212- return err
213- }
214- return RemoveKfDefInstances (context .TODO (), cli )
215- }
216-
217- if platform == cluster .SelfManagedRhods {
218- // remove label created by previous v2 release which is problematic for Managed cluster
219- fmt .Println ("removing labels on Operator Namespace" )
220- operatorNamespace , err := cluster .GetOperatorNamespace ()
221- if err != nil {
222- return err
223- }
224- if err := RemoveLabel (cli , operatorNamespace , labels .SecurityEnforce ); err != nil {
225- return err
226- }
227- // If KfDef CRD is not found, we see it as a cluster not pre-installed v1 operator // Check if kfdef are deployed
228- kfdefCrd := & apiextv1.CustomResourceDefinition {}
229- if err := cli .Get (context .TODO (), client.ObjectKey {Name : "kfdefs.kfdef.apps.kubeflow.org" }, kfdefCrd ); err != nil {
230- if apierrs .IsNotFound (err ) {
231- // If no Crd found, return, since its a new Installation
232- // return empty list
233- return nil
234- }
235- return fmt .Errorf ("error retrieving kfdef CRD : %w" , err )
236- }
237-
238- // If KfDef Instances found, and no DSC instances are found in Self-managed, that means this is an upgrade path from
239- // legacy version. Create a default DSC instance
240- kfDefList := & kfdefv1.KfDefList {}
241- err = cli .List (context .TODO (), kfDefList )
242- if err != nil {
243- return fmt .Errorf ("error getting kfdef instances: : %w" , err )
244- }
245- fmt .Println ("starting deletion of Deployment in selfmanaged cluster" )
246- if len (kfDefList .Items ) > 0 {
247- if err = deleteResource (cli , appNS , "deployment" ); err != nil {
248- return fmt .Errorf ("error deleting deployment: %w" , err )
249- }
250- // this is for the modelmesh monitoring part from v1 to v2
251- if err := deleteResource (cli , montNamespace , "deployment" ); err != nil {
252- return err
253- }
254- if err := deleteResource (cli , montNamespace , "statefulset" ); err != nil {
255- return err
256- }
257- // only for downstream since ODH has a different way to create this CR by dashboard
258- if err := unsetOwnerReference (cli , "odh-dashboard-config" , appNS ); err != nil {
259- return err
260- }
261- // create default DSC
262- if err = CreateDefaultDSC (context .TODO (), cli ); err != nil {
263- return err
264- }
265- }
266- }
267- return nil
268- }
269-
270177func getJPHOdhDocumentResources (namespace string , matchedName []string ) []ResourceSpec {
271178 metadataName := []string {"metadata" , "name" }
272179 return []ResourceSpec {
@@ -342,7 +249,7 @@ func CleanupExistingResource(ctx context.Context, cli client.Client, platform cl
342249 deprecatedOperatorSM := []string {"rhods-monitor-federation2" }
343250 multiErr = multierror .Append (multiErr , deleteDeprecatedServiceMonitors (ctx , cli , dscMonitoringNamespace , deprecatedOperatorSM ))
344251
345- // Remove deprecated opendatahub namespace(owned by kuberay)
252+ // Remove deprecated opendatahub namespace(previously owned by kuberay and Kueue )
346253 multiErr = multierror .Append (multiErr , deleteDeprecatedNamespace (ctx , cli , "opendatahub" ))
347254
348255 // Handling for dashboard OdhApplication Jupyterhub CR, see jira #443
@@ -358,6 +265,12 @@ func CleanupExistingResource(ctx context.Context, cli client.Client, platform cl
358265 "jupyterhub-use-s3-bucket-data" ,
359266 })
360267 multiErr = multierror .Append (multiErr , deleteResources (ctx , cli , & odhDocJPH ))
268+ // only apply on RHOAI since ODH has a different way to create this CR by dashboard
269+ if platform == cluster .SelfManagedRhods || platform == cluster .ManagedRhods {
270+ if err := unsetOwnerReference (cli , "odh-dashboard-config" , dscApplicationsNamespace ); err != nil {
271+ return err
272+ }
273+ }
361274
362275 // to take a reference
363276 toDelete := getDashboardWatsonResources (dscApplicationsNamespace )
@@ -552,145 +465,6 @@ func unsetOwnerReference(cli client.Client, instanceName string, applicationNS s
552465 return nil
553466}
554467
555- func deleteResource (cli client.Client , namespace string , resourceType string ) error {
556- // In v2, Deployment selectors use a label "app.opendatahub.io/<componentName>" which is
557- // not present in v1. Since label selectors are immutable, we need to delete the existing
558- // deployments and recreated them.
559- // because we can't proceed if a deployment is not deleted, we use exponential backoff
560- // to retry the deletion until it succeeds
561- var err error
562- switch resourceType {
563- case "deployment" :
564- err = wait .ExponentialBackoffWithContext (context .TODO (), wait.Backoff {
565- // 5, 10, ,20, 40 then timeout
566- Duration : 5 * time .Second ,
567- Factor : 2.0 ,
568- Jitter : 0.1 ,
569- Steps : 4 ,
570- Cap : 1 * time .Minute ,
571- }, func (ctx context.Context ) (bool , error ) {
572- done , err := deleteDeploymentsAndCheck (ctx , cli , namespace )
573- return done , err
574- })
575- case "statefulset" :
576- err = wait .ExponentialBackoffWithContext (context .TODO (), wait.Backoff {
577- // 10, 20 then timeout
578- Duration : 10 * time .Second ,
579- Factor : 2.0 ,
580- Jitter : 0.1 ,
581- Steps : 2 ,
582- Cap : 1 * time .Minute ,
583- }, func (ctx context.Context ) (bool , error ) {
584- done , err := deleteStatefulsetsAndCheck (ctx , cli , namespace )
585- return done , err
586- })
587- }
588- return err
589- }
590-
591- func deleteDeploymentsAndCheck (ctx context.Context , cli client.Client , namespace string ) (bool , error ) {
592- // Delete Deployment objects
593- var multiErr * multierror.Error
594- deployments := & appsv1.DeploymentList {}
595- listOpts := & client.ListOptions {
596- Namespace : namespace ,
597- }
598-
599- if err := cli .List (ctx , deployments , listOpts ); err != nil {
600- return false , nil //nolint:nilerr
601- }
602- // filter deployment which has the new label to limit that we do not overkill other deployment
603- // this logic can be used even when upgrade from v2.4 to v2.5 without remove it
604- markedForDeletion := []appsv1.Deployment {}
605- for _ , deployment := range deployments .Items {
606- deployment := deployment
607- v2 := false
608- selectorLabels := deployment .Spec .Selector .MatchLabels
609- for label := range selectorLabels {
610- if strings .Contains (label , labels .ODHAppPrefix ) {
611- // this deployment has the new label, this is a v2 to v2 upgrade
612- // there is no need to recreate it, as labels are matching
613- v2 = true
614- continue
615- }
616- }
617- if ! v2 {
618- markedForDeletion = append (markedForDeletion , deployment )
619- multiErr = multierror .Append (multiErr , cli .Delete (ctx , & deployment ))
620- }
621- }
622-
623- for _ , deployment := range markedForDeletion {
624- deployment := deployment
625- if e := cli .Get (ctx , client.ObjectKey {
626- Namespace : namespace ,
627- Name : deployment .Name ,
628- }, & deployment ); e != nil {
629- if apierrs .IsNotFound (e ) {
630- // resource has been successfully deleted
631- continue
632- }
633- // unexpected error, report it
634- multiErr = multierror .Append (multiErr , e ) //nolint:staticcheck,wastedassign
635- }
636- // resource still exists, wait for it to be deleted
637- return false , nil
638- }
639-
640- return true , multiErr .ErrorOrNil ()
641- }
642-
643- func deleteStatefulsetsAndCheck (ctx context.Context , cli client.Client , namespace string ) (bool , error ) {
644- // Delete statefulset objects
645- var multiErr * multierror.Error
646- statefulsets := & appsv1.StatefulSetList {}
647- listOpts := & client.ListOptions {
648- Namespace : namespace ,
649- }
650-
651- if err := cli .List (ctx , statefulsets , listOpts ); err != nil {
652- return false , nil //nolint:nilerr
653- }
654-
655- // even only we have one item to delete to avoid nil point still use range
656- markedForDeletion := []appsv1.StatefulSet {}
657- for _ , statefulset := range statefulsets .Items {
658- v2 := false
659- statefulset := statefulset
660- selectorLabels := statefulset .Spec .Selector .MatchLabels
661- for label := range selectorLabels {
662- if strings .Contains (label , labels .ODHAppPrefix ) {
663- v2 = true
664- continue
665- }
666- }
667- if ! v2 {
668- markedForDeletion = append (markedForDeletion , statefulset )
669- multiErr = multierror .Append (multiErr , cli .Delete (ctx , & statefulset ))
670- }
671- }
672-
673- for _ , statefulset := range markedForDeletion {
674- statefulset := statefulset
675- if e := cli .Get (ctx , client.ObjectKey {
676- Namespace : namespace ,
677- Name : statefulset .Name ,
678- }, & statefulset ); e != nil {
679- if apierrs .IsNotFound (e ) {
680- // resource has been successfully deleted
681- continue
682- }
683- // unexpected error, report it
684- multiErr = multierror .Append (multiErr , e )
685- } else {
686- // resource still exists, wait for it to be deleted
687- return false , nil
688- }
689- }
690-
691- return true , multiErr .ErrorOrNil ()
692- }
693-
694468func RemoveLabel (cli client.Client , objectName string , labelKey string ) error {
695469 foundNamespace := & corev1.Namespace {}
696470 if err := cli .Get (context .TODO (), client.ObjectKey {Name : objectName }, foundNamespace ); err != nil {
0 commit comments