diff --git a/.github/workflows/build-cli.yml b/.github/workflows/build-cli.yml index 577db84c34..f79df645ff 100644 --- a/.github/workflows/build-cli.yml +++ b/.github/workflows/build-cli.yml @@ -106,6 +106,11 @@ jobs: python -m pip install --upgrade pip pip install .[dev] + if [[ -e $GITHUB_WORKSPACE/image/cli/install/mas_devops.tar.gz ]]; then + echo "Found local Python package ($GITHUB_WORKSPACE/image/cli/install/mas_devops.tar.gz) in this PR." + python -m pip install $GITHUB_WORKSPACE/image/cli/install/mas_devops.tar.gz + fi + - name: Lint id: lint run: | diff --git a/python/src/mas/cli/cli.py b/python/src/mas/cli/cli.py index 521fe23095..ac2601b1be 100644 --- a/python/src/mas/cli/cli.py +++ b/python/src/mas/cli/cli.py @@ -184,6 +184,21 @@ def __init__(self): }, } + self.licenses = { + "8.9.x": " - https://ibm.biz/MAS89-License", + "8.10.x": " - https://ibm.biz/MAS810-License", + "8.11.x": " - https://ibm.biz/MAS811-License\n - https://ibm.biz/MAXIT81-License", + "9.0.x": " - https://ibm.biz/MAS90-License\n - https://ibm.biz/MaximoIT90-License\n - https://ibm.biz/MAXArcGIS90-License", + "9.1.x-feature": " - https://ibm.biz/MAS90-License\n - https://ibm.biz/MaximoIT90-License\n - https://ibm.biz/MAXArcGIS90-License\n\nBe aware, this channel subscription is supported for non-production use only. \nIt allows early access to new features for evaluation in non-production environments. \nThis subscription is offered alongside and in parallel with our normal maintained streams. \nWhen using this subscription, IBM Support will only accept cases for the latest available bundle deployed in a non-production environment. \nSeverity must be either 3 or 4 and cases cannot be escalated. \nPlease refer to IBM documentation for more details.\n", + } + + self.upgrade_path = { + "9.0.x": "9.1.x-feature", + "8.11.x": "9.0.x", + "8.10.x": "8.11.x", + "8.9.x": "8.10.x", + } + self.spinner = { "interval": 80, "frames": [" ⠋", " ⠙", " ⠹", " ⠸", " ⠼", " ⠴", " ⠦", " ⠧", " ⠇", " ⠏"] diff --git a/python/src/mas/cli/install/app.py b/python/src/mas/cli/install/app.py index 05fd513c66..049d796bcd 100644 --- a/python/src/mas/cli/install/app.py +++ b/python/src/mas/cli/install/app.py @@ -112,19 +112,11 @@ def validateInternalRegistryAvailable(self): @logMethodCall def licensePrompt(self): - licenses = { - "8.9.x": " - https://ibm.biz/MAS89-License", - "8.10.x": " - https://ibm.biz/MAS810-License", - "8.11.x": " - https://ibm.biz/MAS811-License\n - https://ibm.biz/MAXIT81-License", - "9.0.x": " - https://ibm.biz/MAS90-License\n - https://ibm.biz/MaximoIT90-License\n - https://ibm.biz/MAXArcGIS90-License", - "9.1.x-feature": " - https://ibm.biz/MAS90-License\n - https://ibm.biz/MaximoIT90-License\n - https://ibm.biz/MAXArcGIS90-License\n\n - Be aware, this channel subscription is supported for non-production use only. It allows early access to new features for evaluation is non-production environments. This subscription is offered alongside and in parallel with our normal maintained streams. When using this subscription, IBM Support will only accept cases for the latest available bundle deployed in a non-production environment. Severity must be either 3 or 4 and cases cannot be escalated. Please refer to IBM documentation for more details.\n", - } - if not self.licenseAccepted: self.printH1("License Terms") self.printDescription([ "To continue with the installation, you must accept the license terms:", - licenses[self.getParam('mas_channel')] + self.licenses[self.getParam('mas_channel')] ]) if self.noConfirm: @@ -175,62 +167,28 @@ def processCatalogChoice(self) -> list: self.catalogCp4dVersion = self.chosenCatalog["cpd_product_version_default"] self.catalogMongoDbVersion = self.chosenCatalog["mongo_extras_version_default"] - self.catalogReleases = ["9.0.x", "8.11.x", "8.10.x"] - - self.catalogTable = [ - { - "": "Core", - "9.1.x-feature": self.chosenCatalog["mas_core_version"]["9.1.x-feature"], - "9.0.x": self.chosenCatalog["mas_core_version"]["9.0.x"], - "8.11.x": self.chosenCatalog["mas_core_version"]["8.11.x"], - "8.10.x": self.chosenCatalog["mas_core_version"]["8.10.x"] - }, - { - "": "Manage", - "9.1.x-feature": self.chosenCatalog["mas_manage_version"]["9.1.x-feature"], - "9.0.x": self.chosenCatalog["mas_manage_version"]["9.0.x"], - "8.11.x": self.chosenCatalog["mas_manage_version"]["8.11.x"], - "8.10.x": self.chosenCatalog["mas_manage_version"]["8.10.x"] - }, - { - "": "IoT", - "9.0.x": self.chosenCatalog["mas_iot_version"]["9.0.x"], - "8.11.x": self.chosenCatalog["mas_iot_version"]["8.11.x"], - "8.10.x": self.chosenCatalog["mas_iot_version"]["8.10.x"] - }, - { - "": "Monitor", - "9.0.x": self.chosenCatalog["mas_monitor_version"]["9.0.x"], - "8.11.x": self.chosenCatalog["mas_monitor_version"]["8.11.x"], - "8.10.x": self.chosenCatalog["mas_monitor_version"]["8.10.x"] - }, - { - "": "Assist", - "9.0.x": self.chosenCatalog["mas_assist_version"]["9.0.x"], - "8.11.x": self.chosenCatalog["mas_assist_version"]["8.11.x"], - "8.10.x": self.chosenCatalog["mas_assist_version"]["8.10.x"] - }, - { - "": "Optimizer", - "9.1.x-feature": self.chosenCatalog["mas_optimizer_version"]["9.1.x-feature"], - "9.0.x": self.chosenCatalog["mas_optimizer_version"]["9.0.x"], - "8.11.x": self.chosenCatalog["mas_optimizer_version"]["8.11.x"], - "8.10.x": self.chosenCatalog["mas_optimizer_version"]["8.10.x"] - }, - { - "": "Predict", - "9.0.x": self.chosenCatalog["mas_predict_version"]["9.0.x"], - "8.11.x": self.chosenCatalog["mas_predict_version"]["8.11.x"], - "8.10.x": self.chosenCatalog["mas_predict_version"]["8.10.x"] - }, - { - "": "Inspection", - "9.1.x-feature": self.chosenCatalog["mas_visualinspection_version"]["9.1.x-feature"], - "9.0.x": self.chosenCatalog["mas_visualinspection_version"]["9.0.x"], - "8.11.x": self.chosenCatalog["mas_visualinspection_version"]["8.11.x"], - "8.10.x": self.chosenCatalog["mas_visualinspection_version"]["8.10.x"] - } - ] + self.catalogReleases = [] + self.catalogTable = [] + + applications = { + "Core": "mas_core_version", + "Manage": "mas_manage_version", + "IoT": "mas_iot_version", + "Monitor": "mas_monitor_version", + "Assist": "mas_assist_version", + "Optimizer": "mas_optimizer_version", + "Predict": "mas_predict_version", + "Inspection": "mas_visualinspection_version", + } + + # Dynamically fetch the channels from the chosen catalog + # based on mas core + for channel in self.chosenCatalog["mas_core_version"]: + self.catalogReleases.append(channel) + + # Generate catalogTable + for application, key in applications.items(): + self.catalogTable.append({"": application} | self.chosenCatalog[key]) summary = [ "", diff --git a/python/src/mas/cli/install/catalogs.py b/python/src/mas/cli/install/catalogs.py index b9db5ce93a..d5c0566756 100644 --- a/python/src/mas/cli/install/catalogs.py +++ b/python/src/mas/cli/install/catalogs.py @@ -9,13 +9,13 @@ # ***************************************************************************** supportedCatalogs = { "amd64": [ + "v9-241205-amd64", "v9-241107-amd64", "v9-241003-amd64", "v9-240827-amd64", - "v9-241205-amd64" ], "s390x": [ + "v9-241205-s390x", "v9-241107-s390x", - "v9-241205-s390x" - ] + ], } diff --git a/python/src/mas/cli/upgrade/app.py b/python/src/mas/cli/upgrade/app.py index 8256686601..d97a9880fd 100644 --- a/python/src/mas/cli/upgrade/app.py +++ b/python/src/mas/cli/upgrade/app.py @@ -22,7 +22,7 @@ from .argParser import upgradeArgParser from mas.devops.ocp import createNamespace -from mas.devops.mas import listMasInstances, verifyMasInstance +from mas.devops.mas import listMasInstances, verifyMasInstance, getMasChannel from mas.devops.tekton import installOpenShiftPipelines, updateTektonDefinitions, launchUpgradePipeline logger = logging.getLogger(__name__) @@ -37,6 +37,8 @@ def upgrade(self, argv): instanceId = args.mas_instance_id self.noConfirm = args.no_confirm self.skipPreCheck = args.skip_pre_check + self.licenseAccepted = args.accept_license + next_mas_channel = None if instanceId is None: self.printH1("Set Target OpenShift Cluster") @@ -73,8 +75,30 @@ def upgrade(self, argv): print_formatted_text(HTML(f"Error: MAS instance {instanceId} not found on this cluster")) sys.exit(1) + current_mas_channel = getMasChannel(self.dynamicClient, instanceId) + + if current_mas_channel not in self.upgrade_path: + self.fatalError(f"No upgrade available, {instanceId} is are already on the latest release {current_mas_channel}") + + next_mas_channel = self.upgrade_path[current_mas_channel] + + if not self.licenseAccepted: + self.printH1("License Terms") + self.printDescription([ + "To continue with the upgrade, you must accept the license terms:", + self.licenses[next_mas_channel] + ]) + + if self.noConfirm: + self.fatalError("You must accept the license terms with --accept-license when using the --no-confirm flag") + else: + if not self.yesOrNo("Do you accept the license terms"): + exit(1) + self.printH1("Review Settings") print_formatted_text(HTML(f"Instance ID ..................... {instanceId}")) + print_formatted_text(HTML(f"Current MAS Channel ............. {current_mas_channel}")) + print_formatted_text(HTML(f"Next MAS Channel ................ {next_mas_channel}")) print_formatted_text(HTML(f"Skip Pre-Upgrade Checks ......... {self.skipPreCheck}")) if not self.noConfirm: diff --git a/python/src/mas/cli/upgrade/argParser.py b/python/src/mas/cli/upgrade/argParser.py index 7fd5dda966..c161877ac8 100644 --- a/python/src/mas/cli/upgrade/argParser.py +++ b/python/src/mas/cli/upgrade/argParser.py @@ -32,7 +32,6 @@ required=False, help="The MAS instance ID to be upgraded" ) - otherArgGroup = upgradeArgParser.add_argument_group('More') otherArgGroup.add_argument( '--skip-pre-check', @@ -48,6 +47,12 @@ default=False, help="Launch the upgrade without prompting for confirmation", ) +otherArgGroup.add_argument( + "--accept-license", + action="store_true", + default=False, + help="Accept all license terms without prompting" +) otherArgGroup.add_argument( '-h', "--help", action='help',