From 989577c6d2a769cf6a0dc9ce79a702d5d4e345b8 Mon Sep 17 00:00:00 2001 From: Divyesh Khokhar Date: Sat, 7 Mar 2026 19:23:10 +0530 Subject: [PATCH 01/14] [patch] test odh-rhoai migration --- tekton/src/pipelines/mas-install.yml.j2 | 2 +- tekton/src/pipelines/taskdefs/aiservice/odh.yml.j2 | 3 --- tekton/src/pipelines/taskdefs/aiservice/rhoai.yml.j2 | 3 --- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/tekton/src/pipelines/mas-install.yml.j2 b/tekton/src/pipelines/mas-install.yml.j2 index 340876ab5e7..339a499e95d 100644 --- a/tekton/src/pipelines/mas-install.yml.j2 +++ b/tekton/src/pipelines/mas-install.yml.j2 @@ -207,7 +207,7 @@ spec: # ------------------------------------------------------------------------- {{ lookup('template', pipeline_src_dir ~ '/taskdefs/aiservice/rhoai.yml.j2', template_vars={'application': 'aiservice'}) | indent(4) }} runAfter: - - cert-manager + - aiservice-odh # 5. Install & Configure IBM MAS # ------------------------------------------------------------------------- diff --git a/tekton/src/pipelines/taskdefs/aiservice/odh.yml.j2 b/tekton/src/pipelines/taskdefs/aiservice/odh.yml.j2 index 009cc7ca675..3994b51f204 100644 --- a/tekton/src/pipelines/taskdefs/aiservice/odh.yml.j2 +++ b/tekton/src/pipelines/taskdefs/aiservice/odh.yml.j2 @@ -32,6 +32,3 @@ - input: "$(params.aiservice_channel)" operator: notin values: [""] - - input: "$(params.rhoai)" - operator: notin - values: ["true"] diff --git a/tekton/src/pipelines/taskdefs/aiservice/rhoai.yml.j2 b/tekton/src/pipelines/taskdefs/aiservice/rhoai.yml.j2 index d63e90d0845..54a425cf5cf 100644 --- a/tekton/src/pipelines/taskdefs/aiservice/rhoai.yml.j2 +++ b/tekton/src/pipelines/taskdefs/aiservice/rhoai.yml.j2 @@ -32,6 +32,3 @@ - input: "$(params.aiservice_channel)" operator: notin values: [""] - - input: "$(params.rhoai)" - operator: in - values: ["true"] From b5b40676c78fb3d77dd278dd091b3b341a44e418 Mon Sep 17 00:00:00 2001 From: Divyesh Khokhar Date: Mon, 9 Mar 2026 16:58:12 +0530 Subject: [PATCH 02/14] [patch] rebuild --- tekton/src/pipelines/taskdefs/aiservice/rhoai.yml.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/tekton/src/pipelines/taskdefs/aiservice/rhoai.yml.j2 b/tekton/src/pipelines/taskdefs/aiservice/rhoai.yml.j2 index 54a425cf5cf..c523268baaa 100644 --- a/tekton/src/pipelines/taskdefs/aiservice/rhoai.yml.j2 +++ b/tekton/src/pipelines/taskdefs/aiservice/rhoai.yml.j2 @@ -32,3 +32,4 @@ - input: "$(params.aiservice_channel)" operator: notin values: [""] + From 9fb6b9f0343c3e6349d0bbf78c1b6a6aa2fb75cf Mon Sep 17 00:00:00 2001 From: Divyesh Khokhar Date: Tue, 10 Mar 2026 19:04:04 +0530 Subject: [PATCH 03/14] [patch] test changes --- tekton/src/pipelines/mas-install.yml.j2 | 2 +- tekton/src/pipelines/taskdefs/aiservice/odh.yml.j2 | 3 +++ tekton/src/pipelines/taskdefs/aiservice/rhoai.yml.j2 | 4 +++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/tekton/src/pipelines/mas-install.yml.j2 b/tekton/src/pipelines/mas-install.yml.j2 index 339a499e95d..340876ab5e7 100644 --- a/tekton/src/pipelines/mas-install.yml.j2 +++ b/tekton/src/pipelines/mas-install.yml.j2 @@ -207,7 +207,7 @@ spec: # ------------------------------------------------------------------------- {{ lookup('template', pipeline_src_dir ~ '/taskdefs/aiservice/rhoai.yml.j2', template_vars={'application': 'aiservice'}) | indent(4) }} runAfter: - - aiservice-odh + - cert-manager # 5. Install & Configure IBM MAS # ------------------------------------------------------------------------- diff --git a/tekton/src/pipelines/taskdefs/aiservice/odh.yml.j2 b/tekton/src/pipelines/taskdefs/aiservice/odh.yml.j2 index 3994b51f204..009cc7ca675 100644 --- a/tekton/src/pipelines/taskdefs/aiservice/odh.yml.j2 +++ b/tekton/src/pipelines/taskdefs/aiservice/odh.yml.j2 @@ -32,3 +32,6 @@ - input: "$(params.aiservice_channel)" operator: notin values: [""] + - input: "$(params.rhoai)" + operator: notin + values: ["true"] diff --git a/tekton/src/pipelines/taskdefs/aiservice/rhoai.yml.j2 b/tekton/src/pipelines/taskdefs/aiservice/rhoai.yml.j2 index c523268baaa..d63e90d0845 100644 --- a/tekton/src/pipelines/taskdefs/aiservice/rhoai.yml.j2 +++ b/tekton/src/pipelines/taskdefs/aiservice/rhoai.yml.j2 @@ -32,4 +32,6 @@ - input: "$(params.aiservice_channel)" operator: notin values: [""] - + - input: "$(params.rhoai)" + operator: in + values: ["true"] From af57a91e287ce0a95ed4965467f59f3eef1cf0f3 Mon Sep 17 00:00:00 2001 From: Divyesh Khokhar Date: Tue, 10 Mar 2026 23:05:13 +0530 Subject: [PATCH 04/14] Update README.md --- build/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/build/README.md b/build/README.md index ba5a65c17e1..033d408494d 100644 --- a/build/README.md +++ b/build/README.md @@ -19,3 +19,4 @@ When a build contains multiple commits the most significant commit "wins". Commits in **Unmanaged Branches** will still result in a new build, but any artifacts published will overwrite the previous release. Effectively there is only a latest version for these branches. + From d8d3c364f2c1f6526ff9c1a4c098850fc1dcfac9 Mon Sep 17 00:00:00 2001 From: Divyesh Khokhar Date: Thu, 19 Mar 2026 15:51:18 +0530 Subject: [PATCH 05/14] [patch] add odh to rhoai migration in mas-update --- python/src/mas/cli/update/app.py | 45 +++++++++++++++++++ tekton/src/pipelines/mas-update.yml.j2 | 11 +++++ .../tasks/dependencies/ibm-catalogs.yml.j2 | 18 ++++++++ 3 files changed, 74 insertions(+) diff --git a/python/src/mas/cli/update/app.py b/python/src/mas/cli/update/app.py index f31599e2853..09c6af9caaf 100644 --- a/python/src/mas/cli/update/app.py +++ b/python/src/mas/cli/update/app.py @@ -133,6 +133,7 @@ def update(self, argv): h.stop_and_persist(symbol=self.successIcon, text="IBM Certificate-Manager is not installed") self.detectGrafana4() + self.detectODH() self.detectMongoDb() self.detectDb2uOrKafka("db2") self.detectDb2uOrKafka("kafka") @@ -173,6 +174,7 @@ def update(self, argv): self.printH2("Required Migrations") self.printSummary("Grafana v4 Operator", "Migrate to Grafana v5 Operator" if self.getParam("grafana_v5_upgrade") != "" else "No action required") + self.printSummary("AI Service Data Science Platform", "Migrate from ODH to RHOAI" if self.getParam("odh_to_rhoai_migration") != "" else "No action required") if not self.noConfirm: print() @@ -336,6 +338,49 @@ def detectGrafana4(self) -> bool: h.stop_and_persist(symbol=self.successIcon, text="Grafana Operator v4 is not installed") return False + def detectODH(self) -> bool: + """ + Detect if ODH (Open Data Hub) is installed and may need migration to RHOAI. + This is a simplified check - the Ansible role will perform detailed validation. + """ + with Halo(text='Checking for Open Data Hub (ODH)', spinner=self.spinner) as h: + try: + # Simple check: Is ODH subscription present in openshift-operators? + # Note: ODH/RHOAI is cluster-wide, not instance-specific + subscriptionAPI = self.dynamicClient.resources.get(api_version="operators.coreos.com/v1alpha1", kind="Subscription") + subscriptions = subscriptionAPI.get(namespace="openshift-operators").to_dict()["items"] + + odh_installed = any( + sub.get("spec", {}).get("name") == "opendatahub-operator" + for sub in subscriptions + ) + + if odh_installed: + h.stop_and_persist(symbol=self.successIcon, text="Open Data Hub detected - migration to RHOAI will be evaluated") + self.printDescription([ + "Required Migration Notice", + "Open Data Hub (ODH) is currently installed and will be migrated to Red Hat OpenShift AI (RHOAI)", + "- This is a cluster-wide migration (affects all AI Service instances)", + "- The update process will automatically handle the migration", + "- ODH will be replaced with RHOAI", + "- This migration is mandatory to continue receiving updates", + "", + "Expected Downtime", + "- AI Service will be unavailable during migration (~10-15 minutes)", + "- Data science workloads will be temporarily interrupted", + "- Deployed models will be preserved" + ]) + # Set parameter for CLI display only + self.setParam("odh_to_rhoai_migration", "true") + return True + else: + h.stop_and_persist(symbol=self.successIcon, text="Open Data Hub is not installed") + return False + + except (ResourceNotFoundError, NotFoundError): + h.stop_and_persist(symbol=self.successIcon, text="Open Data Hub is not installed") + return False + def detectMongoDb(self) -> None: with Halo(text='Checking for MongoDb CE', spinner=self.spinner) as h: # TODO: Replace this with a lookup to just use whatever is already set up diff --git a/tekton/src/pipelines/mas-update.yml.j2 b/tekton/src/pipelines/mas-update.yml.j2 index 2fdccbd1632..06465c88d43 100644 --- a/tekton/src/pipelines/mas-update.yml.j2 +++ b/tekton/src/pipelines/mas-update.yml.j2 @@ -109,6 +109,13 @@ spec: description: Approves the Grafana Operator upgrade to version 5 default: "" + # AI Service Migration (ODH to RHOAI) + # ------------------------------------------------------------------------- + - name: odh_to_rhoai_migration + type: string + default: "" + description: Display-only flag indicating ODH to RHOAI migration will occur (cluster-wide operation) + # CP4D update # ------------------------------------------------------------------------- - name: cpd_product_version @@ -185,6 +192,10 @@ spec: value: $(params.artifactory_username) - name: artifactory_token value: $(params.artifactory_token) + + # AI Service Migration (ODH to RHOAI) + - name: odh_to_rhoai_migration + value: $(params.odh_to_rhoai_migration) # 3. Verify health of the cluster before we consider the update complete diff --git a/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 b/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 index d7dae089f0f..d66f689e326 100644 --- a/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 +++ b/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 @@ -29,6 +29,12 @@ spec: type: string description: Optional. Used to uninstall IBM Catalogs default: "" + + # AI Service Migration (ODH to RHOAI) + - name: odh_to_rhoai_migration + type: string + description: Optional. Display-only flag indicating ODH to RHOAI migration will occur + default: "" stepTemplate: env: @@ -48,6 +54,10 @@ spec: # Optional parameter to uninstall IBM Catalogs - name: IBM_CATALOGS_ACTION value: $(params.ibm_catalogs_action) + + # AI Service Migration (ODH to RHOAI) + - name: ODH_TO_RHOAI_MIGRATION + value: $(params.odh_to_rhoai_migration) steps: - name: ibm-catalogs @@ -57,3 +67,11 @@ spec: image: quay.io/ibmmas/cli:latest imagePullPolicy: $(params.image_pull_policy) workingDir: /workspace/configs + + - name: aiservice-ds-migration + command: + - /opt/app-root/src/run-role.sh + - aiservice_ds_migration + image: quay.io/ibmmas/cli:latest + imagePullPolicy: $(params.image_pull_policy) + workingDir: /workspace/configs From 4db2380e5f169a454fdddb6f993efec5fda308c1 Mon Sep 17 00:00:00 2001 From: Divyesh Khokhar Date: Wed, 25 Mar 2026 23:00:19 +0530 Subject: [PATCH 06/14] [patch] finalize changes --- build/README.md | 1 - python/src/mas/cli/update/app.py | 5 +---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/build/README.md b/build/README.md index 033d408494d..ba5a65c17e1 100644 --- a/build/README.md +++ b/build/README.md @@ -19,4 +19,3 @@ When a build contains multiple commits the most significant commit "wins". Commits in **Unmanaged Branches** will still result in a new build, but any artifacts published will overwrite the previous release. Effectively there is only a latest version for these branches. - diff --git a/python/src/mas/cli/update/app.py b/python/src/mas/cli/update/app.py index 5c90c3f506b..8e06f18a4f7 100644 --- a/python/src/mas/cli/update/app.py +++ b/python/src/mas/cli/update/app.py @@ -345,8 +345,6 @@ def detectODH(self) -> bool: """ with Halo(text='Checking for Open Data Hub (ODH)', spinner=self.spinner) as h: try: - # Simple check: Is ODH subscription present in openshift-operators? - # Note: ODH/RHOAI is cluster-wide, not instance-specific subscriptionAPI = self.dynamicClient.resources.get(api_version="operators.coreos.com/v1alpha1", kind="Subscription") subscriptions = subscriptionAPI.get(namespace="openshift-operators").to_dict()["items"] @@ -360,13 +358,12 @@ def detectODH(self) -> bool: self.printDescription([ "Required Migration Notice", "Open Data Hub (ODH) is currently installed and will be migrated to Red Hat OpenShift AI (RHOAI)", - "- This is a cluster-wide migration (affects all AI Service instances)", "- The update process will automatically handle the migration", "- ODH will be replaced with RHOAI", "- This migration is mandatory to continue receiving updates", "", "Expected Downtime", - "- AI Service will be unavailable during migration (~10-15 minutes)", + "- AI Service will be unavailable during migration (~10-12 minutes)", "- Data science workloads will be temporarily interrupted", "- Deployed models will be preserved" ]) From 43e425ab5bf9fb9b4edad645dcefc956c1f8eb9b Mon Sep 17 00:00:00 2001 From: Divyesh Khokhar Date: Wed, 25 Mar 2026 23:14:15 +0530 Subject: [PATCH 07/14] [patch] --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 58545c0f74e..3887eacaab0 100644 --- a/README.md +++ b/README.md @@ -19,3 +19,4 @@ Want to contribute to MAS Command Line Interface? ------------------------------------------------------------------------------- We welcome every Maximo Application Suite users, developers and enthusiasts to contribute to the MAS Command Line Interface while fixing code issues and implementing new automated functionalities. You can contribute to this collection by raising [a new issue](https://github.com/ibm-mas/cli/issues) with suggestions on how to make our MAS automation engine even better, or if you want to become a new code contributor, please refer to the [Contributing Guidelines](CONTRIBUTING.md) and learn more about how to get started. + From e235961eaf26e3f935bc63abf1f21f10f033a607 Mon Sep 17 00:00:00 2001 From: Divyesh Khokhar Date: Thu, 26 Mar 2026 15:05:53 +0530 Subject: [PATCH 08/14] [patch] add param to check if migration needed --- tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 b/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 index 5cfde8ce25a..a0deba8baff 100644 --- a/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 +++ b/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 @@ -81,6 +81,10 @@ spec: workingDir: /workspace/configs - name: aiservice-ds-migration + when: + - input: "$(params.odh_to_rhoai_migration)" + operator: in + values: ["true"] command: - /opt/app-root/src/run-role.sh - aiservice_ds_migration From 9221501e322181168e5532380cdc1f8ae0f4c916 Mon Sep 17 00:00:00 2001 From: Divyesh Khokhar Date: Thu, 26 Mar 2026 15:15:31 +0530 Subject: [PATCH 09/14] [patch] fix build failures --- python/src/mas/cli/update/app.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/src/mas/cli/update/app.py b/python/src/mas/cli/update/app.py index 8e06f18a4f7..c29425e8eff 100644 --- a/python/src/mas/cli/update/app.py +++ b/python/src/mas/cli/update/app.py @@ -347,12 +347,12 @@ def detectODH(self) -> bool: try: subscriptionAPI = self.dynamicClient.resources.get(api_version="operators.coreos.com/v1alpha1", kind="Subscription") subscriptions = subscriptionAPI.get(namespace="openshift-operators").to_dict()["items"] - + odh_installed = any( sub.get("spec", {}).get("name") == "opendatahub-operator" for sub in subscriptions ) - + if odh_installed: h.stop_and_persist(symbol=self.successIcon, text="Open Data Hub detected - migration to RHOAI will be evaluated") self.printDescription([ @@ -373,7 +373,7 @@ def detectODH(self) -> bool: else: h.stop_and_persist(symbol=self.successIcon, text="Open Data Hub is not installed") return False - + except (ResourceNotFoundError, NotFoundError): h.stop_and_persist(symbol=self.successIcon, text="Open Data Hub is not installed") return False From 69e7034311a47f920161432b32496b4cdc5a2bb2 Mon Sep 17 00:00:00 2001 From: Divyesh Khokhar Date: Thu, 26 Mar 2026 22:22:51 +0530 Subject: [PATCH 10/14] [patch] Finalize changes --- README.md | 1 - python/src/mas/cli/update/app.py | 2 +- tekton/src/pipelines/mas-update.yml.j2 | 2 +- tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3887eacaab0..58545c0f74e 100644 --- a/README.md +++ b/README.md @@ -19,4 +19,3 @@ Want to contribute to MAS Command Line Interface? ------------------------------------------------------------------------------- We welcome every Maximo Application Suite users, developers and enthusiasts to contribute to the MAS Command Line Interface while fixing code issues and implementing new automated functionalities. You can contribute to this collection by raising [a new issue](https://github.com/ibm-mas/cli/issues) with suggestions on how to make our MAS automation engine even better, or if you want to become a new code contributor, please refer to the [Contributing Guidelines](CONTRIBUTING.md) and learn more about how to get started. - diff --git a/python/src/mas/cli/update/app.py b/python/src/mas/cli/update/app.py index c29425e8eff..3bde93546d5 100644 --- a/python/src/mas/cli/update/app.py +++ b/python/src/mas/cli/update/app.py @@ -367,7 +367,7 @@ def detectODH(self) -> bool: "- Data science workloads will be temporarily interrupted", "- Deployed models will be preserved" ]) - # Set parameter for CLI display only + # Set parameter to trigger ODH to RHOAI migration self.setParam("odh_to_rhoai_migration", "true") return True else: diff --git a/tekton/src/pipelines/mas-update.yml.j2 b/tekton/src/pipelines/mas-update.yml.j2 index 06465c88d43..0de193a22df 100644 --- a/tekton/src/pipelines/mas-update.yml.j2 +++ b/tekton/src/pipelines/mas-update.yml.j2 @@ -114,7 +114,7 @@ spec: - name: odh_to_rhoai_migration type: string default: "" - description: Display-only flag indicating ODH to RHOAI migration will occur (cluster-wide operation) + description: Set to "true" to trigger ODH to RHOAI migration during update # CP4D update # ------------------------------------------------------------------------- diff --git a/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 b/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 index a0deba8baff..e238cf3151e 100644 --- a/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 +++ b/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 @@ -33,7 +33,7 @@ spec: # AI Service Migration (ODH to RHOAI) - name: odh_to_rhoai_migration type: string - description: Optional. Display-only flag indicating ODH to RHOAI migration will occur + description: Optional. Set to "true" to trigger ODH to RHOAI migration default: "" # Backup/Restore specific parameters From 2db57eb0f7e6eb965aa410024529778b352c50bc Mon Sep 17 00:00:00 2001 From: Divyesh Khokhar Date: Thu, 2 Apr 2026 12:08:25 +0530 Subject: [PATCH 11/14] [patch] update role for migration --- tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 b/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 index e238cf3151e..57f5f6702d6 100644 --- a/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 +++ b/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 @@ -80,14 +80,14 @@ spec: imagePullPolicy: $(params.image_pull_policy) workingDir: /workspace/configs - - name: aiservice-ds-migration + - name: aiservice-rhoai-install when: - input: "$(params.odh_to_rhoai_migration)" operator: in values: ["true"] command: - /opt/app-root/src/run-role.sh - - aiservice_ds_migration + - aiservice_rhoai image: quay.io/ibmmas/cli:latest imagePullPolicy: $(params.image_pull_policy) workingDir: /workspace/configs From 49ef2414ac24b870f163a66ee7d6240fc79abcde Mon Sep 17 00:00:00 2001 From: Divyesh Khokhar Date: Fri, 3 Apr 2026 13:43:27 +0530 Subject: [PATCH 12/14] [patch] add detection for odh to display notice --- python/src/mas/cli/aiservice/upgrade/app.py | 45 +++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/python/src/mas/cli/aiservice/upgrade/app.py b/python/src/mas/cli/aiservice/upgrade/app.py index c7d27ad86b3..3d32532fc15 100644 --- a/python/src/mas/cli/aiservice/upgrade/app.py +++ b/python/src/mas/cli/aiservice/upgrade/app.py @@ -85,6 +85,9 @@ def upgrade(self, argv): self.fatalError(f"No upgrade available, {aiserviceInstanceId} is are already on the latest release {currentAiserviceChannel}") nextAiserviceChannel = self.upgrade_path[currentAiserviceChannel] + # Detect ODH and notify user about migration + odhDetected = self.detectODH() + if not self.licenseAccepted and not self.devMode: self.printH1("License Terms") self.printDescription([ @@ -103,6 +106,9 @@ def upgrade(self, argv): print_formatted_text(HTML(f"Current AI Service Channel ............. {currentAiserviceChannel}")) print_formatted_text(HTML(f"Next AI Service Channel ................ {nextAiserviceChannel}")) print_formatted_text(HTML(f"Skip Pre-Upgrade Checks ......... {self.skipPreCheck}")) + print() + print_formatted_text(HTML("Required Migrations")) + print_formatted_text(HTML(f"AI Service Data Science Platform ........ {'Migrate from ODH to RHOAI' if odhDetected else 'No action required'}")) if not self.noConfirm: print() @@ -136,4 +142,43 @@ def upgrade(self, argv): print_formatted_text(HTML(f"\nView progress:\n {pipelineURL}\n")) else: h.stop_and_persist(symbol=self.failureIcon, text=f"Failed to submit PipelineRun for {aiserviceInstanceId} upgrade, see log file for details") + + def detectODH(self) -> bool: + """ + Detect if ODH (Open Data Hub) is installed and may need migration to RHOAI. + This is a simplified check - the Ansible role will perform detailed validation. + """ + with Halo(text='Checking for Open Data Hub (ODH)', spinner=self.spinner) as h: + try: + subscriptionAPI = self.dynamicClient.resources.get(api_version="operators.coreos.com/v1alpha1", kind="Subscription") + subscriptions = subscriptionAPI.get(namespace="openshift-operators").to_dict()["items"] + + odh_installed = any( + sub.get("spec", {}).get("name") == "opendatahub-operator" + for sub in subscriptions + ) + + if odh_installed: + h.stop_and_persist(symbol=self.successIcon, text="Open Data Hub detected - migration to RHOAI will be performed") + print() + self.printDescription([ + "Required Migration Notice", + "Open Data Hub (ODH) is currently installed and will be migrated to Red Hat OpenShift AI (RHOAI)", + "- The upgrade process will automatically handle the migration", + "- ODH will be replaced with RHOAI", + "- This migration is mandatory to continue receiving updates", + "", + "Expected Downtime", + "- AI Service will be unavailable during migration (~10-12 minutes)", + "- Data science workloads will be temporarily interrupted", + "- Deployed models will be preserved" + ]) print() + return True + else: + h.stop_and_persist(symbol=self.successIcon, text="Open Data Hub is not installed") + return False + + except (ResourceNotFoundError, NotFoundError): + h.stop_and_persist(symbol=self.successIcon, text="Open Data Hub is not installed") + return False From ad0a97fd8fe48474ab87cd0e9551d675a8096461 Mon Sep 17 00:00:00 2001 From: Divyesh Khokhar Date: Fri, 3 Apr 2026 14:11:58 +0530 Subject: [PATCH 13/14] [patch] fix failure --- python/src/mas/cli/aiservice/upgrade/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/src/mas/cli/aiservice/upgrade/app.py b/python/src/mas/cli/aiservice/upgrade/app.py index 3d32532fc15..0053ab89abf 100644 --- a/python/src/mas/cli/aiservice/upgrade/app.py +++ b/python/src/mas/cli/aiservice/upgrade/app.py @@ -179,6 +179,6 @@ def detectODH(self) -> bool: h.stop_and_persist(symbol=self.successIcon, text="Open Data Hub is not installed") return False - except (ResourceNotFoundError, NotFoundError): + except ResourceNotFoundError: h.stop_and_persist(symbol=self.successIcon, text="Open Data Hub is not installed") return False From b41948da1de24b511e1ee030ae315b90b3f95faa Mon Sep 17 00:00:00 2001 From: Divyesh Khokhar Date: Mon, 13 Apr 2026 15:14:44 +0530 Subject: [PATCH 14/14] [patch] cleanup --- tekton/src/pipelines/mas-update.yml.j2 | 4 ---- .../tasks/dependencies/ibm-catalogs.yml.j2 | 22 ------------------- 2 files changed, 26 deletions(-) diff --git a/tekton/src/pipelines/mas-update.yml.j2 b/tekton/src/pipelines/mas-update.yml.j2 index 3872b9649ab..a54c077e398 100644 --- a/tekton/src/pipelines/mas-update.yml.j2 +++ b/tekton/src/pipelines/mas-update.yml.j2 @@ -192,10 +192,6 @@ spec: value: $(params.artifactory_username) - name: artifactory_token value: $(params.artifactory_token) - - # AI Service Migration (ODH to RHOAI) - - name: odh_to_rhoai_migration - value: $(params.odh_to_rhoai_migration) # 3. Verify health of the cluster before we consider the update complete diff --git a/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 b/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 index 57f5f6702d6..b2dc8aa7cba 100644 --- a/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 +++ b/tekton/src/tasks/dependencies/ibm-catalogs.yml.j2 @@ -29,12 +29,6 @@ spec: type: string description: Optional. Used to uninstall IBM Catalogs default: "" - - # AI Service Migration (ODH to RHOAI) - - name: odh_to_rhoai_migration - type: string - description: Optional. Set to "true" to trigger ODH to RHOAI migration - default: "" # Backup/Restore specific parameters - name: ibm_catalogs_backup_version @@ -60,10 +54,6 @@ spec: # Optional parameter to uninstall IBM Catalogs - name: IBM_CATALOGS_ACTION value: $(params.ibm_catalogs_action) - - # AI Service Migration (ODH to RHOAI) - - name: ODH_TO_RHOAI_MIGRATION - value: $(params.odh_to_rhoai_migration) # Backup/Restore specific - name: MAS_BACKUP_DIR @@ -79,18 +69,6 @@ spec: image: quay.io/ibmmas/cli:latest imagePullPolicy: $(params.image_pull_policy) workingDir: /workspace/configs - - - name: aiservice-rhoai-install - when: - - input: "$(params.odh_to_rhoai_migration)" - operator: in - values: ["true"] - command: - - /opt/app-root/src/run-role.sh - - aiservice_rhoai - image: quay.io/ibmmas/cli:latest - imagePullPolicy: $(params.image_pull_policy) - workingDir: /workspace/configs workspaces: - name: backups