diff --git a/.secrets.baseline b/.secrets.baseline
index f7e0ae995f2..124a2a24437 100644
--- a/.secrets.baseline
+++ b/.secrets.baseline
@@ -3,7 +3,7 @@
"files": "^.secrets.baseline$",
"lines": null
},
- "generated_at": "2025-08-15T21:40:03Z",
+ "generated_at": "2025-09-03T13:58:29Z",
"plugins_used": [
{
"name": "AWSKeyDetector"
diff --git a/Makefile b/Makefile
index 36fb6d3319f..15dbc5c3100 100644
--- a/Makefile
+++ b/Makefile
@@ -30,7 +30,7 @@ tekton-test: tekton
docker:
docker build -t quay.io/ibmmas/cli:100.0.0-pre.local image/cli
-all: ansible python tekton docker
+all: ansible-devops python tekton docker
run:
docker run -ti quay.io/ibmmas/cli:100.0.0-pre.local
diff --git a/python/src/mas/cli/update/app.py b/python/src/mas/cli/update/app.py
index 1c3ec1df3a4..5b2b795c9f5 100644
--- a/python/src/mas/cli/update/app.py
+++ b/python/src/mas/cli/update/app.py
@@ -11,6 +11,7 @@
import logging
import logging.handlers
+from typing import Callable
from halo import Halo
from prompt_toolkit import print_formatted_text, HTML
@@ -21,7 +22,7 @@
from .argParser import updateArgParser
from mas.devops.ocp import createNamespace, getStorageClasses, getConsoleURL
-from mas.devops.mas import listMasInstances, getCurrentCatalog
+from mas.devops.mas import listMasInstances, listAiServiceInstances, getCurrentCatalog
from mas.devops.tekton import preparePipelinesNamespace, installOpenShiftPipelines, updateTektonDefinitions, launchUpdatePipeline
@@ -94,7 +95,10 @@ def update(self, argv):
# deprecated MaximoApplicationSuite ImageContentSourcePolicy instead of the new ImageDigestMirrorSet
self.isAirgap()
self.reviewCurrentCatalog()
- self.reviewMASInstance()
+ isMasInstalled = self.reviewMASInstance()
+ isAiServiceInstalled = self.reviewAiServiceInstance()
+ if not isMasInstalled and not isAiServiceInstalled:
+ self.fatalError(["No MAS or AI Service instances were detected on the cluster => nothing to update! See log file for details"])
if self.args.mas_catalog_version is None:
# Interactive mode
@@ -228,15 +232,23 @@ def reviewCurrentCatalog(self) -> None:
f" {catalogInfo['image']}"
])
- def reviewMASInstance(self) -> None:
- self.printH1("Review MAS Instances")
- self.printDescription(["The following MAS intances are installed on the target cluster and will be affected by the catalog update:"])
+ def reviewMASInstance(self) -> bool:
+ return self.reviewInstances(listMasInstances, 'MAS', 'Suite.core.mas.ibm.com/v1')
+
+ def reviewAiServiceInstance(self) -> bool:
+ return self.reviewInstances(listAiServiceInstances, 'AI Service', 'AIServiceApp.aiservice.ibm.com/v1')
+
+ def reviewInstances(self, getInstances: Callable, name: str, kind: str) -> bool:
+ self.printH1(f"Review {name} Instances")
try:
- suites = listMasInstances(self.dynamicClient)
- for suite in suites:
- self.printDescription([f"- {suite['metadata']['name']} v{suite['status']['versions']['reconciled']}"])
+ instances = getInstances(self.dynamicClient)
+ self.printDescription([f"The following {name} instances are installed on the target cluster and will be affected by the catalog update:"])
+ for instance in instances:
+ self.printDescription([f"- {instance['metadata']['name']} v{instance['status']['versions']['reconciled']}"])
+ return True
except ResourceNotFoundError:
- self.fatalError("No MAS instances were detected on the cluster (Suite.core.mas.ibm.com/v1 API is not available). See log file for details")
+ self.printDescription([f"No {name} instances were detected on the cluster ({kind} API is not available)"])
+ return False
def chooseCatalog(self) -> None:
self.printH1("Select IBM Maximo Operator Catalog Version")