diff --git a/python/src/mas/cli/install/app.py b/python/src/mas/cli/install/app.py index 60b861dda89..b7a62a6e3c5 100644 --- a/python/src/mas/cli/install/app.py +++ b/python/src/mas/cli/install/app.py @@ -626,6 +626,7 @@ def configApps(self): self.installManage = True self.isManageFoundation = True self.setParam("is_full_manage", "false") + self.setParam("mas_app_settings_aio_flag", "false") self.manageAppName = "Manage foundation" self.printDescription([f"{self.manageAppName} installs the following capabilities: User, Security groups, Application configurator and Mobile configurator."]) else: diff --git a/python/src/mas/cli/install/settings/db2Settings.py b/python/src/mas/cli/install/settings/db2Settings.py index fe6b1a70ea2..037f90301aa 100644 --- a/python/src/mas/cli/install/settings/db2Settings.py +++ b/python/src/mas/cli/install/settings/db2Settings.py @@ -13,21 +13,26 @@ class Db2SettingsMixin(): - def configDb2(self) -> None: - self.printH1("Configure Databases") + # In silentMode, no prompts will show up for "happy path" DB2 configuration scenarios. Prompts will still show up when an input is absolutely required + # Settings under showAdvancedOptions are always prompted + def configDb2(self, silentMode=False) -> None: + if not silentMode: + self.printH1("Configure Databases") # The channel used for Db2 used has not changed since the January 2024 catalog update self.params["db2_channel"] = "v110509.0" # If neither Iot or Manage is being installed, we have nothing to do if not self.installIoT and not self.installManage: - print_formatted_text("No applications have been selected that require a Db2 installation") - self.setParam("db2_action_system", "none") - self.setParam("db2_action_manage", "none") + if not silentMode: + print_formatted_text("No applications have been selected that require a Db2 installation") + self.setParam("db2_action_system", "none") + self.setParam("db2_action_manage", "none") return # For now we are limiting users to bring your own database for Manage on s390x # Eventually we will be able to remove this clause and allow the standard logic to work for both s390x and amd64 if self.architecture == "s390x" and self.installManage: + # silentMode does not apply for s390x because it requires interaction when selecting local config directory self.printDescription([ "Installation of a Db2 instance using the IBM Db2 Universal Operator is not currently supported on s390x, please provide configuration details for the database you wish to use.", ]) @@ -51,21 +56,26 @@ def configDb2(self) -> None: # Proceed as normal # We know we are installing either IoT or Manage, and on amd64 target architecture - self.printDescription([ - f"The installer can setup one or more IBM Db2 instances in your OpenShift cluster for the use of applications that require a JDBC datasource (IoT, {self.manageAppName}, Monitor, & Predict) or you may choose to configure MAS to use an existing database" - ]) + if not silentMode: + self.printDescription([ + f"The installer can setup one or more IBM Db2 instances in your OpenShift cluster for the use of applications that require a JDBC datasource (IoT, {self.manageAppName}, Monitor, & Predict) or you may choose to configure MAS to use an existing database" + ]) self.setDB2DefaultSettings() instanceId = self.getParam('mas_instance_id') # Do we need to set up an IoT database? if self.installIoT: - self.printH2("Database Configuration for Maximo IoT") - self.printDescription([ - "Maximo IoT requires a shared system-scope Db2 instance because others application in the suite require access to the same database source", - " - Only IBM Db2 is supported for this database" - ]) - if self.yesOrNo("Create system Db2 instance using the IBM Db2 Universal Operator"): + if not silentMode: + self.printH2("Database Configuration for Maximo IoT") + self.printDescription([ + "Maximo IoT requires a shared system-scope Db2 instance because others application in the suite require access to the same database source", + " - Only IBM Db2 is supported for this database" + ]) + createSystemDb2UsingUniversalOperator = True + if not silentMode: + createSystemDb2UsingUniversalOperator = self.yesOrNo("Create system Db2 instance using the IBM Db2 Universal Operator") + if createSystemDb2UsingUniversalOperator: self.setParam("db2_action_system", "install") else: self.setParam("db2_action_system", "byo") @@ -85,28 +95,39 @@ def configDb2(self) -> None: self.setParam("db2_action_system", "none") if self.installManage: - self.printH2(f"Database Configuration for Maximo {self.manageAppName}") - self.printDescription([ - f"Maximo {self.manageAppName} can be configured to share the system Db2 instance or use it's own dedicated database:", - " - Use of a shared instance has a significant footprint reduction but is only recommended for development/test/demo installs", - " - In most production systems you will want to use a dedicated database", - " - IBM Db2, Oracle Database, & Microsoft SQL Server are all supported database options" - ]) + if not silentMode: + self.printH2(f"Database Configuration for Maximo {self.manageAppName}") + self.printDescription([ + f"Maximo {self.manageAppName} can be configured to share the system Db2 instance or use it's own dedicated database:", + " - Use of a shared instance has a significant footprint reduction but is only recommended for development/test/demo installs", + " - In most production systems you will want to use a dedicated database", + " - IBM Db2, Oracle Database, & Microsoft SQL Server are all supported database options" + ]) # Determine whether to use the system or a dedicated database - if self.installIoT and self.yesOrNo(f"Re-use System Db2 instance for {self.manageAppName} application"): + reuseSystemDb2 = False + if self.installIoT: + if not silentMode: + reuseSystemDb2 = self.yesOrNo(f"Re-use System Db2 instance for {self.manageAppName} application") + if reuseSystemDb2: # We are going to bind Manage to the system database, which has already been set up in the previous step self.setParam("mas_appws_bindings_jdbc_manage", "system") self.setParam("db2_action_manage", "none") else: self.setParam("mas_appws_bindings_jdbc_manage", "workspace-application") - if self.yesOrNo(f"Create {self.manageAppName} dedicated Db2 instance using the IBM Db2 Universal Operator"): + createSystemDb2UsingUniversalOperator = True + if not silentMode: + createSystemDb2UsingUniversalOperator = self.yesOrNo(f"Create {self.manageAppName} dedicated Db2 instance using the IBM Db2 Universal Operator") + if createSystemDb2UsingUniversalOperator: self.setParam("db2_action_manage", "install") - self.printDescription([ - f"Available Db2 instance types for {self.manageAppName}:", - " 1. DB2 Warehouse (Default option)", - " 2. DB2 Online Transactional Processing (OLTP)" - ]) - self.promptForListSelect(message=f"Select the {self.manageAppName} dedicated DB2 instance type", options=["db2wh", "db2oltp"], param="db2_type", default="1") + if not silentMode: + self.printDescription([ + f"Available Db2 instance types for {self.manageAppName}:", + " 1. DB2 Warehouse (Default option)", + " 2. DB2 Online Transactional Processing (OLTP)" + ]) + self.promptForListSelect(message=f"Select the {self.manageAppName} dedicated DB2 instance type", options=["db2wh", "db2oltp"], param="db2_type", default="1") + else: + self.setParam("db2_type", "db2wh") else: workspaceId = self.getParam("mas_workspace_id") self.setParam("db2_action_manage", "byo") diff --git a/python/src/mas/cli/upgrade/app.py b/python/src/mas/cli/upgrade/app.py index 34e737f1767..ae4e07857b8 100644 --- a/python/src/mas/cli/upgrade/app.py +++ b/python/src/mas/cli/upgrade/app.py @@ -20,15 +20,16 @@ from ..cli import BaseApp from ..validators import InstanceIDValidator from .argParser import upgradeArgParser +from .settings import UpgradeSettingsMixin from mas.devops.ocp import createNamespace -from mas.devops.mas import listMasInstances, getMasChannel +from mas.devops.mas import listMasInstances, getMasChannel, getWorkspaceId, verifyAppInstance from mas.devops.tekton import installOpenShiftPipelines, updateTektonDefinitions, launchUpgradePipeline logger = logging.getLogger(__name__) -class UpgradeApp(BaseApp): +class UpgradeApp(BaseApp, UpgradeSettingsMixin): def upgrade(self, argv): """ Upgrade MAS instance @@ -38,6 +39,7 @@ def upgrade(self, argv): self.noConfirm = args.no_confirm self.skipPreCheck = args.skip_pre_check self.licenseAccepted = args.accept_license + self.devMode = args.dev_mode if instanceId is None: self.printH1("Set Target OpenShift Cluster") @@ -45,6 +47,8 @@ def upgrade(self, argv): self.connect() else: logger.debug("MAS instance ID is set, so we assume already connected to the desired OCP") + # Need to lookup target architecture because configDb2 will try to access self.architecture + self.lookupTargetArchitecture() if self.dynamicClient is None: print_formatted_text(HTML("Error: The Kubernetes dynamic Client is not available. See log file for details")) @@ -71,16 +75,21 @@ def upgrade(self, argv): currentChannel = getMasChannel(self.dynamicClient, instanceId) if currentChannel is not None: - if currentChannel not in self.upgrade_path: - self.fatalError(f"No upgrade available, {instanceId} is are already on the latest release {currentChannel}") - nextChannel = self.upgrade_path[currentChannel] + if self.devMode: + # This is mainly used for the scenario where Manage Foundation would be installed, because core-upgrade does not use the value of nextChannel, + # it uses a compatibility_matrix object in ansible-devops to determine the next channel, so nextChannel is only informative for core upgrade purposes + nextChannel = prompt(HTML('Custom channel ')) + else: + if currentChannel not in self.upgrade_path: + self.fatalError(f"No upgrade available, {instanceId} is are already on the latest release {currentChannel}") + nextChannel = self.upgrade_path[currentChannel] else: # We still allow the upgrade to proceed even though we can't detect the MAS instance. The upgrade may be being # queued up to run after install for instance currentChannel = "Unknown" nextChannel = "Unknown" - if not self.licenseAccepted: + if not self.licenseAccepted and not self.devMode: self.printH1("License Terms") self.printDescription([ "To continue with the upgrade, you must accept the license terms:", @@ -93,6 +102,30 @@ def upgrade(self, argv): if not self.yesOrNo("Do you accept the license terms"): exit(1) + # The only scenario where Manage Foundation needs to be installed during an upgrade is from 9.0.x to 9.1.x (if Manage was not already installed in 9.0.x). + self.setParam("should_install_manage_foundation", "false") + if nextChannel.startswith("9.1") and not verifyAppInstance(self.dynamicClient, instanceId, "manage"): + self.manageAppName = "Manage foundation" + self.showAdvancedOptions = False + self.installIoT = False + self.installManage = True + self.isManageFoundation = True + self.printDescription([f"{self.manageAppName} installs the following capabilities: User, Security groups, Application configurator and Mobile configurator."]) + self.printH1("Configure IBM Container Registry") + self.promptForString("IBM entitlement key", "ibm_entitlement_key", isPassword=True) + if self.devMode: + self.promptForString("Artifactory username", "artifactory_username") + self.promptForString("Artifactory token", "artifactory_token", isPassword=True) + self.setParam("should_install_manage_foundation", "true") + self.setParam("is_full_manage", "false") + self.setParam("mas_appws_components", "") + self.setParam("mas_app_settings_aio_flag", "false") + self.setParam("mas_app_channel_manage", nextChannel) + self.setParam("mas_workspace_id", getWorkspaceId(self.dynamicClient, instanceId)) + # It has been decided that we don't need to ask for any specific Manage Settings + # self.manageSettings() + self.configDb2(silentMode=True) + self.printH1("Review Settings") print_formatted_text(HTML(f"Instance ID ..................... {instanceId}")) print_formatted_text(HTML(f"Current MAS Channel ............. {currentChannel}")) @@ -101,7 +134,7 @@ def upgrade(self, argv): if not self.noConfirm: print() - continueWithUpgrade = self.yesOrNo("Proceed with these settings?") + continueWithUpgrade = self.yesOrNo("Proceed with these settings") if self.noConfirm or continueWithUpgrade: self.createTektonFileWithDigest() @@ -122,7 +155,7 @@ def upgrade(self, argv): h.stop_and_persist(symbol=self.successIcon, text=f"Latest Tekton definitions are installed (v{self.version})") with Halo(text='Submitting PipelineRun for {instanceId} upgrade', spinner=self.spinner) as h: - pipelineURL = launchUpgradePipeline(self.dynamicClient, instanceId, self.skipPreCheck) + pipelineURL = launchUpgradePipeline(self.dynamicClient, instanceId, self.skipPreCheck, params=self.params) if pipelineURL is not None: h.stop_and_persist(symbol=self.successIcon, text=f"PipelineRun for {instanceId} upgrade submitted") print_formatted_text(HTML(f"\nView progress:\n {pipelineURL}\n")) diff --git a/python/src/mas/cli/upgrade/argParser.py b/python/src/mas/cli/upgrade/argParser.py index c161877ac88..689d370dd79 100644 --- a/python/src/mas/cli/upgrade/argParser.py +++ b/python/src/mas/cli/upgrade/argParser.py @@ -53,6 +53,13 @@ default=False, help="Accept all license terms without prompting" ) +otherArgGroup.add_argument( + "--dev-mode", + required=False, + action="store_true", + default=False, + help="Configure upgrade for development mode", +) otherArgGroup.add_argument( '-h', "--help", action='help', diff --git a/python/src/mas/cli/upgrade/settings/__init__.py b/python/src/mas/cli/upgrade/settings/__init__.py new file mode 100644 index 00000000000..f1385cebf92 --- /dev/null +++ b/python/src/mas/cli/upgrade/settings/__init__.py @@ -0,0 +1,19 @@ +# ***************************************************************************** +# Copyright (c) 2025 IBM Corporation and other Contributors. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# ***************************************************************************** + +from ...install.settings.db2Settings import Db2SettingsMixin +from ...install.settings.manageSettings import ManageSettingsMixin + + +class UpgradeSettingsMixin(Db2SettingsMixin, ManageSettingsMixin): + """ + This class collects all the Mixins providing interactive prompts for mas-upgrade + """ + pass diff --git a/tekton/src/pipelines/upgrade.yml.j2 b/tekton/src/pipelines/upgrade.yml.j2 index 5f513b5db47..d78e27ad1bb 100644 --- a/tekton/src/pipelines/upgrade.yml.j2 +++ b/tekton/src/pipelines/upgrade.yml.j2 @@ -4,24 +4,32 @@ kind: Pipeline metadata: name: mas-upgrade spec: + workspaces: + # The generated configuration files + - name: shared-configs + # PodTemplates configurations + - name: shared-pod-templates params: # 1. Common Parameters # ------------------------------------------------------------------------- {{ lookup('template', params_src_dir ~ '/common.yml.j2') | indent(4) }} + + # 2. Installation (only needed if Manage Foundation is going to be installed) + # ------------------------------------------------------------------------- + {{ lookup('template', params_src_dir ~ '/install-common.yml.j2') | indent(4) }} + {{ lookup('template', params_src_dir ~ '/install.yml.j2') | indent(4) }} - # 2. Upgrade + # 3. Upgrade # ------------------------------------------------------------------------- - name: skip_compatibility_check type: string default: "False" description: Skip performing compatiblity checks before upgrade - # Pipeline config - - name: skip_pre_check + - name: should_install_manage_foundation type: string - default: "" - - {{ lookup('template', params_src_dir ~ '/install-appchannels.yml.j2') | indent(4) }} + description: Set to true if Manage Foundation is supposed to be installed (when upgrading to 9.1 from a 9.0 MAS without Manage) + default: "false" tasks: # 1. Wait for approval & verify health of the cluster before we change anything @@ -78,52 +86,147 @@ spec: runAfter: - core-upgrade + # 3. Install Universal Dependencies (Phase 2) + # 3.1 Db2 + # 3.1.1 System Db2 + {% set tasks = lookup('template', pipeline_src_dir ~ '/taskdefs/dependencies/db2.yml.j2', template_vars={'suffix': 'system'}) | from_yaml %} + {% set task = tasks[0] %} + {% set merged_when = (task.when | default([])) + [{ + 'input': '$(params.should_install_manage_foundation)', + 'operator': 'in', + 'values': ['true'] + }] %} + {% set updated_task = task | combine({'when': merged_when, 'runAfter': ['core-verify']}, recursive=True) %} + {% set task_yaml = [updated_task] | to_nice_yaml(indent=2) %} +{# Add 4 spaces to every line, including the first #} +{{ task_yaml | regex_replace('(?m)^', ' ') }} + + # 3.1.2 Dedicated Manage Db2 + {% set tasks = lookup('template', pipeline_src_dir ~ '/taskdefs/dependencies/db2.yml.j2', template_vars={'suffix': 'manage'}) | from_yaml %} + {% set task = tasks[0] %} + {% set merged_when = (task.when | default([])) + [{ + 'input': '$(params.should_install_manage_foundation)', + 'operator': 'in', + 'values': ['true'] + }] %} + {% set updated_task = task | combine({'when': merged_when, 'runAfter': ['db2-system']}, recursive=True) %} + {% set task_yaml = [updated_task] | to_nice_yaml(indent=2) %} +{# Add 4 spaces to every line, including the first #} +{{ task_yaml | regex_replace('(?m)^', ' ') }} + + # 3.1.3 Configure Db2 in MAS + {% set tasks = lookup('template', pipeline_src_dir ~ '/taskdefs/core/suite-config-db2.yml.j2') | from_yaml %} + {% set task = tasks[0] %} + {% set merged_when = (task.when | default([])) + [{ + 'input': '$(params.should_install_manage_foundation)', + 'operator': 'in', + 'values': ['true'] + }] %} + {% set updated_task = task | combine({'when': merged_when, 'runAfter': ['db2-manage']}, recursive=True) %} + {% set task_yaml = [updated_task] | to_nice_yaml(indent=2) %} +{# Add 4 spaces to every line, including the first #} +{{ task_yaml | regex_replace('(?m)^', ' ') }} - # 3. IoT Upgrade (Phase 2) + # 4. Install & Configure Manage (Phase 3) # ------------------------------------------------------------------------- - - name: app-iot-upgrade + # 4.1. Prepare database for Maxinst + {% set tasks = lookup('template', pipeline_src_dir ~ '/taskdefs/apps/db2-setup-system.yml.j2') | from_yaml %} + {% set task = tasks[0] %} + {% set merged_when = (task.when | default([])) + [{ + 'input': '$(params.should_install_manage_foundation)', + 'operator': 'in', + 'values': ['true'] + }] %} + {% set updated_task = task | combine({'when': merged_when, 'runAfter': ['suite-config-db2']}, recursive=True) %} + {% set task_yaml = [updated_task] | to_nice_yaml(indent=2) %} +{# Add 4 spaces to every line, including the first #} +{{ task_yaml | regex_replace('(?m)^', ' ') }} + + {% set tasks = lookup('template', pipeline_src_dir ~ '/taskdefs/apps/db2-setup-manage.yml.j2') | from_yaml %} + {% set task = tasks[0] %} + {% set merged_when = (task.when | default([])) + [{ + 'input': '$(params.should_install_manage_foundation)', + 'operator': 'in', + 'values': ['true'] + }] %} + {% set updated_task = task | combine({'when': merged_when, 'runAfter': ['suite-config-db2']}, recursive=True) %} + {% set task_yaml = [updated_task] | to_nice_yaml(indent=2) %} +{# Add 4 spaces to every line, including the first #} +{{ task_yaml | regex_replace('(?m)^', ' ') }} + + # 4.2 Manage Install + {% set tasks = lookup('template', pipeline_src_dir ~ '/taskdefs/apps/manage-app.yml.j2') | from_yaml %} + {% set task = tasks[0] %} + {% set merged_when = (task.when | default([])) + [{ + 'input': '$(params.should_install_manage_foundation)', + 'operator': 'in', + 'values': ['true'] + }] %} + {% set updated_task = task | combine({'when': merged_when, 'runAfter': ['suite-db2-setup-system', 'suite-db2-setup-manage']}, recursive=True) %} + {% set task_yaml = [updated_task] | to_nice_yaml(indent=2) %} +{# Add 4 spaces to every line, including the first #} +{{ task_yaml | regex_replace('(?m)^', ' ') }} + + # 4.3 Configure Manage workspace + {% set tasks = lookup('template', pipeline_src_dir ~ '/taskdefs/apps/manage-workspace.yml.j2') | from_yaml %} + {% set task = tasks[0] %} + {% set merged_when = (task.when | default([])) + [{ + 'input': '$(params.should_install_manage_foundation)', + 'operator': 'in', + 'values': ['true'] + }] %} + {% set updated_task = task | combine({'when': merged_when, 'runAfter': ['app-install-manage']}, recursive=True) %} + {% set task_yaml = [updated_task] | to_nice_yaml(indent=2) %} +{# Add 4 spaces to every line, including the first #} +{{ task_yaml | regex_replace('(?m)^', ' ') }} + + # 5. Manage Upgrade (Phase 4) + # ------------------------------------------------------------------------- + - name: app-manage-upgrade timeout: "0" params: - name: mas_instance_id value: $(params.mas_instance_id) - name: mas_app_id - value: iot + value: manage - name: mas_app_channel - value: $(params.mas_app_channel_iot) + value: $(params.mas_app_channel_manage) - name: skip_compatibility_check value: $(params.skip_compatibility_check) - name: devops_suite_name - value: app-iot-upgrade + value: app-manage-upgrade taskRef: kind: Task name: mas-devops-suite-app-upgrade runAfter: - - core-verify - + - app-cfg-manage + when: + - input: "$(params.should_install_manage_foundation)" + operator: notin + values: ["true"] - # 4. Manage Upgrade (Phase 2) + # 6. IoT Upgrade (Phase 5 - after Manage) # ------------------------------------------------------------------------- - - name: app-manage-upgrade + - name: app-iot-upgrade timeout: "0" params: - name: mas_instance_id value: $(params.mas_instance_id) - name: mas_app_id - value: manage + value: iot - name: mas_app_channel - value: $(params.mas_app_channel_manage) + value: $(params.mas_app_channel_iot) - name: skip_compatibility_check value: $(params.skip_compatibility_check) - name: devops_suite_name - value: app-manage-upgrade + value: app-iot-upgrade taskRef: kind: Task name: mas-devops-suite-app-upgrade runAfter: - - core-verify - + - app-manage-upgrade - # 5. Visual Inspection Upgrade (Phase 2) + # 7. Visual Inspection Upgrade (Phase 5 - after Manage) # ------------------------------------------------------------------------- - name: app-visualinspection-upgrade timeout: "0" @@ -142,10 +245,10 @@ spec: kind: Task name: mas-devops-suite-app-upgrade runAfter: - - core-verify + - app-manage-upgrade - # 6. Assist Upgrade (Phase 2) + # 8. Assist Upgrade (Phase 5 - after Manage) # ------------------------------------------------------------------------- - name: app-assist-upgrade timeout: "0" @@ -164,10 +267,10 @@ spec: kind: Task name: mas-devops-suite-app-upgrade runAfter: - - core-verify + - app-manage-upgrade - # 7. Optimizer Upgrade (Phase 2) + # 9. Optimizer Upgrade (Phase 5 - after Manage) # ------------------------------------------------------------------------- - name: app-optimizer-upgrade timeout: "0" @@ -186,66 +289,63 @@ spec: kind: Task name: mas-devops-suite-app-upgrade runAfter: - - core-verify - + - app-manage-upgrade - # 8. Monitor Upgrade (Phase 3 - after IoT) + # 10. Predict Upgrade (Phase 5 - after Manage) # ------------------------------------------------------------------------- - - name: app-monitor-upgrade + - name: app-predict-upgrade timeout: "0" params: - name: mas_instance_id value: $(params.mas_instance_id) - name: mas_app_id - value: monitor + value: predict - name: mas_app_channel - value: $(params.mas_app_channel_monitor) + value: $(params.mas_app_channel_predict) - name: skip_compatibility_check value: $(params.skip_compatibility_check) - name: devops_suite_name - value: app-monitor-upgrade + value: app-predict-upgrade taskRef: kind: Task name: mas-devops-suite-app-upgrade runAfter: - - app-iot-upgrade - + - app-manage-upgrade - # 9. Predict Upgrade (Phase 3 - after Manage) + # 11. Monitor Upgrade (Phase 6 - after IoT) # ------------------------------------------------------------------------- - - name: app-predict-upgrade + - name: app-monitor-upgrade timeout: "0" params: - name: mas_instance_id value: $(params.mas_instance_id) - name: mas_app_id - value: predict + value: monitor - name: mas_app_channel - value: $(params.mas_app_channel_predict) + value: $(params.mas_app_channel_monitor) - name: skip_compatibility_check value: $(params.skip_compatibility_check) - name: devops_suite_name - value: app-predict-upgrade + value: app-monitor-upgrade taskRef: kind: Task name: mas-devops-suite-app-upgrade runAfter: - - app-manage-upgrade - + - app-iot-upgrade - # 10. Verify health of the cluster after upgrade + # 12. Verify health of the cluster after upgrade # ------------------------------------------------------------------------- {{ lookup('template', 'taskdefs/cluster-setup/ocp-verify-all.yml.j2', template_vars={ 'name': 'post-upgrade-verify', 'devops_suite_name': 'post-upgrade-verify' }) | indent(4) }} runAfter: - # Phase 2 apps that don't have a phase 3 app following it + # Phase 5 apps that don't have a phase 6 app following it - app-assist-upgrade - app-optimizer-upgrade - app-visualinspection-upgrade - # Phase 3 apps - app-predict-upgrade + # Phase 6 apps - app-monitor-upgrade finally: