From e5aa7484d25cea98d7157404abab782655097f03 Mon Sep 17 00:00:00 2001 From: KAROL CZARNECKI Date: Fri, 4 Oct 2024 16:06:35 +0100 Subject: [PATCH] Squashed commit of the following: commit 97361294e8c7b56fcedd105f240a8f8217e3b758 Author: anilprajapatiibm <169060963+anilprajapatiibm@users.noreply.github.com> Date: Fri Oct 4 20:18:17 2024 +0530 [minor] Support October Catalog (#1234) Co-authored-by: Ian Boden commit 6e1e2aeaa2a90bca62d3bf2f1281ba81d003f630 Author: Alexandre Quinteiro Date: Wed Oct 2 15:04:28 2024 -0300 [minor] Reorganize scheduler tests - removed selenium and added pytests (#1278) Co-authored-by: Alexandre Quinteiro commit 6df29d8e5113132cb06d46484b34357b87a6951e Author: stonepd Date: Wed Oct 2 17:18:17 2024 +0100 [patch] Provide CLI automation to upgrade CPD v4.8 installations to v5.0 (#1270) commit 64200498dc4fd7b4d34c1980dafa24e565868841 Author: Terence Quinn Date: Tue Oct 1 13:47:36 2024 -0500 [patch] add node about zenmetastore-edb postgres license issue (#1277) commit dccbe8fa2192fb40b662bdc37a69273520c078ce Author: HariPalleti Date: Tue Oct 1 12:56:08 2024 -0500 [patch] dro_namespace considered during update (#1276) commit 002e881968d0dc635d6d7a02abb05df4f4445367 Author: mattlrx <32359792+mattlrx@users.noreply.github.com> Date: Mon Sep 30 10:27:21 2024 +0200 [minor] Mustgather update to collect additional dependencies and resources (#1268) commit 239b6b80b318ad79c3623cf9ead5c84e7d6420c2 Author: HariPalleti Date: Mon Sep 30 03:20:23 2024 -0500 [patch] Fix skip_pre_check on update (#1272) commit 84d84715e0e2b7a7fa5fc2b9124f8d3f16b6bd96 Author: Andrew Whitfield Date: Sun Sep 29 13:08:35 2024 +0100 [patch] Update sls to 90 mins wait time in gitops fvt-preparer (#1274) commit b5f7aa02de33978b3d312f7c1e2c666962b08460 Author: Andrew Whitfield Date: Sat Sep 28 19:20:58 2024 +0100 [patch] increase wait times in gitops fvt-preparer (#1273) commit 14a223a1f0681d6a2c2821c8874ca95dd464c6da Author: Andrew Whitfield Date: Fri Sep 27 15:59:44 2024 +0100 [minor] Gitops updates to support junitreporter + timeouts in FVT (#1271) commit 4a2e6f67e37a37f13e751e5ea84639fedeb44fe1 Author: gabrielbonamicoibm <146848045+gabrielbonamicoibm@users.noreply.github.com> Date: Fri Sep 27 11:15:48 2024 -0300 [minor] Adding mobile version info in dashboard (#1253) Co-authored-by: Leonardo Miranda Co-authored-by: leo-miran <105313348+leo-miran@users.noreply.github.com> Co-authored-by: JonahLuckett <51744616+JonahLuckett@users.noreply.github.com> commit 806157b1e9170cddcbc33664934569880e1b5dd1 Author: chiragcsatani <157094209+chiragcsatani@users.noreply.github.com> Date: Fri Sep 27 19:40:08 2024 +0530 MAXMF-995- Add Prerequisite Request pages pipeline before report tests (#1269) Co-authored-by: Chirag Satani Co-authored-by: leo-miran <105313348+leo-miran@users.noreply.github.com> commit cc5940aafd8bfc4af0e7a9f1244bd67af997e2c1 Author: David Parker Date: Fri Sep 27 13:04:25 2024 +0530 [doc] Fix typo in doc home page commit fbf1ea84792f5180fdf7c541f6814388c848f772 Author: David Parker Date: Fri Sep 27 12:52:57 2024 +0530 [doc] Update documentation home page commit 90eb01de9ffea441d4506cf53692558ed77b6e37 Author: Tom Klapiscak <7372253+tomklapiscak@users.noreply.github.com> Date: Fri Sep 27 07:48:06 2024 +0100 [patch] Fix race conditions in gitops code (#1264) commit 9f890b8e09e87f8ea5e5264298f3140f3e7e13ed Author: stonepd Date: Wed Sep 25 11:17:30 2024 +0100 [patch] include default for set_finished parameter (#1267) commit a9f520d14ab2219485e20eade0dc1c1bdeded490 Author: David Parker Date: Tue Sep 24 10:47:08 2024 +0530 [doc] Update recommended CLI version commit 54d6ed16e0464b303dc09d309dc01b74e8404d62 Author: Ian Boden <82514609+IanBoden@users.noreply.github.com> Date: Tue Sep 24 05:36:22 2024 +0100 [patch] Remove expires-after on release (#1262) Co-authored-by: David Parker commit 41c56a9cdc9bb5b32a10f5a7f41a617a85f60b55 Author: Tremaine Hart Date: Mon Sep 23 13:10:00 2024 -0500 [patch] [MASCORE-3975] Create FVT test for Grafana (#1263) commit faa2f4b08c9f1a2c6b0cf817c1da7b6c4caa8581 Author: bmoferrall <44264093+bmoferrall@users.noreply.github.com> Date: Mon Sep 23 15:26:33 2024 +0100 [patch] MAXMIS-521: fix sequencing of operational map test(s) (#1260) Co-authored-by: Brendan More O'Ferrall commit cbe90757a5feb11e7071c8bfbc7134c69bc9cb92 Author: padmankosalaram <45054700+padmankosalaram@users.noreply.github.com> Date: Mon Sep 23 18:07:46 2024 +0530 [patch] Step timeout to 6.40hrs as imagescan wait for 6.30hrs (#1259) commit deb6c05722a83e69dbf73a44d724fd790ccd48c5 Author: David Parker Date: Mon Sep 23 06:29:45 2024 +0100 [patch] Fix rogue VERSION in artifact names (#1258) commit b38b245281b602212f97873749aa73e084df88a3 Author: David Parker Date: Thu Sep 19 12:50:45 2024 +0100 [skip ci] Tidy up NFS Client handling commit ba4e530e0f5a5635c135c77243c47b9e7db86159 Author: anilprajapatiibm <169060963+anilprajapatiibm@users.noreply.github.com> Date: Thu Sep 19 16:03:56 2024 +0530 [patch] fix table rowspan in catalog documentation (#1256) commit a7f63b36843df1c0bf73aea5eb17d56b519bd3a9 Author: Andrew Whitfield Date: Thu Sep 19 11:24:49 2024 +0100 [minor] Add sanity tests for gitops (#1255) commit 3afa904ec31fba6388c49edf756e4b746f559b18 Author: leo-miran <105313348+leo-miran@users.noreply.github.com> Date: Wed Sep 18 14:56:41 2024 -0300 [patch] mobile pytest task performance parameter (#1239) Co-authored-by: Gabriel Bonamico commit 1bd92c2e45bd5a5c86d61866d2aa9bc90212b207 Author: Tremaine Hart Date: Wed Sep 18 10:13:31 2024 -0500 [patch] need to check for nfs-client now (#1252) commit b685fee01896da018ebe867f089c31c048c8de98 Author: stonepd Date: Wed Sep 18 10:51:02 2024 +0100 [patch] run grafana role after catalog install (#1250) commit b0d13c5d4c4c5bc4650fbdafa8ec696852b5db18 Author: Andrew Whitfield Date: Wed Sep 18 10:35:18 2024 +0100 [patch] Update name of finally task and set max_retries correctly (#1246) commit 9e9c7fde909f50825dc4c5ce5394c23c1522bb56 Author: stonepd Date: Tue Sep 17 10:00:37 2024 +0100 [patch] install cert manager after catalogs to avoid subscription patch failure (#1249) commit c5ccc6d3e9f1dbed8461323016b23b41a7bedad2 Author: Andre Ferreira Guimaraes Junior Date: Mon Sep 16 14:24:26 2024 -0300 [minor] [MSO-1655] Break down optimizer markers (#1244) Co-authored-by: Alexandre Quinteiro commit 07c8f2da664447e40c421c308f4ae0e8af9997a6 Author: lyoshidaibm Date: Mon Sep 16 13:28:03 2024 -0300 [patch] MAXMIS-485 - Change keywords for fvt pipeline (#1247) Co-authored-by: unnati-solanki-git <131964221+unnati-solanki-git@users.noreply.github.com> commit ab810d338fcc4e46300fb972ad680fc6a09bdf0d Author: jamie-nolan Date: Mon Sep 16 11:46:25 2024 +0100 [minor] Add Operational Map to FVT. (#1245) commit 59485c93f56d495d6ce8b12e658f9b7d646f15cc Author: Andrew Whitfield Date: Fri Sep 13 20:27:58 2024 +0100 [patch] update gitops pipelines to use wait-for-tekton task (#1243) commit 923f5cfb5d738118ae131de9bff0e3520d61ca99 Author: Alexandre Quinteiro Date: Fri Sep 13 16:05:05 2024 -0300 [patch] Add cos prefix in use_hmac parameter (#1241) Co-authored-by: Alexandre Quinteiro Co-authored-by: Chirag Satani Co-authored-by: Leonardo Miranda commit 71f07f6c7a4bc24f05c0ec523ad7d1650743fb5c Author: Andrew Whitfield Date: Thu Sep 12 15:22:42 2024 +0100 [patch] Check for no status on subscription - gitops (#1238) commit 35ea9662ba3584f8b97b3c79570ac86c3792a6d7 Author: Ian Boden <82514609+IanBoden@users.noreply.github.com> Date: Thu Sep 12 14:20:02 2024 +0100 [patch] Add support for mirroring odf dependcies that are required for 4.15 (#1235) commit 7ea23a9b48ba3486b6bb4c32b04ad7a0fd9a6351 Author: David Parker Date: Wed Sep 11 09:39:48 2024 +0100 [doc] Fix "IBM License Key Center" link in docs commit 6c2b88b2bd808afb56fa40738af915444f44d1fc Author: David Parker Date: Tue Sep 10 09:31:01 2024 +0100 [doc] Doc updates & latest CLI version update commit 8b6b7c686a55053c4a4379a098d2f246bd91dd75 Author: Vishal-patel-7 <142403240+Vishal-patel-7@users.noreply.github.com> Date: Tue Sep 10 08:53:27 2024 +0530 [minor] Added HMAC to COS role (#1228) Co-authored-by: unnati-solanki-git <131964221+unnati-solanki-git@users.noreply.github.com> commit b0035d3ae1e4d7cb4f3810425d405e91a1a615a5 Author: David Parker Date: Mon Sep 9 12:28:08 2024 +0100 [doc] Minor doc updates commit b8989fc0a40ae9d09fc6155b7edf8d71b02c4649 Author: David Parker Date: Mon Sep 9 11:33:21 2024 +0100 [doc] Update examples commit dd6edf4027ad3f73b850df314d05637c9037bf7b Author: David Parker Date: Sun Sep 8 13:43:22 2024 +0100 [skip ci] Add EAM migration example commit 831e892e5e74042d6e8a6d0984cf8ca6d16623c9 Author: Tremaine Hart Date: Fri Sep 6 10:27:00 2024 -0500 [minor] [MASCORE-3026] implement role/tasks for new deployments of MongoDB CE v7.0 (#1232) commit 94b4f8db10520e41cc73e7d7112793d448d38595 Author: unnati-solanki-git <131964221+unnati-solanki-git@users.noreply.github.com> Date: Fri Sep 6 18:10:00 2024 +0530 [patch] moving user timeout in the end (#1230) commit 10d7a2b4a3cc9b0fee0da53b6f009f01944adfe4 Author: David Parker Date: Thu Sep 5 14:44:17 2024 +0100 [doc] Update Documentation and support [doc] commit prefix commit 5268e7f8c0ef4c72eaa0bd838c23ebe97bb80e68 Author: David Parker Date: Thu Sep 5 11:47:36 2024 +0100 [major] Remove image mirroring support for UDS (#1231) commit 4bc95cf6e7e00a9b5549c9d21e9922651e92dc12 Author: Matheus Cardoso de Medeiros <38898699+RexMCM@users.noreply.github.com> Date: Thu Sep 5 06:29:44 2024 -0300 [patch] Add support for enabling special characters in ID/username field (#1176) Co-authored-by: Matheus Cardoso de Medeiros Co-authored-by: David Parker --- .github/CODEOWNERS | 2 +- .github/workflows/build-cli.yml | 13 +- build/bin/build-docs.sh | 7 +- build/bin/docker-build.sh | 6 + catalogs/v9-241003-amd64.yaml | 12 + docs/catalogs/index.md | 6 +- docs/catalogs/v9-240730-amd64.md | 2 +- docs/catalogs/v9-240827-amd64.md | 2 +- docs/catalogs/v9-241003-amd64.md | 682 ++++++++++++++++++ docs/commands/install.md | 99 ++- docs/commands/mirror-images.md | 4 +- docs/examples/eam-migration.md | 178 +++++ docs/examples/images/dashboard-link.png | Bin 0 -> 12793 bytes docs/examples/images/dbeaver.png | Bin 0 -> 104370 bytes docs/examples/images/install-pipeline.png | Bin 0 -> 136283 bytes docs/examples/images/shutdown_eam.png | Bin 0 -> 54800 bytes docs/examples/mirror-db2.md | 64 ++ docs/guides/choosing-the-right-catalog.md | 28 +- docs/guides/image-mirroring.md | 18 +- docs/guides/install.md | 14 +- docs/index.md | 61 +- examples/mirror_db2.md | 26 - image/cli/app-root/src/finalizer.py | 21 + image/cli/app-root/src/junit-xml-generator.py | 44 ++ .../cli/app-root/src/mobile-version-finder.py | 353 --------- image/cli/app-root/src/mobilever.py | 397 ++++++++++ image/cli/app-root/src/register-start.py | 15 +- image/cli/app-root/src/save-junit-to-mongo.py | 25 +- image/cli/app-root/src/wait-for-tekton.sh | 5 +- image/cli/mascli/functions/gitops_cluster | 36 +- image/cli/mascli/functions/gitops_db2u | 2 +- image/cli/mascli/functions/gitops_dro | 2 +- .../mascli/functions/gitops_mas_fvt_preparer | 5 +- .../mascli/functions/gitops_suite_app_config | 7 + image/cli/mascli/functions/gitops_utils | 174 +++-- .../internal/install_config_storage_classes | 12 + .../cli/mascli/functions/internal/save_config | 3 - image/cli/mascli/functions/mirror_images | 63 +- image/cli/mascli/functions/must_gather | 38 +- .../mascli/must-gather/mg-collect-mas-manage | 8 + .../masapp/ibm-mas-masapp-config.yaml.j2 | 6 + .../phase1/ibm-mas-cluster-base.yaml.j2 | 6 + .../templates/gitops/bootstrap/argocd.yaml | 6 +- .../templates/gitops/bootstrap/configmap.yaml | 5 + image/cli/masfvt/finally.yml | 2 +- mkdocs.yml | 34 +- python/src/mas/cli/install/app.py | 107 +-- python/src/mas/cli/install/argBuilder.py | 3 + python/src/mas/cli/install/argParser.py | 11 +- python/src/mas/cli/update/app.py | 69 +- python/src/mas/cli/update/argParser.py | 36 + tekton/src/params/install.yml.j2 | 16 +- .../pipelines/fvt-deprovision-after.yml.j2 | 5 +- tekton/src/pipelines/fvt-launcher.yml.j2 | 8 +- tekton/src/pipelines/fvt-optimizer.yml.j2 | 159 +++- .../gitops/deprovision-cluster.yml.j2 | 17 +- .../gitops/deprovision-mas-deps.yml.j2 | 100 +-- .../pipelines/gitops/gitops-mas-apps.yml.j2 | 4 + .../gitops/gitops-mas-cluster.yml.j2 | 6 + .../pipelines/gitops/gitops-mas-deps.yml.j2 | 23 +- .../gitops-mas-fvt-preparer-pipeline.yml.j2 | 8 + .../gitops/gitops-mas-initiator.yml.j2 | 17 +- .../gitops/provision-bootstrap-cluster.yml.j2 | 17 +- tekton/src/pipelines/install.yml.j2 | 5 +- tekton/src/pipelines/rollback.yml.j2 | 2 +- .../cluster-setup/ocp-verify-all.yml.j2 | 2 +- .../taskdefs/cluster-setup/ocp-verify.yml.j2 | 2 +- .../taskdefs/core/suite-install.yml.j2 | 2 + .../taskdefs/cp4d/cp4d-aiopenscale.yml.j2 | 2 +- .../taskdefs/cp4d/cp4d-cognos.yml.j2 | 2 +- .../taskdefs/cp4d/cp4d-platform.yml.j2 | 2 +- .../pipelines/taskdefs/cp4d/cp4d-spark.yml.j2 | 2 +- .../pipelines/taskdefs/cp4d/cp4d-spss.yml.j2 | 2 +- .../pipelines/taskdefs/cp4d/cp4d-wml.yml.j2 | 2 +- .../pipelines/taskdefs/cp4d/cp4d-wsl.yml.j2 | 2 +- .../taskdefs/dependencies/cos.yml.j2 | 2 + .../taskdefs/fvt-core/phase1-under5min.yml.j2 | 13 +- .../taskdefs/fvt-manage-is/phase1.yml.j2 | 30 +- .../taskdefs/fvt-manage-is/phase2.yml.j2 | 18 +- .../taskdefs/fvt-manage-is/phase3.yml.j2 | 4 +- .../taskdefs/fvt-manage/phase2.yml.j2 | 11 + .../taskdefs/fvt-manage/phase3.yml.j2 | 33 + .../taskdefs/fvt-manage/phase4.yml.j2 | 12 +- .../fvt-mobile/pytest/phase3-apps.yml.j2 | 4 +- .../gitops/apps/assist-workspace.yml.j2 | 2 + .../taskdefs/gitops/apps/iot-workspace.yml.j2 | 2 + .../gitops/apps/manage-workspace.yml.j2 | 2 + .../gitops/apps/monitor-workspace.yml.j2 | 2 + .../gitops/apps/optimizer-workspace.yml.j2 | 2 + .../gitops/apps/predict-workspace.yml.j2 | 2 + .../apps/visualinspection-workspace.yml.j2 | 2 + tekton/src/pipelines/update.yml.j2 | 10 +- tekton/src/pipelines/upgrade.yml.j2 | 2 +- tekton/src/tasks/dependencies/cos.yml.j2 | 6 + tekton/src/tasks/dependencies/mongodb.yml.j2 | 6 + tekton/src/tasks/fvt/fvt-finalize.yml.j2 | 2 + .../tasks/fvt/fvt-manage-last-phase.yml.j2 | 26 +- tekton/src/tasks/fvt/fvt-mobile-pytest.yml.j2 | 10 +- tekton/src/tasks/gitops/gitops-cluster.yml.j2 | 7 + tekton/src/tasks/gitops/gitops-cos.yml.j2 | 8 +- .../gitops/gitops-deprovision-cos.yml.j2 | 4 + .../gitops/gitops-mas-fvt-preparer.yml.j2 | 89 ++- .../gitops/gitops-suite-app-config.yml.j2 | 5 + tekton/src/tasks/ivt/ivt-core.yml.j2 | 2 +- tekton/src/tasks/suite-install.yml.j2 | 7 +- 105 files changed, 2569 insertions(+), 882 deletions(-) create mode 100644 catalogs/v9-241003-amd64.yaml create mode 100644 docs/catalogs/v9-241003-amd64.md create mode 100644 docs/examples/eam-migration.md create mode 100644 docs/examples/images/dashboard-link.png create mode 100644 docs/examples/images/dbeaver.png create mode 100644 docs/examples/images/install-pipeline.png create mode 100644 docs/examples/images/shutdown_eam.png create mode 100644 docs/examples/mirror-db2.md delete mode 100644 examples/mirror_db2.md create mode 100644 image/cli/app-root/src/junit-xml-generator.py delete mode 100644 image/cli/app-root/src/mobile-version-finder.py create mode 100644 image/cli/app-root/src/mobilever.py diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index e961f5326f..76e88cc40d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @durera @andrercm @sanjayprab @terenceq @whitfiea @alequint @leo-miran +* @durera @JonahLuckett @andrercm @sanjayprab @terenceq @whitfiea @alequint @leo-miran diff --git a/.github/workflows/build-cli.yml b/.github/workflows/build-cli.yml index afc4a32b65..3f020ad08c 100644 --- a/.github/workflows/build-cli.yml +++ b/.github/workflows/build-cli.yml @@ -16,6 +16,7 @@ jobs: build-tekton: name: Build Tekton Definitions runs-on: ubuntu-latest + if: ${{ !contains(github.event.head_commit.message, '[doc]') }} steps: # 1. Initialize the build # ------------------------------------------------------------------------------------------- @@ -61,6 +62,7 @@ jobs: build-python: name: Build Python Package runs-on: ubuntu-latest + if: ${{ !contains(github.event.head_commit.message, '[doc]') }} needs: build-tekton steps: # 1. Initialize the build @@ -141,6 +143,7 @@ jobs: build-container: name: Build Container Image runs-on: ubuntu-latest + if: ${{ !contains(github.event.head_commit.message, '[doc]') }} needs: - build-tekton - build-python @@ -177,6 +180,7 @@ jobs: wget --header="Authorization:Bearer $ARTIFACTORY_TOKEN" $ARTIFACTORY_GENERIC_RELEASE_URL/ibm-mas/ansible-devops/latest/ibm-mas_devops-latest.tar.gz -O $GITHUB_WORKSPACE/image/cli/install/ibm-mas_devops.tar.gz fi + # 3. Download Built Artifacts # ------------------------------------------------------------------------------------------- - name: Download the tekton file built in the other job @@ -248,6 +252,7 @@ jobs: pyinstaller-windows: name: Build Windows CLI runs-on: windows-latest + if: ${{ !contains(github.event.head_commit.message, '[doc]') }} needs: - build-tekton - build-python @@ -301,13 +306,14 @@ jobs: with: repo_token: ${{ secrets.GITHUB_TOKEN }} file: ${{ github.workspace }}/python/dist/mas-cli.exe - asset_name: mas-cli-windows-amd64-${{ env.VERSION }}.exe + asset_name: mas-cli-windows-amd64.exe tag: ${{ github.ref }} overwrite: true pyinstaller-linux: name: Build Linux CLI runs-on: ubuntu-latest + if: ${{ !contains(github.event.head_commit.message, '[doc]') }} needs: - build-tekton - build-python @@ -361,13 +367,14 @@ jobs: with: repo_token: ${{ secrets.GITHUB_TOKEN }} file: ${{ github.workspace }}/python/dist/mas-cli - asset_name: mas-cli-linux-amd64-${{ env.VERSION }} + asset_name: mas-cli-linux-amd64 tag: ${{ github.ref }} overwrite: true pyinstaller-macos: name: Build MacOS CLI runs-on: macos-latest + if: ${{ !contains(github.event.head_commit.message, '[doc]') }} needs: - build-tekton - build-python @@ -421,6 +428,6 @@ jobs: with: repo_token: ${{ secrets.GITHUB_TOKEN }} file: ${{ github.workspace }}/python/dist/mas-cli - asset_name: mas-cli-macos-arm64-${{ env.VERSION }} + asset_name: mas-cli-macos-arm64 tag: ${{ github.ref }} overwrite: true diff --git a/build/bin/build-docs.sh b/build/bin/build-docs.sh index f0a7fb256b..f0f1210f13 100644 --- a/build/bin/build-docs.sh +++ b/build/bin/build-docs.sh @@ -3,11 +3,12 @@ # Update all the placeholders in the doc source # Make sure not to commit these changes if you run this script locally find docs -type f -name '*.md' -exec sed -i \ - -e 's/@@CLI_LATEST_VERSION@@/10.9.0/g' \ + -e 's/@@CLI_LATEST_VERSION@@/11.1.3/g' \ -e 's/@@MAS_PREVIOUS_CHANNEL@@/8.11.x/g' \ - -e 's/@@MAS_PREVIOUS_CATALOG@@/v8-240730-amd64/g' \ + -e 's/@@MAS_PREVIOUS_CATALOG@@/v8-240827-amd64/g' \ -e 's/@@MAS_LATEST_CHANNEL@@/9.0.x/g' \ - -e 's/@@MAS_LATEST_CATALOG@@/v9-240827-amd64/g' \ + -e 's/@@MAS_LATEST_CHANNEL_MANAGE@@/9.0.x/g' \ + -e 's/@@MAS_LATEST_CATALOG@@/v9-241003-amd64/g' \ {} \; python -m pip install -q mkdocs mkdocs-redirects diff --git a/build/bin/docker-build.sh b/build/bin/docker-build.sh index 936059cd53..f8bddc7b8c 100755 --- a/build/bin/docker-build.sh +++ b/build/bin/docker-build.sh @@ -49,6 +49,12 @@ echo "RELEASE_LABEL .. $GITHUB_RUN_ID" echo "VCS_REF ........ $GITHUB_SHA" echo "VCS_URL ........ https://github.com/$GITHUB_REPOSITORY" +# Remove expires-after for release builds (only pre-release builds should auto-expire) +if [[ ! "$DOCKER_TAG" == *"-pre."* ]]; then + echo "Removing quay.expires-after label from Dockerfile" + sed -i "/quay.expires-after/d" $DOCKERFILE +fi + docker build \ --build-arg VERSION_LABEL=$DOCKER_TAG \ --build-arg RELEASE_LABEL=$GITHUB_RUN_ID \ diff --git a/catalogs/v9-241003-amd64.yaml b/catalogs/v9-241003-amd64.yaml new file mode 100644 index 0000000000..de5181e79a --- /dev/null +++ b/catalogs/v9-241003-amd64.yaml @@ -0,0 +1,12 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: CatalogSource +metadata: + name: ibm-operator-catalog + namespace: openshift-marketplace +spec: + displayName: IBM Maximo Operators (v9-241003-amd64) + publisher: IBM + description: Static Catalog Source for IBM Maximo Application Suite + sourceType: grpc + image: icr.io/cpopen/ibm-maximo-operator-catalog@sha256:ba2237481b2ce7407698775a71f44daaecd2db6f74855f20829ac1bceeddb3d9 + priority: 90 diff --git a/docs/catalogs/index.md b/docs/catalogs/index.md index 4b8a8c21f6..741df9377f 100644 --- a/docs/catalogs/index.md +++ b/docs/catalogs/index.md @@ -1,5 +1,8 @@ Catalog Options ------------------------------------------------------------------------------- +!!! important + Cloud Pak for Data 4.8, used in catalogs between 240625 and 240827 contains a license key for the zenmetastore-edb postgres database that expired on October 1, 2024. We have delivered a workaround for this in our install which is available from CLI version 11.2.1. If you are installing CP4D as a MAS dependency you must use version 11.2.1 of the CLI at a minimum. If you need to install MAS with CP4D using an older catalog than supported by this version of the CLI please contact IBM support. + As the MAS CLI is updated we maintain a rolling window of approximately four months worth of catalogs in the interactive mode choices for install, mirror-images, and update functions; after this period the catalogs will be removed from the options, generally speaking customers are recommended to use the latest catalog with the latest CLI for new installs, even if installing an older release of MAS. Older catalogs can still be used once they are not shown in the interactive prompt, but this is not recommended, refer to the table below for the recommended version of the CLI to use with each catalog update. @@ -46,10 +49,11 @@ To receive security updates and bug fixes you must periodically update the versi #### 2024 | Catalog | OCP Support | Recommended CLI | End of Support | | ------------------------------------- | ----------- | --------------- | ------------------------------- | +| [v9-241003-amd64](v9-241003-amd64.md) | 4.12 - 4.15 | latest | OCP 4.14 EOS October 31, 2025 | | [v9-240827-amd64](v9-240827-amd64.md) | 4.12 - 4.15 | latest | OCP 4.14 EOS October 31, 2025 | | [v9-240730-amd64](v9-240730-amd64.md) | 4.12 - 4.15 | latest | OCP 4.14 EOS October 31, 2025 | | [v9-240625-amd64](v9-240625-amd64.md) | 4.12 - 4.14 | latest | OCP 4.14 EOS October 31, 2025 | -| [v8-240528-amd64](v8-240528-amd64.md) | 4.12 - 4.14 | 10.8.0 | OCP 4.14 EOS October 31, 2025 | +| [v8-240528-amd64](v8-240528-amd64.md) | 4.12 - 4.14 | 10.8.1 | OCP 4.14 EOS October 31, 2025 | | [v8-240430-amd64](v8-240430-amd64.md) | 4.12 - 4.14 | 9.4.0 | OCP 4.14 EOS October 31, 2025 | | [v8-240405-amd64](v8-240405-amd64.md) | 4.12 - 4.14 | 9.4.0 | OCP 4.14 EOS October 31, 2025 | | [v8-240326-amd64](v8-240326-amd64.md) | 4.12 - 4.14 | 9.4.0 | OCP 4.14 EOS October 31, 2025 | diff --git a/docs/catalogs/v9-240730-amd64.md b/docs/catalogs/v9-240730-amd64.md index 4ede897f0b..acbd179897 100644 --- a/docs/catalogs/v9-240730-amd64.md +++ b/docs/catalogs/v9-240730-amd64.md @@ -86,7 +86,7 @@ IBM Maximo Application Suite customers receive a standard Red Hat OpenShift Cont - + diff --git a/docs/catalogs/v9-240827-amd64.md b/docs/catalogs/v9-240827-amd64.md index 40c9f7c661..26a567cac4 100644 --- a/docs/catalogs/v9-240827-amd64.md +++ b/docs/catalogs/v9-240827-amd64.md @@ -76,7 +76,7 @@ IBM Maximo Application Suite customers receive a standard Red Hat OpenShift Cont
OCPOCP General Availability Standard Support Extended Support
- + diff --git a/docs/catalogs/v9-241003-amd64.md b/docs/catalogs/v9-241003-amd64.md new file mode 100644 index 0000000000..c2512bf718 --- /dev/null +++ b/docs/catalogs/v9-241003-amd64.md @@ -0,0 +1,682 @@ +IBM Maximo Operator Catalog v9 (241003) +=============================================================================== + +Details +------------------------------------------------------------------------------- + +
OCPOCP General Availability Standard Support Extended Support
+ + + + +
Imageicr.io/cpopen/ibm-maximo-operator-catalog
Tagv9-241003-amd64
Digestsha256:ba2237481b2ce7407698775a71f44daaecd2db6f74855f20829ac1bceeddb3d9
+ +!!! important + **Maximo Assist** + Customers using Maximo Assist v8.7 or v8.8 should not update to this catalog and must instead contact IBM Support for guidance regarding the removal of IBM Watson Discovery and upgrading to Maximo Assist v9.0 + + **Maximo Predict** + Customers using Maximo Predict v8.7 should first update to v8.8 before updating to this catalog, Cloud Pak for Data v4.8 support is missing from the v8.7 maintenance stream currently + + Customers using Maximo Predict v8.8 will have to retrain their models due to the upgrade to Cloud Pak for Data v4.8 included in this catalog update. For more information refer to the [product documentation](https://www.ibm.com/docs/en/mas-cd/mhmpmh-and-p-u/continuous-delivery?topic=ui-upgrade-cloud-pak-data-requires-retraining-some-models-maximo-predict). + + +What's New +------------------------------------------------------------------------------- +- **Security updates and bug fixes** + - IBM Maximo Application Suite Core Platform v8.10, v8.11 and v9.0 + - IBM Maximo Manage v8.7, v8.6 and v9.0 + - IBM Maximo IoT v8.7, v8.8 and v9.0 + - IBM Maximo Monitor v8.11, v8.10 and v9.0 + - IBM Maximo Optimizer v8.5, v8.4 and v9.0 + - IBM Maximo Predict v9.0, v8.9 + - IBM Maximo Visualinspection v8.9 and v9.0 + - IBM Data Dictionary v1.1 + + +Manual Installation +------------------------------------------------------------------------------- +`oc apply -f https://raw.githubusercontent.com/ibm-mas/cli/master/catalogs/v9-241003-amd64.yaml` + + +Source +------------------------------------------------------------------------------- +```yaml +apiVersion: operators.coreos.com/v1alpha1 +kind: CatalogSource +metadata: + name: ibm-operator-catalog + namespace: openshift-marketplace +spec: + displayName: IBM Maximo Operators (v9-241003-amd64) + publisher: IBM + description: Static Catalog Source for IBM Maximo Application Suite + sourceType: grpc + image: icr.io/cpopen/ibm-maximo-operator-catalog@sha256:ba2237481b2ce7407698775a71f44daaecd2db6f74855f20829ac1bceeddb3d9 + priority: 90 +``` + +Red Hat OpenShift Container Platform Support +------------------------------------------------------------------------------- +IBM Maximo Application Suite will run anywhere that you can run a supported OpenShift release on AMD64 architecture, including: + +- [AWS](https://aws.amazon.com/rosa/) +- [Azure](https://azure.microsoft.com/en-gb/services/openshift/) +- [Google Cloud Platform](https://cloud.google.com/architecture/partners/openshift-on-gcp) +- [IBM Cloud](https://www.ibm.com/cloud/openshift) + +For more information about the OCP lifecycle refer to the [Red Hat OpenShift Container Platform Life Cycle Policy](https://access.redhat.com/support/policy/updates/openshift/). + +IBM Maximo Application Suite customers receive a standard Red Hat OpenShift Container Platform subscription as part of their purchase. This includes 18 months of maintenance support for each OpenShift minor release. A further 6 months support is available to purchase as an Extended Update Support (EUS) Add-on to x86-64 versions of Red Hat OpenShift Kubernetes Engine, Red Hat OpenShift Container Platform, and Red Hat OpenShift Platform Plus Standard subscriptions. + +!!! note + Extended Update Support is included with Premium subscriptions of x86-64 versions of Red Hat OpenShift Kubernetes Engine, Red Hat OpenShift Container Platform, and Red Hat OpenShift Platform Plus. Please contact your Red Hat Sales Representative if you are unsure if you have access to EUS and to help decide if it is appropriate for your environment. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OCPGeneral AvailabilityStandard SupportExtended SupportSupported MAS Releases
4.15February 27, 2024August 27, 2025N/A8.10 - 9.0
4.14October 31, 2023May 1, 2025October 31, 20268.10 - 9.0
4.13May 17, 2023November 17, 2024N/A8.10 - 9.0
4.12January 17, 2023July 17, 2024January 17, 20258.10 - 9.0
+ + +### Certified Operators +- `registry.redhat.io/redhat/certified-operator-index:v4.15` +- `registry.redhat.io/redhat/certified-operator-index:v4.14` +- `registry.redhat.io/redhat/certified-operator-index:v4.13` +- `registry.redhat.io/redhat/certified-operator-index:v4.12` + +The following packages from this catalog are used in the Maximo Application Suite install: + +- **gpu-operator-certified** required by `ibm.mas_devops.nvidia_gpu` role +- **kubeturbo-certified** required by `ibm.mas_devops.kubeturbo` role + + +### Community Operators +- `registry.redhat.io/redhat/community-operator-index:v4.15` +- `registry.redhat.io/redhat/community-operator-index:v4.14` +- `registry.redhat.io/redhat/community-operator-index:v4.13` +- `registry.redhat.io/redhat/community-operator-index:v4.12` + +The following packages from this catalog are used in the Maximo Application Suite install: + +- **grafana-operator** required by `ibm.mas_devops.grafana` role +- **opentelemetry-operator** required by `ibm.mas_devops.opentelemetry` role +- **strimzi-kafka-operator** required by `ibm.mas_devops.kafka` role (if using Strimzi as Kakfa provider) + + +### Red Hat Operators +- `registry.redhat.io/redhat/redhat-operator-index:v4.15` +- `registry.redhat.io/redhat/redhat-operator-index:v4.14` +- `registry.redhat.io/redhat/redhat-operator-index:v4.13` + +The following packages from these catalogs are used in the Maximo Application Suite install: + +- **amq-streams** required by `ibm.mas_devops.kafka` role (if using AMQ Streams as Kakfa provider) +- **openshift-pipelines-operator-rh** required by the MAS CLI +- **nfd** required by `ibm.mas_devops.nvidia_gpu` role +- **aws-efs-csi-driver-operator** required by `ibm.mas_devops.ocp_efs` role +- **local-storage-operator** required by `ibm.mas_devops.ocs` role +- **odf-operator** required by `ibm.mas_devops.ocs` role + + +IBM Cloud Pak for Data Compatibility +------------------------------------------------------------------------------- +For more information on Cloud Pak for Data's support policy review this [IBM Cloud Pak for Data Software Support Lifecycle Addendum](https://www.ibm.com/support/pages/node/6593147). + +Cloud Pak for Data covers the following application's dependencies: + +- **Assist**: Watson Text to Speak, Watson Speach to Text, Watson Assistant +- **Predict**: Watson Studio, Watson Machine Learning, Watson Analytics Service, Watson Openscale + + + + + + + + + + + + + + + + + +
OCPCloud Pak for DataSupported MAS Releases
ReleaseGeneral AvailabilityEnd of Support
4.144.8.0 March, 2024 TBD 8.10 - 9.0
4.134.8.0 March, 2024 TBD 8.10 - 9.0
4.124.8.0 February, 2023 February, 2024 8.10 - 8.11
+ + +Package Manifest +------------------------------------------------------------------------------- + + + +### IBM Maximo Application Suite +| Package | Default Channel | Channel | Latest Version | +|--------------------------|-------------------|-----------|------------------| +| ibm-mas | 9.0.x | 8.10.x | 8.10.18 | +| | | 8.11.x | 8.11.15 | +| | | 9.0.x | 9.0.3 | +| ibm-mas-aibroker | 9.0.x | 9.0.x | 9.0.2 | +| ibm-mas-arcgis | 9.0.x | 9.0.x | 9.0.0 | +| ibm-mas-assist | 9.0.x | 8.7.x | 8.7.7 | +| | | 8.8.x | 8.8.6 | +| | | 9.0.x | 9.0.2 | +| ibm-mas-hputilities | 8.6.x | 8.6.x | 8.6.7 | +| ibm-mas-iot | 9.0.x | 8.7.x | 8.7.17 | +| | | 8.8.x | 8.8.13 | +| | | 9.0.x | 9.0.3 | +| ibm-mas-manage | 9.0.x | 8.6.x | 8.6.18 | +| | | 8.7.x | 8.7.12 | +| | | 9.0.x | 9.0.3 | +| ibm-mas-monitor | 9.0.x | 8.10.x | 8.10.14 | +| | | 8.11.x | 8.11.11 | +| | | 9.0.x | 9.0.3 | +| ibm-mas-optimizer | 9.0.x | 8.4.x | 8.4.10 | +| | | 8.5.x | 8.5.9 | +| | | 9.0.x | 9.0.3 | +| ibm-mas-predict | 9.0.x | 8.8.x | 8.8.3 | +| | | 8.9.x | 8.9.5 | +| | | 9.0.x | 9.0.2 | +| ibm-mas-visualinspection | 9.0.x | 8.8.x | 8.8.4 | +| | | 8.9.x | 8.9.6 | +| | | 9.0.x | 9.0.3 | + + +### IBM Utilities +| Package | Default Channel | Channel | Latest Version | +|---------------------|-------------------|-----------|------------------| +| ibm-data-dictionary | 1.1.x | 1.1.x | 1.1.12 | +| ibm-sls | 3.x | 3.x | 3.10.0 | +| ibm-truststore-mgr | 1.x | 1.x | 1.5.4 | + + +### IBM Cloud Pak Foundational Services +| Package | Default Channel | Channel | Latest Version | +|-------------------------------------|-------------------|--------------|------------------| +| cloud-native-postgresql | stable-v1.18 | fast | 1.18.3 | +| | | stable | 1.18.7 | +| | | stable-v1.15 | 1.15.5 | +| | | stable-v1.17 | 1.17.3 | +| | | stable-v1.18 | 1.18.7 | +| ibm-cert-manager-operator | v3.23 | beta | 3.9.0 | +| | | v3 | 3.25.13 | +| | | v3.20 | 3.22.0 | +| | | v3.21 | 3.23.0 | +| | | v3.22 | 3.24.0 | +| | | v3.23 | 3.25.13 | +| | | v4.0 | 4.0.0 | +| | | v4.1 | 4.1.0 | +| | | v4.2 | 4.2.7 | +| ibm-common-service-operator | v3.23 | beta | 103.103.103 | +| | | v3 | 3.19.22 | +| | | v3.20 | 3.20.1 | +| | | v3.21 | 3.21.0 | +| | | v3.22 | 3.22.0 | +| | | v3.23 | 3.23.14 | +| | | v4.0 | 4.0.1 | +| | | v4.1 | 4.1.0 | +| | | v4.2 | 4.2.0 | +| | | v4.3 | 4.3.1 | +| | | v4.4 | 4.4.0 | +| | | v4.5 | 4.5.0 | +| | | v4.6 | 4.6.5 | +| | | v4.7 | 4.7.0 | +| | | v4.8 | 4.8.0 | +| ibm-commonui-operator-app | v3.23 | beta | 1.5.1 | +| | | v3 | 1.21.14 | +| | | v3.20 | 1.18.1 | +| | | v3.21 | 1.19.0 | +| | | v3.22 | 1.20.0 | +| | | v3.23 | 1.21.14 | +| | | v4.0 | 4.0.0 | +| | | v4.1 | 4.1.0 | +| | | v4.2 | 4.2.0 | +| | | v4.3 | 4.3.1 | +| | | v4.4 | 4.4.4 | +| | | v4.5 | 4.5.1 | +| ibm-events-operator | v3 | beta | 3.7.1 | +| | | v3 | 5.0.1 | +| ibm-ingress-nginx-operator-app | v3.23 | beta | 1.5.0 | +| | | v3 | 1.20.13 | +| | | v3.20 | 1.17.1 | +| | | v3.21 | 1.18.0 | +| | | v3.22 | 1.19.0 | +| | | v3.23 | 1.20.13 | +| ibm-licensing-operator-app | v3.23 | beta | 1.4.1 | +| | | v3 | 1.20.13 | +| | | v3.20 | 1.17.0 | +| | | v3.21 | 1.18.0 | +| | | v3.22 | 1.19.0 | +| | | v3.23 | 1.20.13 | +| | | v4.0 | 4.0.0 | +| | | v4.1 | 4.1.0 | +| | | v4.2 | 4.2.7 | +| ibm-management-ingress-operator-app | v3.23 | beta | 1.5.1 | +| | | v3 | 1.20.13 | +| | | v3.20 | 1.17.0 | +| | | v3.21 | 1.18.0 | +| | | v3.22 | 1.19.0 | +| | | v3.23 | 1.20.13 | +| ibm-mongodb-operator-app | v3.23 | beta | 1.3.1 | +| | | v3 | 1.18.13 | +| | | v3.20 | 1.15.0 | +| | | v3.21 | 1.16.0 | +| | | v3.22 | 1.17.0 | +| | | v3.23 | 1.18.13 | +| | | v4.0 | 4.0.0 | +| | | v4.1 | 4.1.0 | +| | | v4.2 | 4.2.2 | +| ibm-namespace-scope-operator | v3.23 | beta | 1.1.1 | +| | | v3 | 1.17.13 | +| | | v3.20 | 1.14.0 | +| | | v3.21 | 1.15.0 | +| | | v3.22 | 1.16.0 | +| | | v3.23 | 1.17.13 | +| | | v4.0 | 4.0.0 | +| | | v4.1 | 4.1.0 | +| | | v4.2 | 4.2.7 | +| ibm-odlm | v3.23 | beta | 1.5.0 | +| | | v3 | 1.21.13 | +| | | v3.20 | 1.18.0 | +| | | v3.21 | 1.19.0 | +| | | v3.22 | 1.20.0 | +| | | v3.23 | 1.21.13 | +| | | v4.0 | 4.0.0 | +| | | v4.1 | 4.1.0 | +| | | v4.2 | 4.2.3 | +| | | v4.3 | 4.3.4 | +| ibm-platform-api-operator-app | v3.23 | beta | 3.9.1 | +| | | v3 | 3.25.13 | +| | | v3.20 | 3.22.0 | +| | | v3.21 | 3.23.0 | +| | | v3.22 | 3.24.0 | +| | | v3.23 | 3.25.13 | +| ibm-user-data-services-operator | alpha | alpha | 2.0.12 | +| ibm-zen-operator | v3.23 | beta | 1.0.1 | +| | | v3 | 1.8.13 | +| | | v3.20 | 1.7.1 | +| | | v3.21 | 1.7.2 | +| | | v3.22 | 1.8.0 | +| | | v3.23 | 1.8.13 | +| | | v4.0 | 5.0.0 | +| | | v4.1 | 5.0.1 | +| | | v4.2 | 5.0.2 | +| | | v4.3 | 5.1.1 | +| | | v4.4 | 5.1.7 | +| | | v6.0 | 6.0.2 | +| isf-operator | v2.0 | v2.0 | 2.8.1 | + + +### IBM Cloud Pak for Data +| Package | Default Channel | Channel | Latest Version | +|-------------------------------|-------------------|-----------|------------------| +| analyticsengine-operator | v5.4 | beta | 1.0.1 | +| | | stable-v1 | 1.0.9 | +| | | v2.0 | 2.0.0 | +| | | v2.1 | 2.1.0 | +| | | v2.2 | 2.2.0 | +| | | v2.3 | 2.3.0 | +| | | v3.0 | 3.0.0 | +| | | v3.1 | 3.1.0 | +| | | v3.3 | 3.3.0 | +| | | v3.4 | 3.4.0 | +| | | v3.5 | 3.5.0 | +| | | v4.0 | 4.0.0 | +| | | v4.1 | 4.1.0 | +| | | v4.2 | 4.2.0 | +| | | v4.3 | 4.3.0 | +| | | v5.0 | 5.0.0 | +| | | v5.1 | 5.1.0 | +| | | v5.3 | 5.3.0 | +| | | v5.4 | 5.4.0 | +| | | v6.0 | 6.0.0 | +| cpd-platform-operator | v6.0 | beta | 2.0.0 | +| | | stable-v1 | 2.0.0 | +| | | v2.0 | 2.0.8 | +| | | v3.0 | 3.0.0 | +| | | v3.1 | 3.1.0 | +| | | v3.2 | 3.2.0 | +| | | v3.3 | 3.3.0 | +| | | v3.4 | 3.4.0 | +| | | v3.5 | 3.5.0 | +| | | v3.6 | 3.6.0 | +| | | v3.7 | 3.7.0 | +| | | v3.8 | 3.8.0 | +| | | v4.0 | 4.0.0 | +| | | v4.1 | 4.1.0 | +| | | v4.2 | 4.2.0 | +| | | v4.3 | 4.3.0 | +| | | v4.4 | 4.4.0 | +| | | v5.0 | 5.0.0 | +| | | v5.1 | 5.1.0 | +| | | v5.2 | 5.2.0 | +| | | v5.3 | 5.3.0 | +| | | v5.4 | 5.4.0 | +| | | v5.5 | 5.5.0 | +| | | v5.6 | 5.6.0 | +| | | v6.0 | 6.0.2 | +| ibm-ca-operator | v26.2 | v22.0 | 22.0.0 | +| | | v22.1 | 22.1.0 | +| | | v22.2 | 22.2.0 | +| | | v22.3 | 22.3.0 | +| | | v23.0 | 23.0.0 | +| | | v23.1 | 23.1.0 | +| | | v23.3 | 23.3.0 | +| | | v23.4 | 23.4.0 | +| | | v23.5 | 23.5.0 | +| | | v24.0 | 24.0.0 | +| | | v24.3 | 24.3.0 | +| | | v25.0 | 25.0.0 | +| | | v25.2 | 25.2.0 | +| | | v25.3 | 25.3.0 | +| | | v25.4 | 25.4.0 | +| | | v26.0 | 26.0.0 | +| | | v26.1 | 26.1.0 | +| | | v26.2 | 26.2.0 | +| | | v4.0 | 4.0.8 | +| ibm-cpd-canvasbase | v8.5 | v8.0 | 8.0.0 | +| | | v8.1 | 8.1.0 | +| | | v8.3 | 8.3.0 | +| | | v8.4 | 8.4.0 | +| | | v8.5 | 8.5.0 | +| | | v9.0 | 9.0.0 | +| ibm-cpd-ccs | v9.2 | v1.0 | 1.0.9 | +| | | v2.0 | 2.0.0 | +| | | v2.1 | 2.1.0 | +| | | v2.2 | 2.2.0 | +| | | v2.3 | 2.3.0 | +| | | v6.0 | 6.0.0 | +| | | v6.1 | 6.1.0 | +| | | v6.3 | 6.3.0 | +| | | v6.4 | 6.4.0 | +| | | v6.5 | 6.5.0 | +| | | v7.0 | 7.0.0 | +| | | v7.1 | 7.1.0 | +| | | v7.2 | 7.2.0 | +| | | v7.3 | 7.3.0 | +| | | v8.0 | 8.0.0 | +| | | v8.1 | 8.1.0 | +| | | v8.2 | 8.2.0 | +| | | v8.3 | 8.3.0 | +| | | v8.4 | 8.4.0 | +| | | v8.5 | 8.5.0 | +| | | v8.6 | 8.6.0 | +| | | v9.0 | 9.0.0 | +| | | v9.1 | 9.1.0 | +| | | v9.2 | 9.2.0 | +| ibm-cpd-datarefinery | v9.1 | v1.0 | 1.0.10 | +| | | v2.0 | 2.0.0 | +| | | v2.1 | 2.1.0 | +| | | v2.2 | 2.2.0 | +| | | v2.3 | 2.3.0 | +| | | v6.0 | 6.0.0 | +| | | v6.1 | 6.1.0 | +| | | v6.3 | 6.3.0 | +| | | v6.4 | 6.4.0 | +| | | v6.5 | 6.5.0 | +| | | v7.0 | 7.0.0 | +| | | v8.0 | 8.0.0 | +| | | v8.1 | 8.1.0 | +| | | v8.3 | 8.3.0 | +| | | v8.4 | 8.4.0 | +| | | v8.5 | 8.5.0 | +| | | v8.6 | 8.6.0 | +| | | v9.0 | 9.0.0 | +| | | v9.1 | 9.1.0 | +| ibm-cpd-spss | v8.5 | v1.0 | 1.0.9 | +| | | v2.0 | 2.0.0 | +| | | v2.1 | 2.1.0 | +| | | v2.2 | 2.2.0 | +| | | v2.3 | 2.3.0 | +| | | v6.0 | 6.0.0 | +| | | v6.1 | 6.1.0 | +| | | v6.3 | 6.3.0 | +| | | v6.4 | 6.4.0 | +| | | v6.5 | 6.5.0 | +| | | v7.0 | 7.0.0 | +| | | v8.0 | 8.0.0 | +| | | v8.1 | 8.1.0 | +| | | v8.3 | 8.3.0 | +| | | v8.4 | 8.4.0 | +| | | v8.5 | 8.5.0 | +| | | v9.0 | 9.0.0 | +| ibm-cpd-wml-operator | v6.1 | alpha | 1.1.0 | +| | | beta | 1.0.1486 | +| | | v1.1 | 1.1.8 | +| | | v2.0 | 2.0.0 | +| | | v2.1 | 2.1.0 | +| | | v2.2 | 2.2.0 | +| | | v2.3 | 2.3.0 | +| | | v3.0 | 3.0.0 | +| | | v3.1 | 3.1.0 | +| | | v3.3 | 3.3.0 | +| | | v3.4 | 3.4.0 | +| | | v3.5 | 3.5.0 | +| | | v4.0 | 4.0.0 | +| | | v5.0 | 5.0.0 | +| | | v5.1 | 5.1.0 | +| | | v5.3 | 5.3.0 | +| | | v5.4 | 5.4.0 | +| | | v5.5 | 5.5.0 | +| | | v5.6 | 5.6.0 | +| | | v6.0 | 6.0.0 | +| | | v6.1 | 6.1.0 | +| ibm-cpd-wos | v6.1 | alpha | 1.2.0 | +| | | v1 | 1.5.0 | +| | | v1.5 | 1.5.4 | +| | | v2.0 | 2.0.0 | +| | | v2.1 | 2.1.0 | +| | | v2.2 | 2.2.0 | +| | | v2.3 | 2.3.0 | +| | | v3.0 | 3.0.0 | +| | | v3.1 | 3.1.0 | +| | | v3.3 | 3.3.0 | +| | | v3.4 | 3.4.0 | +| | | v3.5 | 3.5.0 | +| | | v4.0 | 4.0.0 | +| | | v4.2 | 4.2.0 | +| | | v5.0 | 5.0.0 | +| | | v5.3 | 5.3.0 | +| | | v5.4 | 5.4.0 | +| | | v5.5 | 5.5.0 | +| | | v5.6 | 5.6.0 | +| | | v6.0 | 6.0.0 | +| | | v6.1 | 6.1.0 | +| ibm-cpd-ws-runtimes | v9.1 | v1.0 | 1.0.9 | +| | | v5.0 | 5.0.0 | +| | | v5.1 | 5.1.0 | +| | | v5.2 | 5.2.0 | +| | | v5.3 | 5.3.0 | +| | | v6.0 | 6.0.0 | +| | | v6.1 | 6.1.0 | +| | | v6.3 | 6.3.0 | +| | | v6.4 | 6.4.0 | +| | | v6.5 | 6.5.0 | +| | | v7.0 | 7.0.0 | +| | | v8.0 | 8.0.0 | +| | | v8.1 | 8.1.0 | +| | | v8.3 | 8.3.0 | +| | | v8.4 | 8.4.0 | +| | | v8.5 | 8.5.0 | +| | | v8.6 | 8.6.0 | +| | | v9.0 | 9.0.0 | +| | | v9.1 | 9.1.0 | +| ibm-cpd-wsl | v9.1 | v2.0 | 2.0.9 | +| | | v3.0 | 3.0.0 | +| | | v3.1 | 3.1.0 | +| | | v3.2 | 3.2.0 | +| | | v3.3 | 3.3.0 | +| | | v6.0 | 6.0.0 | +| | | v6.1 | 6.1.0 | +| | | v6.3 | 6.3.0 | +| | | v6.4 | 6.4.0 | +| | | v6.5 | 6.5.0 | +| | | v7.0 | 7.0.0 | +| | | v8.0 | 8.0.0 | +| | | v8.1 | 8.1.0 | +| | | v8.3 | 8.3.0 | +| | | v8.4 | 8.4.0 | +| | | v8.5 | 8.5.0 | +| | | v8.6 | 8.6.0 | +| | | v9.0 | 9.0.0 | +| | | v9.1 | 9.1.0 | +| ibm-elasticsearch-operator | v1.1 | v1.1 | 1.1.2238 | +| ibm-etcd-operator | v1.0 | v1.0 | 1.0.30 | +| ibm-iam-operator | v3.23 | beta | 3.9.1 | +| | | v3 | 3.23.14 | +| | | v3.20 | 3.20.1 | +| | | v3.21 | 3.21.0 | +| | | v3.22 | 3.22.0 | +| | | v3.23 | 3.23.14 | +| | | v4.0 | 4.0.1 | +| | | v4.1 | 4.1.0 | +| | | v4.2 | 4.2.0 | +| | | v4.3 | 4.3.1 | +| | | v4.4 | 4.4.0 | +| | | v4.5 | 4.5.4 | +| | | v4.6 | 4.6.0 | +| | | v4.7 | 4.7.0 | +| ibm-minio-operator | v1.0 | v1.0 | 1.0.18 | +| ibm-model-train-operator | v2.0 | v1.1 | 1.1.15 | +| | | v2.0 | 2.0.0 | +| ibm-rabbitmq-operator | v1.0 | v1.0 | 1.0.29 | +| ibm-watson-discovery-operator | v8.1 | v4.0 | 4.0.9 | +| | | v4.5 | 4.5.0 | +| | | v4.6 | 4.6.0 | +| | | v4.7 | 4.7.0 | +| | | v5.0 | 5.0.0 | +| | | v5.2 | 5.2.0 | +| | | v5.3 | 5.3.0 | +| | | v5.5 | 5.5.0 | +| | | v6.0 | 6.0.0 | +| | | v6.1 | 6.1.0 | +| | | v6.3 | 6.3.0 | +| | | v7.0 | 7.0.0 | +| | | v7.2 | 7.2.0 | +| | | v7.3 | 7.3.0 | +| | | v7.4 | 7.4.0 | +| | | v7.5 | 7.5.0 | +| | | v7.6 | 7.6.0 | +| | | v8.0 | 8.0.0 | +| | | v8.1 | 8.1.0 | +| ibm-watson-gateway-operator | v1.0 | v1.0 | 1.0.23 | + + +### IBM Db2 Universal Operator +| Package | Default Channel | Channel | Latest Version | +|---------------|-------------------|-----------|------------------| +| db2u-operator | v110509.0 | v1.0 | 1.0.11 | +| | | v1.1 | 1.1.13 | +| | | v110508.0 | 110508.0.3 | +| | | v110509.0 | 110509.0.2 | +| | | v2.0 | 2.0.0 | +| | | v2.1 | 2.1.0 | +| | | v2.2 | 2.2.0 | +| | | v3.0 | 3.0.0 | +| | | v3.1 | 3.1.0 | +| | | v3.2 | 3.2.0 | +| | | v4.0 | 4.0.0 | +| | | v4.1 | 4.1.0 | +| | | v4.2 | 4.2.0 | +| | | v5.0 | 5.0.0 | +| | | v5.1 | 5.1.0 | +| | | v5.2 | 5.2.0 | +| | | v5.3 | 5.3.0 | +| | | v6.0 | 6.0.0 | + + +### IBM AppConnect +| Package | Default Channel | Channel | Latest Version | +|------------------|-------------------|-----------|------------------| +| couchdb-operator | v2.2 | beta | 1.4.2 | +| | | stable | 2.2.1 | +| | | v1.0 | 1.0.14 | +| | | v1.1 | 1.1.0 | +| | | v1.2 | 1.2.1 | +| | | v1.3 | 1.3.1 | +| | | v1.4 | 1.4.4 | +| | | v2.0 | 2.0.0 | +| | | v2.1 | 2.0.1 | +| | | v2.2 | 2.2.1 | +| ibm-appconnect | v12.3 | cd | 5.2.0 | +| | | v1.0 | 1.0.5 | +| | | v1.1-eus | 1.1.10 | +| | | v1.2 | 1.2.0 | +| | | v1.3 | 1.3.2 | +| | | v1.4 | 1.4.0 | +| | | v1.5 | 1.5.2 | +| | | v10.0 | 10.0.1 | +| | | v10.1 | 10.1.1 | +| | | v11.0 | 11.0.1 | +| | | v11.1 | 11.1.0 | +| | | v11.2 | 11.2.1 | +| | | v11.3 | 11.3.0 | +| | | v11.4 | 11.4.0 | +| | | v11.5 | 11.5.1 | +| | | v11.6 | 11.6.0 | +| | | v12.0-sc2 | 12.0.3 | +| | | v12.1 | 12.1.2 | +| | | v12.2 | 12.2.1 | +| | | v12.3 | 12.3.0 | +| | | v2.0 | 2.0.0 | +| | | v2.1 | 2.1.0 | +| | | v3.0 | 3.0.0 | +| | | v3.1 | 3.1.0 | +| | | v4.0 | 4.0.0 | +| | | v4.1 | 4.1.0 | +| | | v4.2 | 4.2.0 | +| | | v5.0-lts | 5.0.20 | +| | | v5.1 | 5.1.0 | +| | | v5.2 | 5.2.0 | +| | | v6.0 | 6.0.0 | +| | | v6.1 | 6.1.1 | +| | | v6.2 | 6.2.0 | +| | | v7.0 | 7.0.0 | +| | | v7.1 | 7.1.0 | +| | | v7.2 | 7.2.0 | +| | | v8.0 | 8.0.0 | +| | | v8.1 | 8.1.0 | +| | | v8.2 | 8.2.1 | +| | | v9.0 | 9.0.0 | +| | | v9.1 | 9.1.0 | +| | | v9.2 | 9.2.1 | + + +### Eclipse Amlen +| Package | Default Channel | Channel | Latest Version | +|------------------------|-------------------|-----------|------------------| +| eclipse-amlen-operator | 1.x | 1.x | 1.1.1 | diff --git a/docs/commands/install.md b/docs/commands/install.md index 01f3391415..f47eb21cab 100644 --- a/docs/commands/install.md +++ b/docs/commands/install.md @@ -6,61 +6,50 @@ Usage For full usage information run `mas install --help` ``` -usage: mas install [-c MAS_CATALOG_VERSION] [--mas-catalog-digest MAS_CATALOG_DIGEST] [--ibm-entitlement-key IBM_ENTITLEMENT_KEY] [-i MAS_INSTANCE_ID] - [-w MAS_WORKSPACE_ID] [-W MAS_WORKSPACE_NAME] [--mas-channel MAS_CHANNEL] [--eck] [--eck-enable-logstash] - [--eck-remote-es-hosts ECK_REMOTE_ES_HOSTS] [--eck-remote-es-username ECK_REMOTE_ES_USERNAME] - [--eck-remote-es-password ECK_REMOTE_ES_PASSWORD] [--superuser-username MAS_SUPERUSER_USERNAME] [--superuser-password MAS_SUPERUSER_PASSWORD] - [--additional-configs ADDITIONAL_CONFIGS] [--pod-templates POD_TEMPLATES] [--non-prod] [--disable-ca-trust] - [--manual-certificates MANUAL_CERTIFICATES] [--disable-walkme] [--storage-class-rwo STORAGE_CLASS_RWO] - [--storage-class-rwx STORAGE_CLASS_RWX] [--storage-pipeline STORAGE_PIPELINE] [--storage-accessmode {ReadWriteMany,ReadWriteOnce}] - [--license-file LICENSE_FILE] [--uds-email UDS_CONTACT_EMAIL] [--uds-firstname UDS_CONTACT_FIRSTNAME] [--uds-lastname UDS_CONTACT_LASTNAME] - [--dro-namespace DRO_NAMESPACE] [--mongodb-namespace MONGODB_NAMESPACE] [--ocp-ingress-tls-secret-name OCP_INGRESS_TLS_SECRET_NAME] - [--assist-channel ASSIST_CHANNEL] [--iot-channel IOT_CHANNEL] [--monitor-channel MONITOR_CHANNEL] [--manage-channel MANAGE_CHANNEL] - [--predict-channel PREDICT_CHANNEL] [--visualinspection-channel VISUALINSPECTION_CHANNEL] [--optimizer-channel OPTIMIZER_CHANNEL] - [--optimizer-plan {full,limited}] [--aibroker-channel AIBROKER_CHANNEL] [--mas-aibroker-storage-provider MAS_AIBROKER_STORAGE_PROVIDER] - [--mas-aibroker-storage-accesskey MAS_AIBROKER_STORAGE_ACCESSKEY] [--mas-aibroker-storage-secretkey MAS_AIBROKER_STORAGE_SECRETKEY] - [--mas-aibroker-storage-host MAS_AIBROKER_STORAGE_HOST] [--mas-aibroker-storage-port MAS_AIBROKER_STORAGE_PORT] - [--mas-aibroker-storage-ssl MAS_AIBROKER_STORAGE_SSL] [--mas-aibroker-storage-region MAS_AIBROKER_STORAGE_REGION] - [--mas-aibroker-storage-pipelines-bucket MAS_AIBROKER_STORAGE_PIPELINES_BUCKET] - [--mas-aibroker-storage-tenants-bucket MAS_AIBROKER_STORAGE_TENANTS_BUCKET] - [--mas-aibroker-storage-templates-bucket MAS_AIBROKER_STORAGE_TEMPLATES_BUCKET] [--mas-aibroker-tenant-name MAS_AIBROKER_TENANT_NAME] - [--mas-aibroker-watsonxai-apikey MAS_AIBROKER_WATSONXAI_APIKEY] [--mas-aibroker-watsonxai-url MAS_AIBROKER_WATSONXAI_URL] - [--mas-aibroker-watsonxai-project-id MAS_AIBROKER_WATSONXAI_PROJECT_ID] [--mas-aibroker-watsonx-action MAS_AIBROKER_WATSONX_ACTION] - [--mas-aibroker-db-host MAS_AIBROKER_DB_HOST] [--mas-aibroker-db-port MAS_AIBROKER_DB_PORT] [--mas-aibroker-db-user MAS_AIBROKER_DB_USER] - [--mas-aibroker-db-database MAS_AIBROKER_DB_DATABASE] [--mas-aibroker-db-secret-name MAS_AIBROKER_DB_SECRET_NAME] - [--mas-aibroker-db-secret-key MAS_AIBROKER_DB_SECRET_KEY] [--mas-aibroker-db-secret-value MAS_AIBROKER_DB_SECRET_VALUE] [--install-arcgis] - [--arcgis-channel MAS_ARCGIS_CHANNEL] [--manage-server-bundle-size {dev,snojms,small,jms}] [--manage-jms] [--manage-persistent-volumes] - [--manage-jdbc {system,workspace-application}] [--manage-demodata] [--manage-components MAS_APPWS_COMPONENTS] - [--manage-customization-archive-name MAS_APP_SETTINGS_CUSTOMIZATION_ARCHIVE_NAME] - [--manage-customization-archive-url MAS_APP_SETTINGS_CUSTOMIZATION_ARCHIVE_URL] - [--manage-customization-archive-username MAS_APP_SETTINGS_CUSTOMIZATION_ARCHIVE_USERNAME] - [--manage-customization-archive-password MAS_APP_SETTINGS_CUSTOMIZATION_ARCHIVE_PASSWORD] - [--manage-db-tablespace MAS_APP_SETTINGS_TABLESPACE] [--manage-db-indexspace MAS_APP_SETTINGS_INDEXSPACE] - [--manage-db-schema MAS_APP_SETTINGS_DB2_SCHEMA] [--manage-crypto-key MAS_APP_SETTINGS_CRYPTO_KEY] - [--manage-cryptox-key MAS_APP_SETTINGS_CRYPTOX_KEY] [--manage-old-crypto-key MAS_APP_SETTINGS_OLD_CRYPTO_KEY] - [--manage-old-cryptox-key MAS_APP_SETTINGS_OLD_CRYPTOX_KEY] [--manage-override-encryption-secrets] - [--manage-base-language MAS_APP_SETTINGS_BASE_LANG] [--manage-secondary-languages MAS_APP_SETTINGS_SECONDARY_LANGS] - [--manage-server-timezone MAS_APP_SETTINGS_SERVER_TIMEZONE] [--cp4d-version CPD_PRODUCT_VERSION] [--cp4d-install-spss] - [--cp4d-install-openscale] [--cp4d-install-cognos] [--db2-namespace DB2_NAMESPACE] [--db2-channel DB2_CHANNEL] [--db2-system] [--db2-manage] - [--db2-type DB2_TYPE] [--db2-timezone DB2_TIMEZONE] [--db2-affinity-key DB2_AFFINITY_KEY] [--db2-affinity-value DB2_AFFINITY_VALUE] - [--db2-tolerate-key DB2_TOLERATE_KEY] [--db2-tolerate-value DB2_TOLERATE_VALUE] [--db2-tolerate-effect DB2_TOLERATE_EFFECT] - [--db2-cpu-requests DB2_CPU_REQUESTS] [--db2-cpu-limits DB2_CPU_LIMITS] [--db2-memory-requests DB2_MEMORY_REQUESTS] - [--db2-memory-limits DB2_MEMORY_LIMITS] [--db2-backup-storage DB2_BACKUP_STORAGE_SIZE] [--db2-data-storage DB2_DATA_STORAGE_SIZE] - [--db2-logs-storage DB2_LOGS_STORAGE_SIZE] [--db2-meta-storage DB2_META_STORAGE_SIZE] [--db2-temp-storage DB2_TEMP_STORAGE_SIZE] - [--kafka-provider {strimzi,redhat,ibm,aws}] [--kafka-username KAFKA_USERNAME] [--kafka-password KAFKA_PASSWORD] - [--kafka-namespace KAFKA_NAMESPACE] [--kafka-version KAFKA_VERSION] [--msk-instance-type AWS_MSK_INSTANCE_TYPE] - [--msk-instance-nodes AWS_MSK_INSTANCE_NUMBER] [--msk-instance-volume-size AWS_MSK_VOLUME_SIZE] [--msk-cidr-az1 AWS_MSK_CIDR_AZ1] - [--msk-cidr-az2 AWS_MSK_CIDR_AZ2] [--msk-cidr-az3 AWS_MSK_CIDR_AZ3] [--msk-cidr-egress AWS_MSK_EGRESS_CIDR] - [--msk-cidr-ingress AWS_MSK_INGRESS_CIDR] [--eventstreams-resource-group EVENTSTREAMS_RESOURCE_GROUP] - [--eventstreams-instance-name EVENTSTREAMS_INSTANCE_NAME] [--eventstreams-instance-location EVENTSTREAMS_INSTANCE_LOCATION] [--cos {ibm,ocs}] - [--cos-resourcegroup COS_RESOURCEGROUP] [--turbonomic-name TURBONOMIC_TARGET_NAME] [--turbonomic-url TURBONOMIC_SERVER_URL] - [--turbonomic-version TURBONOMIC_SERVER_VERSION] [--turbonomic-username TURBONOMIC_USERNAME] [--turbonomic-password TURBONOMIC_PASSWORD] - [--ibmcloud-apikey IBMCLOUD_APIKEY] [--aws-region AWS_REGION] [--aws-access-key-id AWS_ACCESS_KEY_ID] [--secret-access-key SECRET_ACCESS_KEY] - [--aws-vpc-id AWS_VPC_ID] [--artifactory-username ARTIFACTORY_USERNAME] [--artifactory-token ARTIFACTORY_TOKEN] - [--approval-core APPROVAL_CORE] [--approval-assist APPROVAL_ASSIST] [--approval-iot APPROVAL_IOT] [--approval-manage APPROVAL_MANAGE] - [--approval-monitor APPROVAL_MONITOR] [--approval-optimizer APPROVAL_OPTIMIZER] [--approval-predict APPROVAL_PREDICT] - [--approval-visualinspection APPROVAL_VISUALINSPECTION] [--accept-license] [--dev-mode] [--no-wait-for-pvc] [--skip-pre-check] - [--skip-grafana-install] [--no-confirm] [-h] +mas install [-c MAS_CATALOG_VERSION] [--mas-catalog-digest MAS_CATALOG_DIGEST] [--ibm-entitlement-key IBM_ENTITLEMENT_KEY] [-i MAS_INSTANCE_ID] + [-w MAS_WORKSPACE_ID] [-W MAS_WORKSPACE_NAME] [--mas-channel MAS_CHANNEL] [--eck] [--eck-enable-logstash] + [--eck-remote-es-hosts ECK_REMOTE_ES_HOSTS] [--eck-remote-es-username ECK_REMOTE_ES_USERNAME] + [--eck-remote-es-password ECK_REMOTE_ES_PASSWORD] [--superuser-username MAS_SUPERUSER_USERNAME] [--superuser-password MAS_SUPERUSER_PASSWORD] + [--additional-configs ADDITIONAL_CONFIGS] [--pod-templates POD_TEMPLATES] [--non-prod] [--disable-ca-trust] + [--manual-certificates MANUAL_CERTIFICATES] [--disable-walkme] [--storage-class-rwo STORAGE_CLASS_RWO] + [--storage-class-rwx STORAGE_CLASS_RWX] [--storage-pipeline STORAGE_PIPELINE] [--storage-accessmode {ReadWriteMany,ReadWriteOnce}] + [--license-file LICENSE_FILE] [--uds-email UDS_CONTACT_EMAIL] [--uds-firstname UDS_CONTACT_FIRSTNAME] [--uds-lastname UDS_CONTACT_LASTNAME] + [--dro-namespace DRO_NAMESPACE] [--mongodb-namespace MONGODB_NAMESPACE] [--ocp-ingress-tls-secret-name OCP_INGRESS_TLS_SECRET_NAME] + [--assist-channel ASSIST_CHANNEL] [--iot-channel IOT_CHANNEL] [--monitor-channel MONITOR_CHANNEL] [--manage-channel MANAGE_CHANNEL] + [--predict-channel PREDICT_CHANNEL] [--visualinspection-channel VISUALINSPECTION_CHANNEL] [--optimizer-channel OPTIMIZER_CHANNEL] + [--optimizer-plan {full,limited}] [--install-arcgis] [--arcgis-channel MAS_ARCGIS_CHANNEL] + [--manage-server-bundle-size {dev,snojms,small,jms}] [--manage-jms] [--manage-persistent-volumes] + [--manage-jdbc {system,workspace-application}] [--manage-demodata] [--manage-components MAS_APPWS_COMPONENTS] + [--manage-customization-archive-name MAS_APP_SETTINGS_CUSTOMIZATION_ARCHIVE_NAME] + [--manage-customization-archive-url MAS_APP_SETTINGS_CUSTOMIZATION_ARCHIVE_URL] + [--manage-customization-archive-username MAS_APP_SETTINGS_CUSTOMIZATION_ARCHIVE_USERNAME] + [--manage-customization-archive-password MAS_APP_SETTINGS_CUSTOMIZATION_ARCHIVE_PASSWORD] + [--manage-db-tablespace MAS_APP_SETTINGS_TABLESPACE] [--manage-db-indexspace MAS_APP_SETTINGS_INDEXSPACE] + [--manage-db-schema MAS_APP_SETTINGS_DB2_SCHEMA] [--manage-crypto-key MAS_APP_SETTINGS_CRYPTO_KEY] + [--manage-cryptox-key MAS_APP_SETTINGS_CRYPTOX_KEY] [--manage-old-crypto-key MAS_APP_SETTINGS_OLD_CRYPTO_KEY] + [--manage-old-cryptox-key MAS_APP_SETTINGS_OLD_CRYPTOX_KEY] [--manage-override-encryption-secrets] + [--manage-base-language MAS_APP_SETTINGS_BASE_LANG] [--manage-secondary-languages MAS_APP_SETTINGS_SECONDARY_LANGS] + [--manage-server-timezone MAS_APP_SETTINGS_SERVER_TIMEZONE] [--cp4d-version CPD_PRODUCT_VERSION] [--cp4d-install-spss] + [--cp4d-install-openscale] [--cp4d-install-cognos] [--db2-namespace DB2_NAMESPACE] [--db2-channel DB2_CHANNEL] [--db2-system] [--db2-manage] + [--db2-type DB2_TYPE] [--db2-timezone DB2_TIMEZONE] [--db2-affinity-key DB2_AFFINITY_KEY] [--db2-affinity-value DB2_AFFINITY_VALUE] + [--db2-tolerate-key DB2_TOLERATE_KEY] [--db2-tolerate-value DB2_TOLERATE_VALUE] [--db2-tolerate-effect DB2_TOLERATE_EFFECT] + [--db2-cpu-requests DB2_CPU_REQUESTS] [--db2-cpu-limits DB2_CPU_LIMITS] [--db2-memory-requests DB2_MEMORY_REQUESTS] + [--db2-memory-limits DB2_MEMORY_LIMITS] [--db2-backup-storage DB2_BACKUP_STORAGE_SIZE] [--db2-data-storage DB2_DATA_STORAGE_SIZE] + [--db2-logs-storage DB2_LOGS_STORAGE_SIZE] [--db2-meta-storage DB2_META_STORAGE_SIZE] [--db2-temp-storage DB2_TEMP_STORAGE_SIZE] + [--kafka-provider {strimzi,redhat,ibm,aws}] [--kafka-username KAFKA_USERNAME] [--kafka-password KAFKA_PASSWORD] + [--kafka-namespace KAFKA_NAMESPACE] [--kafka-version KAFKA_VERSION] [--msk-instance-type AWS_MSK_INSTANCE_TYPE] + [--msk-instance-nodes AWS_MSK_INSTANCE_NUMBER] [--msk-instance-volume-size AWS_MSK_VOLUME_SIZE] [--msk-cidr-az1 AWS_MSK_CIDR_AZ1] + [--msk-cidr-az2 AWS_MSK_CIDR_AZ2] [--msk-cidr-az3 AWS_MSK_CIDR_AZ3] [--msk-cidr-egress AWS_MSK_EGRESS_CIDR] + [--msk-cidr-ingress AWS_MSK_INGRESS_CIDR] [--eventstreams-resource-group EVENTSTREAMS_RESOURCE_GROUP] + [--eventstreams-instance-name EVENTSTREAMS_INSTANCE_NAME] [--eventstreams-instance-location EVENTSTREAMS_INSTANCE_LOCATION] [--cos {ibm,ocs}] + [--cos-resourcegroup COS_RESOURCEGROUP] [--turbonomic-name TURBONOMIC_TARGET_NAME] [--turbonomic-url TURBONOMIC_SERVER_URL] + [--turbonomic-version TURBONOMIC_SERVER_VERSION] [--turbonomic-username TURBONOMIC_USERNAME] [--turbonomic-password TURBONOMIC_PASSWORD] + [--ibmcloud-apikey IBMCLOUD_APIKEY] [--aws-region AWS_REGION] [--aws-access-key-id AWS_ACCESS_KEY_ID] [--secret-access-key SECRET_ACCESS_KEY] + [--aws-vpc-id AWS_VPC_ID] [--artifactory-username ARTIFACTORY_USERNAME] [--artifactory-token ARTIFACTORY_TOKEN] [--allow-special-chars MAS_SPECIAL_CHARACTERS] + [--approval-core APPROVAL_CORE] [--approval-assist APPROVAL_ASSIST] [--approval-iot APPROVAL_IOT] [--approval-manage APPROVAL_MANAGE] + [--approval-monitor APPROVAL_MONITOR] [--approval-optimizer APPROVAL_OPTIMIZER] [--approval-predict APPROVAL_PREDICT] + [--approval-visualinspection APPROVAL_VISUALINSPECTION] [--accept-license] [--dev-mode] [--no-wait-for-pvc] [--skip-pre-check] + [--skip-grafana-install] [--no-confirm] [-h] ``` diff --git a/docs/commands/mirror-images.md b/docs/commands/mirror-images.md index 167e01931b..5a0e0477ba 100644 --- a/docs/commands/mirror-images.md +++ b/docs/commands/mirror-images.md @@ -16,10 +16,8 @@ Usage - `-u|--username REGISTRY_USERNAME` Username to authenticate to the target registry - `-p|--password REGISTRY_PASSWORD` Password to authenticate to the target registry -### Source Registry Entitlements +### Source Registry Entitlement - `--ibm-entitlement IBM_ENTITLEMENT_KEY` IBM Entitlement Key -- `--redhat-username REDHAT_CONNECT_USERNAME` Red Hat Connect Username (only required when mirroring UDS images) -- `--redhat-password REDHAT_CONNECT_PASSWORD` Red Hat Connect Password (only required when mirroring UDS images) ### Maximo Operator Catalog Selection - `-c|--catalog MAS_CATALOG_VERSION` Maximo Operator Catalog Version to mirror (e.g. @@MAS_LATEST_CATALOG@@) diff --git a/docs/examples/eam-migration.md b/docs/examples/eam-migration.md new file mode 100644 index 0000000000..91ef45f9f8 --- /dev/null +++ b/docs/examples/eam-migration.md @@ -0,0 +1,178 @@ +Migration from EAM 7 to MAS 9 +=============================================================================== + +This example demonstrates how to migrate from EAM 7 to Maximo Manage v9 running on [Red Hat OpenShift on IBM Cloud](https://www.ibm.com/products/openshift) (ROKS). + +- For this demo we are using an existing database instance that is configured without TLS enabled (so we do not need to worry about providing the certificates in the configuration) +- Normally you would take a backup of the database and use that, but for the purpose of this example we are going to take over the database currently in use, if you wish to follow this example using a restored backup of your database simply skip step 2. + + +Prerequisites +------------------------------------------------------------------------------- + +**1 An IBMCloud API Key** + +- Login in your IBM Cloud account +- Go to **Manage** menu and select **Access (IAM)** +- Go to **API keys** menu, click **Create an IBM Cloud API key** +- Enter a name and description for your API Key and click **Create** + +**2 A MAS License File** + +Access [IBM License Key Center](https://licensing.flexnetoperations.com/), on the **Get Keys** menu select **IBM AppPoint Suites**. Select **IBM MAXIMO APPLICATION SUITE AppPOINT LIC** and on the next page fill in the information as below: + +| Field | Content | +| -------------- | ------- | +| Number of Keys | How many AppPoints to assign to the license file | +| Host ID Type | Set to Ethernet Address | +| Host ID | Enter any 12 digit hexadecimal string | +| Hostname | Set to the hostname of your OCP instance, but this can be any value really | +| Port | Set to 27000 | + +Create a new folder `mas9demo` in your home directory and save this file there as `~/mas9demo/entitlement.lic` + +**3 An IBM Entitlement Key** + +Access [IBM Container Software Library](https://myibm.ibm.com/products-services/containerlibrary) using your IBMId to obtain your entitlement key. + + +Step 1 - Provision OpenShift +------------------------------------------------------------------------------- +We are going to provision the cluster using **Red Hat OpenShift on IBM Cloud** via the MAS CLI container image. Ensure that you set the `IBMCLOUD_APIKEY` environment variable to the key you obtained from the [IBM Container Software Library](https://myibm.ibm.com/products-services/containerlibrary). + + +```bash +export IBMCLOUD_APIKEY=x + +docker run -e IBMCLOUD_APIKEY -ti --rm -v ~:/mnt/home --pull always quay.io/ibmmas/cli:@@CLI_LATEST_VERSION@@ \ + mas provision-roks -r mas-development -c mas9demo -v 4.14_openshift \ + --worker-count 3 --worker-flavor b3c.8x32 --worker-zone lon02 \ + --no-confirm +``` + +This will provision an OpenShift cluster with three 8x32 worker nodes. It will take approximately **1 hour** to provision the cluster. + +!!! note + At time of writing the cost of this three node OpenShift cluster on IBMCloud is $1.61 per hour (which works out as just under $1'200 per month). Billing is hourly and to complete this example we will only need the cluster for a few hours. + + +Step 2 - Shutdown EAM +------------------------------------------------------------------------------- +We must stop EAM because we are going to take over the same database that is currently using; log into the WebSphere administrative console and stop the servers. + +![alt text](images/shutdown_eam.png) + +!!! note + You can skip this step if you took a backup of your database and instead are using that. + + +Step 3 - Prepare the JDBCCfg +------------------------------------------------------------------------------- +IBM Maximo Application Suite (MAS) configuration is held in Kubernetes resources, when we install MAS we will tell the installer to apply this configuration as part of the installation. + +```yaml +--- +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: "jdbc-demo-credentials" + namespace: "mas-dev-core" +stringData: + username: "{DB_USERNAME}" + password: "{DB_PASSWORD}" +--- +apiVersion: config.mas.ibm.com/v1 +kind: JdbcCfg +metadata: + name: "dev-jdbc-wsapp-demo-manage" + namespace: "mas-dev-core" + labels: + "mas.ibm.com/configScope": "workspace-application" + "mas.ibm.com/instanceId": "dev" + "mas.ibm.com/workspaceId": "demo" + "mas.ibm.com/applicationId": "manage" +spec: + displayName: "dev-jdbc-manage" + config: + url: "{JDBC_URL}" + sslEnabled: false + credentials: + secretName: "jdbc-demo-credentials" +``` + +Replace `{JDBC_URL}`, `{DB_USERNAME}`, and `{DB_PASSWORD}` with the actual values for your database, for example: + +- **JDBC_URL** = `jdbc:db2://1.2.3.4:50005/maxdb76:sslConnection=false;` +- **DB_USERNAME** = `maximo` +- **DB_PASSWORD** = `maximo` + +Save this file into the same directory where we saved the MAS entitlement file, as `~/mas9demo/mas9demo-jdbc.yaml` + +Validate that the JDBC URL and username/password are correct by running the command `SELECT VARNAME, VARVALUE FROM MAXIMO.MAXVARS WHERE VARNAME='MAXUPG';`, which will confirm the database is currently running at version 7. + +![alt text](images/dbeaver.png) + + +Step 4 - Install MAS +------------------------------------------------------------------------------- +Ensure the following environment variables are all set: + +- `IBMCLOUD_APIKEY` (see [prerequisites](#prerequisites)) +- `SUPERUSER_PASSWORD` (choose the password for the MAS superuser account) +- `IBM_ENTITLEMENT_KEY` (see [prerequisites](#prerequisites)) + +We will install MAS in **non-production mode**, with an instance ID of `dev` and a workspace ID of `demo` using the latest (at time of writing) catalog update. + +!!! note + When we launch the CLI container we are mounting your home directory into the container image, this is how the installer will access the `entitlement.lic` and `mas9demo-jdbc.yaml` files that you created earlier. + +```bash +export IBMCLOUD_APIKEY=x +export SUPERUSER_PASSWORD=x +export IBM_ENTITLEMENT_KEY=x + +docker run -e IBMCLOUD_APIKEY -ti --rm -v ~:/mnt/home --pull always quay.io/ibmmas/cli:@@CLI_LATEST_VERSION@@ bash -c " + CLUSTER_TYPE=roks CLUSTER_NAME=mas9demo ROLE_NAME=ocp_login ansible-playbook ibm.mas_devops.run_role && + mas install \ + --non-prod \ + --mas-instance-id dev \ + --mas-workspace-id demo \ + --mas-workspace-name 'EAM Migration Demo' \ + --mas-catalog-version @@MAS_LATEST_CATALOG@@ \ + --mas-channel @@MAS_LATEST_CHANNEL@@ \ + --manage-channel @@MAS_LATEST_CHANNEL_MANAGE@@ \ + --manage-jdbc workspace-application \ + --manage-components base=latest \ + --additional-configs /mnt/home/mas9demo \ + --license-file /mnt/home/mas9demo/entitlement.lic \ + --uds-email parkerda@uk.ibm.com \ + --uds-firstname David \ + --uds-lastname Parker \ + --storage-class-rwo ibmc-block-gold \ + --storage-class-rwx ibmc-file-gold-gid \ + --storage-pipeline ibmc-file-gold-gid \ + --storage-accessmode ReadWriteMany \ + --superuser-username superuser \ + --superuser-password '$SUPERUSER_PASSWORD' \ + --ibm-entitlement-key '$IBM_ENTITLEMENT_KEY' \ + --accept-license \ + --no-confirm +" +``` + +The install itself is performed on the cluster, the CLI merely prepares the installation pipeline, you will be presented with a URL to view the install pipeline in the OpenShift Console. + +!!! tip + You can either monitor the install in the OpenShift Console or go get lunch, the install will take approximately 2-3 hours depending on network conditions. + +![alt text](images/install-pipeline.png) + +Once the installation has completed you will be able to log into Maximo Application Suite & Maximo Manage using any user from the original EAM, for convenience the installer adds a link to the Maximo Application Suite Administrator Dashboard to the OpenShift Console's **Application Menu**, and we can log into MAS using the superuser username and password supplied during install: + +![alt text](images/dashboard-link.png) + +!!! note + In this demo we have not configured integration to an SMTP server, as a result we must manually set a new password for the migrated users (including **maxadmin**) before they can be used. + + If e-mail services are enabled during the MAS install then a new password would be generated automatically for each migrated user and a welcome e-mail containing their new Maximo Application Suite password would be sent. diff --git a/docs/examples/images/dashboard-link.png b/docs/examples/images/dashboard-link.png new file mode 100644 index 0000000000000000000000000000000000000000..fcd216765fd994092c5ee94dbba652dfcf49934c GIT binary patch literal 12793 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 mcV+~&98^!r^4N+ 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 aE5!724I{RU+kXGP)_q{4S$f~@_5T1Xp8u}^ literal 0 HcmV?d00001 diff --git a/docs/examples/images/install-pipeline.png b/docs/examples/images/install-pipeline.png new file mode 100644 index 0000000000000000000000000000000000000000..aaf70184ffa4f5ede263dc7b190969a8fd63625b GIT binary patch literal 136283 zcmeFZXIPWV*Efn4MF9~IMS%^7Gy&-y1f)m{y%&+*dxxMPC|#7^TPO)3w1AW(0@8a6 zy-82#5K2Nh_`c8n@BKa>&U2j)=gYayT*)<=JDGdtUbAM+TEDecA~n<%Nl9o)h=_#wS7o?42sMCJX@Hm({sZDrJCh=?lV@10rPx@zBb zQ!?}YA0brPO+RUG%{M!G9i+ zmX$So^^!c1IGBGTjLP(Hy?HhK-(^8o2+Q+#ub(#Og0(9h;-2*Rvv zEY<=l#WWRXP=0DIP>J4-H9~Ya?oDi?Y5(c@YdiZk+eE`=LdT$8&sS%U9p1MtqQOwD ztYs;?6p8HMb|U~2vTZqes3)yo$Y5LUA~`VWTR-mkkV@_PxD9vMc+dH19Sb>Rf*BOQ z`b?^@U?{mY@M5^TYX_ov!Ua1mO=g%WoexN=;`=81Vuf=Xw#lC52#hT5m?B%`pu zTk6Fy99Ld2I3&&fQlHhoW`|oCqT{i&?V??tDVoR{@6Hh8H7o`RM;vehkh`Gt^rO^5 zOaE!ifu`ij`fsTaJzE}=(bEIlXMsOjPOELb7JrLosbGxDv+zQ{r+PuzQ}@ld28s#T z;)K2|`ET�LTs}*mTfH?Mt8=>L0>O1Z`hZk?TL=*j!7fnt#bYy|ijOQ*Fg?^hq}5 zrMru7cuy-eUekHf_ol&<@`t$@1Y4 z{6Q|=0cu!D7_| zz~M;*je6qad;gi&&(^gIVzytqF;2n9oqDrIP$@b3U{r!}AG-%blM20DENK4Oq_Tbm zi9yqJC)yh%5wYp6{&WvL?$KlC9NnB5X90IQEgMUQtPHJ$Xd#}UMSVJ%+b>R+k4Af^ z#~Hb0Wb|4Veq_U-Np1;POVg0P+wHhAU$X($r^|CyVFiWSx9Z`UmdnN?N4doN(S{ z&ugSKPxS&7=XvJy!&XNh>iKv4^*rGXSG6|Qb}rqhV8@Ah$Bi{f!)A=Zp(s|Y$##2G zL$c$n9M^axx}U#8a}Jc(oC!y1L!+4{i2UuG&Gk+oD zLf_A{x9`lB;as(O9?fob@_15vESYfcyiAikXa(&NI-`=A6l`S~e&|v*cVYJc$sB4d}ZGUz+#wn)=arF!O;K~_$UJ1(<5tnxr=!8j-&W-;1@EarO z9yJ%Umi+0!b;fL48j){wfg817_5lS~rQ9at&g1@IToih;wEr0G4Wu53-;7e zuuA2gF7JMJP;h44vR&~thF{Xw@})92a4u>5>AL}vjt$YG4Fh(Ro2X_ZnA)fre!?|!{5%;_XU6Yc_FH$EqeBf4Hk z%hTiI9I^Rbk^SXh=N*%ximqAefTGNqr=Q5%9>i-OSefraT4ZAm-#QvaWP&oUk=ToO z>K#?dc6jMcbhRq9TZB7fUJ|~AtmvI{Rexfsb~0r$&8R=bvKa3&g~wgK(!54u;W)23 z(VV5wEul}m6aedjewc(hDW&L%o$J3bt=aJmk8|N9_^+*sdoTW$&yo!6Pf%Y>lNI$m z5gqnjLyw;>_B2c~lzyCcAl;bNz6aIf-An`7-d05yg=zhaJEa{uaz5X8)r4>ES6OGjc+e$H07o1!|-RlbvW9=>@ik@-8k|iC)x__;8X4V~UAJUNwGICvjp-9s}wQyz0 zl^KJ5U4$0lTM+^+!~BSWkFS@HZWNcY#4(@$*+Eq0Nfbo8(2+ldr5({(x%L!+yCBy~ z`&927obO-X3uT?5u*h zop*x*W;a5YO^;vjWQ!5+4>zP)8jMB_*FoYrRpOYUc#fC>?Or5OwT2^5p=kmCFH?g4 zGGW4Eb^olhpVusbf~uBOzq6toJuH*AL#^5Qv%Si7){0u`3sJZ;-nd(HraoO7m3ZJ^ zuSjA!Q6Me=bZ$3d&Ar;TEmiM+9JX{Iz8F20Qj5_!p z_m9RvHs>h;bh_6{w=So*aKHVSZPqBV0AAx<#BoYesuNaDn^B^Ujis%($r+|8%`Iv- zI)8Yv&vy9DM)5A$i7pRy6}#fae!uB&3R+rtEYB^4^r!;hTk2i5k`!Qc(3xEN`Foj3 zkL3|)m*f#9W!I5E8F^3raY~bHj^t&yp1fpGlZ$Z~h7a`*;fY!$$u;gY`YVXRTa3`6iZ7L}TZkj$s7@Z(r%6q7xTlnt>DxJV zFkBcGCQ!tTw*8r75{mO>N$QM)q`fnMX-!&t{X;R8*rMWOylJ9w0?o?Bh1TT0;q=aj z#>U3|<^EDCb}bR~K$bYHdM&eneJ1PGt!%?0>z=YUJcl&9i3wo^`t!4rN=Lk{AYJL{D6rL-*- zhI0wW;+ICo$0~b_0|M8tgARLKoMSuM0b^xWbduw?-;#F_x%ZRI(7U1#obEkG@&Cw| z4~l36gAC)_lWwT2;fA><$<5Y0IgcJ=br)OaTg0DuXnO4*Y!CNmksPpd)V(BF(qHP# z&>@Bgs$i0T)kSSBuUc5AX<5fKY%fySQ$>6t(U?dpB{7}@9PN2qNxRg%t+%~8qW@@5 z+a{V}lo#Tj?Fs5q9GF;El8xWlYJ76)kG4fhYT9}@cjlCu$rpQGcm{lItZ{23E95FC z@jq&pxTsR&vrYOkc61HzubbN~xWnQoOI93XSWq7LW4^8DxKU`czOV(*RHUq@uG-Ic zsv?=^$csU#Li$7*ervD=+T1FmhhBV#?pJqUXGuGt(7P15bP!f7Z~#-W4`SKb_i%iru+8GyiQEsW6s z{F$PYwN5Li3+Fd6qxhp;o$dLUb5ReBH~ z1*2Nf&Ljt~(8h@E%w)#CYL7sW#qaA>*``d#aSZY%5RxbM^RGATW^P=}t4C3p?eFh< z6b@vezDk5rM!|=g06F@%Lb~dHX=8*oRN(!U#v>hP3lmMwy~jpD1yKPP0!Fi#Rbh{P zh|A~2bio5=LFK6Cd$sW+$0{x*7;$NbO=CcJCg>;1MKLy2RF0v;Gn4^nSY$bg1-Cx! z_uxlwkIJJOFnjhYNw2ETut-oO9Y_%;4RRSL)l z#-`p>!*g7wVSC-DZ0x~z8#O;cqjz#f)_s;Wd6kGy?s**prr%saG|W@*mV+HkG5%JT z{L;|-Wo75o(?~IeO+qA?K#b|^$MyfqY@s(KSNPBZ@+N82Fy0P+)ML5uygub_@;TwC zYNrl)oji?^@a3`#Sf4sGpUxSd=eayrm^c%6W*zr4=jL@PAp}BJ-|VaLcZ&ACeDi*d&X%&B2)og}jC3e@k$ECZS%7v>N7QMRU_F%AkR;(yq4^3xntoCXtOU-{Z zz=4L-_C)Ja)ox0LyEIgHQC`1s!y7Xi(w{(iK^W*p3>0OuH?8Rwv>wJFGu zX@kSAf@9!M9dBT1N|7mB9(Tc`jrGM_w5I{~vlEqugl|@4kwj`6``_l$fHExN@x$L* zKi8~7$~ow22iNwfNdC z6=P-szp3Lt=LIro|G^6A5M z>E)Nh#;)H zh#8^}#Is?%q5t$JBJ#_n$o=PgA|ey+Q^4N8FVOqN{GUJgf73t~y-xM7u|M?ux4HfI zpk*xA7<@y<*k_k)toUY z+8>>sEHACZNRr%@D5ea&91b-{4i#>QQ!R9=6-EUM*uG~?+O0)X>dc=76afGTr_tgH z^B4Ysss4;4O+gBmE{4z?)*$GPK5MQJa_q3%cp5XpF>)0pquwykW{n>|Y5V-F{%uPW3U)MvRqNsO6 zB$SF?kM+8`QRxIrG|{biFCkDrmL0aaz2CdQ=<6yRUOzkUP#<2;F7QgVnMRh%i%(}f z?k4B*x7n!x*9W-^4zq&61CHQ#KC2x=i-C0}47m#sg>&Ta&y;Sq>gp5;G9S}fe%&3P z0CP`DO3=czvZXDs5O2s#TKfYa+Py(>7-;HN*Tv zuCdb)SgGNu37_R{rZ*vGoJeqGn7RJ!nN%IaBi84yd!$1Yx7wX+_#V2G{j-mLnlim! zT%ao+NslHJZX$)bN1))KlSfSRz8*#X|_T)mqi=0R=e2H^);k>D=;}< zDp0PTL;h+smFZZsZz);k3kXfoGGZo`_!{&Svs8b8^KLY5zI&7l5%YfssdW-enZ>VZ zeen$20~4t13kDRAHCZ@W%~tnNSQ~ib+roqJ<5l^9*whWJmd;XnutKzhQ8CYeo*jvzOAo`|vG*#w-A8!n$etd=n2I%9MLn&pc{I*kl!pE^cL)shHCf@1v z=)(g-N-LqQYld$pM4yr1jhgQYdpo$E2+q4q=C#_={iBT$ksUkVyp_|E-EAPKTXjc4 z>At5`_<>6-@4JL|{?KE^wJBth; zJyFwC+&$LCjY|y;(gWBs3XbtbdoSTa*`SlqHyq%d&AS+@KI{WOe2r|CjV`SxOF3R4 zjijag-ZXGH*X)KMr*e2NKBxpRPev|Pft`TCAOQpNaZoa(tKHP^ZSZ4Yrkdp_G_W_} z&RIrqzGhgCHX~%FRDK6L$*o&g%UI~mfHUEQ)cVKz23R$1PZO9L#+lc`y?@42ar;Ntc!~a`q6V8 z1A|nTxu#ObaoEN%sHef5xpV68)8{9m?G6b!%1Sg;wqe+;d-v1v4Vuh%d{`&+Y}4%p zAjt`+*zCkDA&$X34`5bSX#4&qYwGnHOhzq62$!45FjTBjsSIF0Bb-j0g8Nc=#+pgg zD{{;VWteL>A}qPMkpTx;G|<;X>~0;tn0?j5*F@h9bI2U_nwhdZbUKSn`WmpU-{NA) zKn(&~{#X&2M%Gdl$VBm5k(2359n@^y6op;+Wa3s=c|dWt<#(11jFp2X{0F~Cv)k|Z z<3p2}g`3~U=J?|buygx7vop%9Xi?|PQN>utWX;&M%i_Ij!qBr$AqPLm_~C5rWlf;6 z@EBxT(8euvW5G3`uJsiZX$7@qhcs~YzLD*B51DWhI<*-nYVzM_vy6zj(lnVw7Rl1K zY-)2R<7@)cw;XE!16q?uk+=qf?6p}Pm$4vdX5r%e5v5uhpYp7u(G$1&z&SaKxXgFz zX%8S;tpdkkP$Pzps@0Htxbtc{9d@Yh+`bL#+R+Zy=*eFFmj4C1TdFdLmG6MI*RlR7 za%{?>bNT8NBGA)G1t}@Ut}K+t8i}4#BDA)SOgkxpRMzXSQP%iv32lk5OSBK2i{r-k za|8>W;dXRGJdVE~L3$S@(@%YZ*1nirxSmf)ee{lMK2sJy6L~6t9^%DV#l2eSl`d4X zOrLl7Zb~RS`-9wh^x^jfb>p#ze@>2KX~&f!C1*FkoFgaG0_pa{_^ISo2|W5VE+Rhr zUAGn>M{zkrWi$Yv?59j8ot0bPBkU0PW|nMYH``gkcwq3$czzuYL9wf%uL~KHu@p9X z;y&@p0e)m;Z(KVAeh;$L-ariDbItVD;^h|9gU6weqE7=R4^qCtFdH6=nzusiO~wK6 z=K4pF59U&%b&k+E4`Z1zmk`dX+<-g@3Taisc(B*>(v{j55V8ui-3{j|#?$~O6Sls7 z@{Za*3mH<-|6LVeO=t_o?;`6%bIRV`GX4 zP>ZMbm!&S7c>|d=yD=AH2rz(<3E%L>wF^GEj1OGC@)r0NR*M#Sf6<>%GbL}xha@Cp z^L*+9ZFKW~yJDh`a=>}IhvmNl=&L<@{j&kaIE^O|JEvYpUKslx2lyZrWF)q610Eoe z!gpHu(U9xC7j{2A<2ik=c;YW||Kh&#-#9a&DUW)gfgtnP zZMM+d$lJYUu$5{B%=wx_iNUt2@>5OW0v|Ie1>+RWk?bp$z!WI!0jnPQsV&Zq4(SHC z)*^QdOyXS5e`eupO|?nmSWlXD!165A6;l_#@zMekbBZjl=g*t876Aq3E4Ebhk(f3s^z^`(?(k<6azqchrgB##p)PM1rtMab9sHXyw6+l(I2frlvie;i4Po?y=PN9cMAwG`vNpZb( zIJ;Oo*ITR;0LR78rj%5f?-~R#&D2{42Vu{Y_3cGbYCp{mAf0Vqd4~VDfvI50#EO2n9*_9^E)2dmmW#8acpnNi23{sxa zeDzhkwk)1SM5OuU@o@A2_Itea=yw2GFHiQCZq*xiL6;dN7-~*8C*-I!>Je8yQ}{h> z^uTAMK*r2TpiSW4P|DX#K@M|`QuWQTZbM`51qYj?63y1BP~wEKElj|w(v8yn`PuO@ zMd4$#exN!nd&d5Xb5VZ(=5rtAr)aOS)ZkU&)pmc6Uy{9zT}?&5V)8Y>`V0tz?vBab zBgmBG7Tp-9mZ5i!bGdCV$ek;x{GcoVFb#n$N*?eE=wEJ=u3+!%+|~RU#dD~fpK4v1>YNDt9#Xm2NmV(AN#OR^b&AQO2cgCRm+r}3+|sf=;WyIvvN zDbRKJfL;7;YlqT=F?w&#@gYu1UxlE0m!2^ty15FybOF6FlYX%&a#jARzZ}GqIrWqP zKJU|JlBS!21cctdaI+oW-99z_l1IK5?s0I1b^X`gBAzhrZ?GT;%mXI zm+z^Wr%uyspF$!u$H$B55)W?Av%6Z#lOvyf*~~{nK0~dVY%mk-oTV@Kt5>rOkapE^h670bNHSV+_P7nn zvmBi|-e}zPPcc1&+D1|rub<2?y34-cw(l17u5mxDYt~*ya(#>uj;?4Uy3AhY(Rn@( zL8_Q9t&e7;91>VmVk0bt*j4DhD zl%iQ&ql$M4wXXAdgM%6c zst$>%?_Nqc()=hFwf$6kyhBJWX{bjxhHMQ zx%NNmbJqwz*x)%xebWpSW>km^3`f`BGI3y(%ZP3!=E6e*fjF?`Pq~idU_zGN}QSREW7YpKuaqBO@Ij_#{FE3wv5@JT8c46Bi%X*pz9WN(KN{|JF zjkg^K@5f8!3k0kZEL*v#&Bx-I#Y#STnh|fMPUvP)j+tF_C(bFq@Hn~b5q2>ut?B;S zr_4=TG^C<#%xs$~!?3gdnOYnUTvYADkJZ04Yg8jViqSm|I9;Z!(H4&rAyNGH%bSGe z72tcwnJy&Wq>k@BO^{8r4NzRubEi4*`-8Y4-l<3Kw@YtskCNxazRI5Y^>&9+YBiei zxyIVXB%S@QgezN(_kE=Mcn}HpG_PPx7@zoZ??>!K z`ODlV{2^od=JCTHJ~Ci7C#&Pw?_W72MVyru+?|aYR8{DDjJCwqph4bZ>svIf#hY#j z(&$yYMFxJsgE++>N=?6N{=P9E*SIC8gpI-I;X2V^y=ydVx>bd@4|iyGzDWhYQJj+W9k@=_RQ1`HWj>46zO0=@ z0#?wUc+YAideTEo>nK`La3CSdI25)8qUE5xaNmt=qkRHkb*qr9-FT&3stXE5$BLKu zo2!0lEZ}`th%|NzXYxzZSh3A|%Y`@VX<75%pF84@WV0qiqN zf9L(Mqb`WPW8uDgy*tk2+4#fU%ErseVXdMv|E$RKV(+{zdtl3(TCc zR6=XsaJ=le*Eh^kGmq{vzN6&BjDO*KL+t)1BzUeXEKfQZ#!aA#HE&v0y!$R`o=Ukzz_a5oj8^tomifEZ9MUM^l@KP|MMGMD zUfWY2qAFMvix>g4D%B(u&yQ zRup3&*J@o(ICqEM-m?E*+}Z5&9_$%$rjB;U?(aB z9*|z%KEUuv1b%C*B-KYf74o6|@6>P4aLItkSIwaUV^1dR=e5dcf8p)*mUY zfcY*;pvLIS!n;$SI+na9DS^T<#0X(7urg6Wu3~++51|HE#c3!-*v#3 zd(-560{vKL5Puj_g8%vMJ@j;^Ht^FNd-AN(ByI=ASu>rMRWtl(Y$R5(RL+dSawVdc zA$7GE75m97!!^5%Bwk*$+A;Q#(Z(S+S-ty=y0|BYzPr?52Ku$Oqd-k8> z?y+9!VXU!eH6~G#wy9*^l!x8Ejj!*_>*0SF4>>SUWWLhOvQ!mbcxIZ1WENqJBZ{~w zTH=ZR`9ez>#BI+)`ImF|ZgOMUJqj86qAO>Cp*}8qqo6X{XJdKgbw>>eSsd)R&TjFC z?`ZDtdw3^rGRfrTsiJ7Hy7{w=LvQfmoL%s)6Me@Wwj)TOAa2$MY_=I`JQ9_fb;uH3 zViwO(g9|;?3Fxdd3sJk1W7d|ab1eLk10g9t(pvnpA_x8Lf`{cjCT{(Djpc=3Y)%vV zY6%b7H6xswK4N!q_>1qDUP+Oe`kP$&D5|@G-<6ZSBJQP*h`qcrbra&Y!`F<(6#zdt z*KSZR|47Q_lhXntg>;rs!2mA0r)ucY2Rp_nsBWX(M4ja*%vlm~vFH}dKWwRZs84XH zyUt>SbWOa>hh*EImq*0%UR}o=WCI{y;gWdK-<&+wI(xPOcI%y*?ZA1vm_3HKS%JZi zpxJdPgFeLnWvwn`@4J=_`&+5)Ja7RCZJ`QvsJou=hKCGjD9soe)yuf zLJ9WxnAuQin}m!voChMKFr&Rx#!5Z6+^?aq)mWf{2k?#22Jm+2Hfh z?F}$T5*3~F-3s3wsbJnsl@6VW%KD(wDyenp!M$T(z3nxU?Ku}cj%!+ydA@U|(6)qR zQ1B%>F+wo0O+o0|A+Bj>%IuB(&*%%>A^C^t?HqaI zdTj&gDa~$}302M{gLw8}T26nO>&P=XEVm&iP;gZ2{rjX&W&xAosg0$Yz6ABSO!Fz! z{^`z?|J0estlXSEKf7<`Fo$+Qq?tXT_BH^o=2-hwnn@BeYmwUmg{@*!x`Z2~ zSM0iZ%b`SfzS1EOCIwUf5;ZH}+^^`6-7%C@elG(#%&8_F#d}L3I>8(qM*TAvLV!C2 zl1PqS-XQ(rT$`!@_j zkJbrsv4`7UOAJgM?ImOvLK=My>ccLIH#L?wbhla7JPGH<)Je@j?{369tP;3J_tqwg z*xwpmL&XgLzJZQ9OGJexsS*j-eL7DrH>}pn36|>RO_DRA0PY-ZK;p6*-WWb)$v|OH znx+@@!|)~I{9DH}+2$Kj`yv%)J;L;w@47d^!)N|uwY8#!9Qhpw*<(f2j_{=z(~WzA zqXz@?HpBVTi35jT;@-{%8XKW;_N~LzM)d>Q;rp!H43Ynq$lpS6E&J7ziPaaM(}lb} ze(f8Dd##?4aLf)*ZtSG6L%ncSwIb+k1$k=$GU{hkJv#HmuIoj^>;

!6whFT~4<$ z7Sn6ERIM{=vDX%0cNF^leYzu|o&Osxy%&}Q_gMVlFFv_&JU;+lIO-apN#6H^!izCOm{7kce zc&WSe%f{%eAA+}E*P1NyN=ACWDIPFLJKbJA!c1E6C_OKH*!fw!oa zQ@LEk7oI`qP6vD1ed7v_n}Ly;59SvL?KBkTeHr;=8z^03bu(|EMV5|~3$3GZy9r0> z!F|UZrJySxM>yrYmb@a&>&x{=q&hu%%Su=j`Zkkv4r~yrWK=*QSix=Kc$@7h<&9^=_Rll`Nl z+*t`s!CDR*qLBlax}5Cy=}&F08}t-8rIoMO6lk113~;^{7^iqYI2$xUsad3}^kYoy zp&LZ;tg~$Q50_1m$4+(Cy0!3aRg3bvKtovr!#T2Z_RvDeson^2HFB(REVG%F z@fxQ<;Ziki4c_d+Qd_x{Ib!-pe)Jx>Eal>AU#EMxJ4CxNIRLjwVcnH2c|>+mW!)ok zovc0fyuG_Vwx?0x0IP||VDB3F4*U6SuEAHvci@;Nxa7ypygHvBZd}Q1D&g!*HtrqN zrq$ovqai^)AVG%S@0WJYOxVYUveR_`btZlYENao_*rF+GonFQ6pz7WjC)-VCUoIQw zmSuOpgid-WrODcM&iNffIjzD?}*R75Y zVm&S>GhR4eh6sU_w^DDktn~gBPQi>smzy@yHQ&8F^X#4S2$`)W3SYQK!QaVho)R() zBLF&G1XPguTVsRWaez>mb9=y6OsZbq#|B*EIn8-??L@>Z*&xGHpPr$$axd`SlpVZ& zWO1o3ek7DjuOktf>)?ymQR6h`c{BKk>+$y>R^KlR8Ri#tjTfTJw^*Mb#}!3<_q<>7#R=zN+7U;w{vT)Jno(Jh@v(L>7+q~M53{CxBsvml;nRNX z49!P(-afi3eyrGbjMM4bwOy-;+p76izC5jLekNeF zrE)3)oVanUrdhWpX6F=CAo=|3<-JzHTJtk)&`B-O)Vo#D;_eg-MPsmW^M{Y*MR|aB zTNJfUiAM7m7T;}?E5&cJ%SGK(1GfD=?r^d7ZX^>4dSy$zCYYe0W`HyvcS_T(oEy

qQ|teU~Jc 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: Command to execute - timeout (int): How long to allow for the command to complete - # Returns - [int, string, string]: `returnCode`, `stdOut`, `stdErr` - """ - - lock = threading.Lock() - - with lock: - p = Popen(cmdArray, stdin=PIPE, stdout=PIPE, stderr=PIPE, bufsize=-1) - try: - output, error = p.communicate(timeout=timeout) - return RunCmdResult(p.returncode, output, error) - except TimeoutExpired as e: - return RunCmdResult(127, "TimeoutExpired", str(e)) - - -def get_graphite_versions(): - # This list will contains all files found in the maxinst pod - apps_list = [] - - # Downloads all zip files from maxinst container - try: - pods = dynClient.resources.get(api_version="v1", kind="Pod") - podList = pods.get( - namespace=f"mas-{instanceId}-manage", - label_selector="mas.ibm.com/appType=maxinstudb", - ) - - if podList is None or podList.items is None or len(podList.items) == 0: - pass - else: - podName = podList.items[0].metadata.name - - # list all graphite zip packages in maxinst pod - ocExecCommand = [ - "oc", - "exec", - "-n", - f"mas-{instanceId}-manage", - podName, - "--", - "ls", - "/opt/IBM/SMP/maximo/tools/maximo/en/graphite/apps", - ] - result = run_cmd(ocExecCommand) - ls_result = result.out.decode("utf-8") - apps_list = ls_result.split("\n") - # removes last empty value from the list - apps_list.pop() - - # Download all packages that were found - for a in apps_list: - print("Downloading:", a) - ocExecCommand = [ - "oc", - "cp", - "-n", - f"mas-{instanceId}-manage", - f"{podName}:/opt/IBM/SMP/maximo/tools/maximo/en/graphite/apps/{a}", - f"./{a}", - "--retries=10", - ] - run_cmd(ocExecCommand) - - except Exception as e: - print(f"Unable to download mobile packages from maxinst pod: {e}") - sys.exit(1) - - # Downloading navigator from mobileapi pod - try: - pods = dynClient.resources.get(api_version="v1", kind="Pod") - podList = pods.get( - namespace=f"mas-{instanceId}-core", - label_selector=f"app={instanceId}-mobileapi", - ) - - if podList is None or podList.items is None or len(podList.items) == 0: - pass - else: - podName = podList.items[0].metadata.name - - # list navigator zip packages in mobileapi pod - ocExecCommand = [ - "oc", - "exec", - "-n", - f"mas-{instanceId}-core", - podName, - "--", - "ls", - "/etc/mobile/packages", - ] - result = run_cmd(ocExecCommand) - ls_result = result.out.decode("utf-8") - apps_list = ls_result.split("\n") - # removes last empty value from the list - apps_list.pop() - - for a in apps_list: - print("Downloading:", a) - ocExecCommand = [ - "oc", - "cp", - "-n", - f"mas-{instanceId}-core", - f"{podName}:/etc/mobile/packages/{a}", - f"./{a}", - "--retries=10", - ] - run_cmd(ocExecCommand) - except Exception as e: - print(f"Unable to download mobileapi navigator package from mobileapi pod: {e}") - sys.exit(1) - - # Extracting build.json from each file and deleting zip - pathlist = Path(".").glob("*.zip") - for app_zip_file in pathlist: - zip_file_path = f"./{str(app_zip_file)}" - zip_file_prefix = zip_file_path.split(".zip") - with zipfile.ZipFile(zip_file_path, "r") as zip_ref: - try: - zip_ref.extract("build.json", ".") - except KeyError as e: - print(f"There is no build.json file in {app_zip_file}") - with open("build.json", "w", encoding="utf-8") as dummy_file: - warn_json = { - "WARN": { - str(app_zip_file): "File does not contain version information" - } - } - json.dump(warn_json, dummy_file, indent=4) - zip_ref.close() - os.rename("./build.json", f"{zip_file_prefix[0]}.json") - os.remove(zip_file_path) - - # dictionary that will contain all graphite versions for all found zips - graphite_json = {} - - pathlist = Path(".").glob("*.json") - for path in pathlist: - path_in_str = str(path) - - with open(path_in_str, "r", encoding="utf-8") as openfile: - json_object = json.load(openfile) - - if json_object.get("WARN") is not None: - graphite_json.update({"WARN": json_object.get("WARN")}) - else: - graphite_json.update( - { - json_object.get("applicationId"): { - "version": json_object.get("version"), - "applicationId": json_object.get("applicationId"), - "applicationTitle": json_object.get("applicationTitle"), - "mobileVersion": json_object.get("mobileVersion"), - "buildToolsVersion": json_object.get("buildToolsVersion"), - "appProcessorVersion": json_object.get("appProcessorVersion"), - } - } - ) - - # removing empty mobile version or non mobile apps - if json_object.get("mobileVersion") is None: - del graphite_json[json_object.get("applicationId")]["mobileVersion"] - - # removing empty title from apps with no title - if json_object.get("applicationTitle") is None: - del graphite_json[json_object.get("applicationId")]["applicationTitle"] - - # delete build.json file - os.remove(path_in_str) - - # ordering json file - graphite_json_sorted = OrderedDict(sorted(graphite_json.items())) - - return graphite_json_sorted - - -def get_mobile_and_is_image_tags(): - - images_json = {} - - # getting mobileapi image version from entitymgr-suite pod - try: - pods = dynClient.resources.get(api_version="v1", kind="Pod") - podList = pods.get( - namespace=f"mas-{instanceId}-core", - label_selector=f"app={instanceId}-entitymgr-suite", - ) - - if podList is None or podList.items is None or len(podList.items) == 0: - pass - else: - podName = podList.items[0].metadata.name - - # list navigator zip packages in mobileapi pod - ocExecCommand = [ - "oc", - "exec", - "-n", - f"mas-{instanceId}-core", - podName, - "--", - "cat", - "/opt/ansible/roles/suite/vars/images.yml", - ] - result = run_cmd(ocExecCommand) - cat_result = result.out.decode("utf-8") - images = yaml.safe_load(cat_result) - images_json.update({"mobileapi": images["defaultTags"]["mobileapi"]}) - except Exception as e: - print(f"Unable to catch images file from core's entitymgr-suite pod: {e}") - sys.exit(1) - - # getting industry solutions images version from entitymgr-ws - try: - pods = dynClient.resources.get(api_version="v1", kind="Pod") - podList = pods.get( - namespace=f"mas-{instanceId}-manage", - label_selector="mas.ibm.com/appType=entitymgr-ws-operator", - ) - - if podList is None or podList.items is None or len(podList.items) == 0: - pass - else: - podName = podList.items[0].metadata.name - - # list navigator zip packages in mobileapi pod - ocExecCommand = [ - "oc", - "exec", - "-n", - f"mas-{instanceId}-manage", - podName, - "--", - "cat", - "/opt/ansible/roles/workspace/vars/images.yml", - ] - result = run_cmd(ocExecCommand) - cat_result = result.out.decode("utf-8") - images = yaml.safe_load(cat_result) - images_json.update(images["defaultTags"]) - - except Exception as e: - print(f"Unable to catch images file from Manage's entitymgr-ws pod: {e}") - sys.exit(1) - - images_json_sorted = OrderedDict(sorted(images_json.items())) - - return images_json_sorted - - -def artifactory_upload(): - - url = artDir + "/fvt-mobile/" + output_filename - bearer = f"Bearer {artKey}" - headers = {"content-type": "application/json", "Authorization": bearer} - - with open(output_filename, "rb") as f: - r = requests.put(url, data=f, headers=headers, timeout=10) - - if r.status_code != 201: - print("Upload failed.") - else: - print("Upload successful") - print("Download URL:", r.json()["downloadUri"]) - - -if __name__ == "__main__": - - if "KUBERNETES_SERVICE_HOST" in os.environ: - config.load_incluster_config() - k8s_config = Configuration.get_default_copy() - k8s_client = client.api_client.ApiClient(configuration=k8s_config) - dynClient = DynamicClient(k8s_client) - else: - k8s_client = config.new_client_from_config() - dynClient = DynamicClient(k8s_client) - - if os.path.isfile(output_filename): - print("Found an existing output file. Deleting...") - os.remove(output_filename) - - print("Retrieving Graphite versions for Manage apps") - graphite_versions = get_graphite_versions() - - print("Retrieving image versions for Manage IS and Add-ons ") - img_versions = get_mobile_and_is_image_tags() - - print("Generating output file with versions") - mobile_is_versions = {} - mobile_is_versions.update( - {"graphite_versions": graphite_versions, "images_versions": img_versions} - ) - - with open(output_filename, "w", encoding="utf-8") as outfile: - json.dump(mobile_is_versions, outfile, indent=4) - - print("Printing gererated file:") - print("************************************************") - with open(output_filename, "r", encoding="utf-8") as readfile: - print(readfile.read()) - print("************************************************") - - # Upload logs conditionally based o env var - if uploadFile: - print("Uploading file to artifactory") - artifactory_upload() - - print("Done") diff --git a/image/cli/app-root/src/mobilever.py b/image/cli/app-root/src/mobilever.py new file mode 100644 index 0000000000..5fbf3865fb --- /dev/null +++ b/image/cli/app-root/src/mobilever.py @@ -0,0 +1,397 @@ +import os +import threading +import zipfile +import sys +import json +import yaml +import requests +from pathlib import Path +from collections import OrderedDict +from subprocess import PIPE, Popen, TimeoutExpired +from kubernetes.client import Configuration +from openshift.dynamic import DynamicClient +from kubernetes import client, config + + +class RunCmdResult(object): + def __init__(self, returnCode, output, error): + self.rc = returnCode + self.out = output + self.err = error + + def successful(self): + return self.rc == 0 + + def failed(self): + return self.rc != 0 + + +class MobVer(object): + + def __init__(self, instanceId, dynClient): + + if dynClient is None: + if "KUBERNETES_SERVICE_HOST" in os.environ: + config.load_incluster_config() + k8s_config = Configuration.get_default_copy() + k8s_client = client.api_client.ApiClient(configuration=k8s_config) + self.dynClient = DynamicClient(k8s_client) + else: + k8s_client = config.new_client_from_config() + self.dynClient = DynamicClient(k8s_client) + else: + self.dynClient = dynClient + + self.instanceId = ( + instanceId if instanceId is not None else os.getenv("INSTANCE_ID") + ) + self.uploadFile = os.getenv("UPLOAD_FILE") + self.buildNum = os.getenv("BUILD_NUM") + self.artKey = os.getenv("ARTIFACTORY_TOKEN") + self.artDir = os.getenv("ARTIFACTORY_UPLOAD_DIR") + self.output_filename = ( + f"{self.instanceId}-{self.buildNum}-mobile-is-versions.json" + ) + + def run_cmd(self, cmdArray, timeout=630): + """ + Run a command on the local host. This drives all the helm operations, + as there is no python Helm client available. + # Parameters + cmdArray (list): Command to execute + timeout (int): How long to allow for the command to complete + # Returns + [int, string, string]: `returnCode`, `stdOut`, `stdErr` + """ + + lock = threading.Lock() + + with lock: + p = Popen(cmdArray, stdin=PIPE, stdout=PIPE, stderr=PIPE, bufsize=-1) + try: + output, error = p.communicate(timeout=timeout) + return RunCmdResult(p.returncode, output, error) + except TimeoutExpired as e: + return RunCmdResult(127, "TimeoutExpired", str(e)) + + def get_maxinst_and_mobileapi_pods(self): + + podName = [] + # retrieving maxinst pod in manage namespace + try: + pods = self.dynClient.resources.get(api_version="v1", kind="Pod") + podList = pods.get( + namespace=f"mas-{self.instanceId}-manage", + label_selector="mas.ibm.com/appType=maxinstudb", + ) + + if podList is None or podList.items is None or len(podList.items) == 0: + print("Pod with label mas.ibm.com/appType=maxinstudb was not found") + else: + podName.append(podList.items[0].metadata.name) + + except Exception as e: + print(f"Unable to download mobile packages from maxinst pod: {e}") + sys.exit(1) + + # retrieving mobile api pod in core namespace + try: + pods = self.dynClient.resources.get(api_version="v1", kind="Pod") + podList = pods.get( + namespace=f"mas-{self.instanceId}-core", + label_selector=f"app={self.instanceId}-mobileapi", + ) + + if podList is None or podList.items is None or len(podList.items) == 0: + print(f"Pod with label app={self.instanceId}-mobileapi was not found") + else: + podName.append(podList.items[0].metadata.name) + + except Exception as e: + print( + f"Unable to download mobileapi navigator package from mobileapi pod: {e}" + ) + sys.exit(1) + + return podName + + def download_mobile_packages(self, podName): + # list all graphite zip packages in maxinst pod + ocExecCommand = [ + "oc", + "exec", + "-n", + f"mas-{self.instanceId}-manage", + podName, + "--", + "ls", + "/opt/IBM/SMP/maximo/tools/maximo/en/graphite/apps", + ] + result = self.run_cmd(ocExecCommand) + ls_result = result.out.decode("utf-8") + apps_list = ls_result.split("\n") + # removes last empty value from the list + apps_list.pop() + + # Download all packages that were found + for a in apps_list: + ocExecCommand = [ + "oc", + "cp", + "-n", + f"mas-{self.instanceId}-manage", + f"{podName}:/opt/IBM/SMP/maximo/tools/maximo/en/graphite/apps/{a}", + f"./{a}", + "--retries=10", + ] + self.run_cmd(ocExecCommand) + + def download_navigator_package(self, podName): + + ocExecCommand = [ + "oc", + "exec", + "-n", + f"mas-{self.instanceId}-core", + podName, + "--", + "ls", + "/etc/mobile/packages", + ] + result = self.run_cmd(ocExecCommand) + ls_result = result.out.decode("utf-8") + apps_list = ls_result.split("\n") + # removes last empty value from the list + apps_list.pop() + + for a in apps_list: + ocExecCommand = [ + "oc", + "cp", + "-n", + f"mas-{self.instanceId}-core", + f"{podName}:/etc/mobile/packages/{a}", + f"./{a}", + "--retries=10", + ] + self.run_cmd(ocExecCommand) + + def extract_build_json_from_zip_files(self, source_zip_files_path): + # Extracting build.json from each file and deleting zip + pathlist = Path(source_zip_files_path).glob("*.zip") + + for app_zip_file in pathlist: + + zip_file_path = f"{source_zip_files_path}/{str(app_zip_file)}" + with zipfile.ZipFile(zip_file_path, "r") as zip_ref: + try: + zip_ref.extract("build.json", ".") + except KeyError: + print(f"There is no build.json file in {app_zip_file}") + with open("build.json", "w", encoding="utf-8") as dummy_file: + warn_json = { + "WARN": { + str( + app_zip_file + ): "File does not contain version information" + } + } + json.dump(warn_json, dummy_file, indent=4) + zip_ref.close() + + zip_file_prefix = zip_file_path.split(".zip") + os.rename( + f"{source_zip_files_path}/build.json", f"{zip_file_prefix[0]}.json" + ) + os.remove(zip_file_path) + + def extract_build_info_from_json_files(self, source_json_files_path): + # dictionary that will contain all graphite versions for all found zips + graphite_json = {} + + pathlist = Path(source_json_files_path).glob("*.json") + for path in pathlist: + path_in_str = str(path) + + with open(path_in_str, "r", encoding="utf-8") as openfile: + json_object = json.load(openfile) + + if json_object.get("WARN") is not None: + graphite_json.update({"WARN": json_object.get("WARN")}) + else: + graphite_json.update( + { + json_object.get("applicationId"): { + "version": json_object.get("version"), + "applicationId": json_object.get("applicationId"), + "applicationTitle": json_object.get("applicationTitle"), + "mobileVersion": json_object.get("mobileVersion"), + "buildToolsVersion": json_object.get("buildToolsVersion"), + "appProcessorVersion": json_object.get( + "appProcessorVersion" + ), + } + } + ) + + # removing empty mobile version or non mobile apps + if json_object.get("mobileVersion") is None: + del graphite_json[json_object.get("applicationId")]["mobileVersion"] + + # removing empty title from apps with no title + if json_object.get("applicationTitle") is None: + del graphite_json[json_object.get("applicationId")][ + "applicationTitle" + ] + + # delete build.json file + os.remove(path_in_str) + + # ordering json file + graphite_json_sorted = OrderedDict(sorted(graphite_json.items())) + + return graphite_json_sorted + + def get_graphite_versions(self): + # This list will contains all files found in the maxinst pod + pods_list = self.get_maxinst_and_mobileapi_pods() + + maxinst_pod = pods_list[0] + mobileapi_pod = pods_list[1] + + self.download_mobile_packages(podName=maxinst_pod) + + self.download_navigator_package(podName=mobileapi_pod) + + self.extract_build_json_from_zip_files(source_zip_files_path=".") + + graphite_ver = self.extract_build_info_from_json_files( + source_json_files_path="." + ) + + return graphite_ver + + def get_mobile_and_is_image_tags(self): + + images_json = {} + + # getting mobileapi image version from entitymgr-suite pod + try: + pods = self.dynClient.resources.get(api_version="v1", kind="Pod") + podList = pods.get( + namespace=f"mas-{self.instanceId}-core", + label_selector=f"app={self.instanceId}-entitymgr-suite", + ) + + if podList is None or podList.items is None or len(podList.items) == 0: + pass + else: + podName = podList.items[0].metadata.name + + # list navigator zip packages in mobileapi pod + ocExecCommand = [ + "oc", + "exec", + "-n", + f"mas-{self.instanceId}-core", + podName, + "--", + "cat", + "/opt/ansible/roles/suite/vars/images.yml", + ] + result = self.run_cmd(ocExecCommand) + cat_result = result.out.decode("utf-8") + images = yaml.safe_load(cat_result) + images_json.update({"mobileapi": images["defaultTags"]["mobileapi"]}) + except Exception as e: + print(f"Unable to catch images file from core's entitymgr-suite pod: {e}") + sys.exit(1) + + # getting industry solutions images version from entitymgr-ws + try: + pods = self.dynClient.resources.get(api_version="v1", kind="Pod") + podList = pods.get( + namespace=f"mas-{self.instanceId}-manage", + label_selector="mas.ibm.com/appType=entitymgr-ws-operator", + ) + + if podList is None or podList.items is None or len(podList.items) == 0: + pass + else: + podName = podList.items[0].metadata.name + + # list navigator zip packages in mobileapi pod + ocExecCommand = [ + "oc", + "exec", + "-n", + f"mas-{self.instanceId}-manage", + podName, + "--", + "cat", + "/opt/ansible/roles/workspace/vars/images.yml", + ] + result = self.run_cmd(ocExecCommand) + cat_result = result.out.decode("utf-8") + images = yaml.safe_load(cat_result) + images_json.update(images["defaultTags"]) + + except Exception as e: + print(f"Unable to catch images file from Manage's entitymgr-ws pod: {e}") + sys.exit(1) + + images_json_sorted = OrderedDict(sorted(images_json.items())) + + return images_json_sorted + + def artifactory_upload(self): + + url = self.artDir + "/fvt-mobile/" + self.output_filename + bearer = f"Bearer {self.artKey}" + headers = {"content-type": "application/json", "Authorization": bearer} + + with open(self.output_filename, "rb") as f: + r = requests.put(url, data=f, headers=headers, timeout=10) + + if r.status_code != 201: + print("Upload failed.") + else: + print("Upload successful") + print("Download URL:", r.json()["downloadUri"]) + + +if __name__ == "__main__": + + MobVersion = MobVer(instanceId=None, dynClient=None) + + if os.path.isfile(MobVersion.output_filename): + print("Found an existing output file. Deleting...") + os.remove(MobVersion.output_filename) + + print("Retrieving Graphite versions for Manage apps") + graphite_versions = MobVersion.get_graphite_versions() + + print("Retrieving image versions for Manage IS and Add-ons ") + img_versions = MobVersion.get_mobile_and_is_image_tags() + + print("Generating output file with versions") + mobile_is_versions = {} + mobile_is_versions.update( + {"graphite_versions": graphite_versions, "images_versions": img_versions} + ) + + with open(MobVersion.output_filename, "w", encoding="utf-8") as outfile: + json.dump(mobile_is_versions, outfile, indent=4) + + print("Printing gererated file:") + print("************************************************") + with open(MobVersion.output_filename, "r", encoding="utf-8") as readfile: + print(readfile.read()) + print("************************************************") + + # Upload logs conditionally based o env var + if MobVersion.uploadFile: + print("Uploading file to artifactory") + MobVersion.artifactory_upload() + + print("Done") diff --git a/image/cli/app-root/src/register-start.py b/image/cli/app-root/src/register-start.py index b3ba156b77..5914753515 100644 --- a/image/cli/app-root/src/register-start.py +++ b/image/cli/app-root/src/register-start.py @@ -25,11 +25,12 @@ instanceId = os.getenv("DEVOPS_ENVIRONMENT", "none") build = os.getenv("DEVOPS_BUILD_NUMBER") suite = os.getenv("DEVOPS_SUITE_NAME", "") + productId = os.getenv("PRODUCT_ID", "ibm-mas-devops") - productId = "ibm-mas-devops" channelId = "n/a" cliVersion = os.getenv("VERSION", "unknown") ansibleDevopsVersion = os.getenv("ANSIBLE_DEVOPS_VERSION", "unknown") + gitopsVersion = os.getenv("GITOPS_VERSION", "unknown") if suite == "": print ("Results not recorded because DEVOPS_SUITE_NAME is not defined") @@ -52,6 +53,7 @@ print(f"CLI Version ............ {cliVersion}") print(f"mas_devops Version ..... {ansibleDevopsVersion}") + print(f"gitops Version ......... {gitopsVersion}") print(f"Run ID ................. {runId}") print(f"Result ID .............. {resultId}") @@ -84,11 +86,12 @@ } }, '$set': { - f"products.ibm-mas-devops.productId": productId, - f"products.ibm-mas-devops.channelId": channelId, - f"products.ibm-mas-devops.version": cliVersion, - f"products.ibm-mas-devops.ansibleDevopsVersion": ansibleDevopsVersion, - f"products.ibm-mas-devops.results.{suite}": suiteSummary + f"products.{productId}.productId": productId, + f"products.{productId}.channelId": channelId, + f"products.{productId}.version": cliVersion, + f"products.{productId}.ansibleDevopsVersion": ansibleDevopsVersion, + f"products.{productId}.gitopsVersion": gitopsVersion, + f"products.{productId}.results.{suite}": suiteSummary } }, upsert=True diff --git a/image/cli/app-root/src/save-junit-to-mongo.py b/image/cli/app-root/src/save-junit-to-mongo.py index ef32ebf91f..1a3057bc83 100644 --- a/image/cli/app-root/src/save-junit-to-mongo.py +++ b/image/cli/app-root/src/save-junit-to-mongo.py @@ -26,8 +26,8 @@ build = os.getenv("DEVOPS_BUILD_NUMBER") suite = os.getenv("DEVOPS_SUITE_NAME", "") junitOutputDir = os.getenv("JUNIT_OUTPUT_DIR", "/tmp") + productId = os.getenv("PRODUCT_ID", "ibm-mas-devops") - productId = "ibm-mas-devops" channelId = "n/a" cliVersion = os.getenv("VERSION", "unknown") ansibleDevopsVersion = os.getenv("ANSIBLE_DEVOPS_VERSION", "unknown") @@ -71,7 +71,18 @@ bf = Yahoo(dict_type=dict) resultDoc = bf.data(root) - for testcase in resultDoc["testsuites"]["testsuite"]["testcase"]: + if isinstance(resultDoc["testsuites"]["testsuite"]["testcase"], list) : + for testcase in resultDoc["testsuites"]["testsuite"]["testcase"]: + testcase["name"] = testcase["name"].replace("[localhost] localhost: ", "") + # Playbooks don't have ibm/mas_devops in the classname but do have /opt/app-root. + # Roles have both ibm/mas_devops and /opt/app-root. + # Guard against both and remove when required. + if "/opt/app-root/" in testcase["classname"]: + testcase["classname"] = testcase["classname"].split("/opt/app-root/")[1] + if "ibm/mas_devops/" in testcase["classname"]: + testcase["classname"] = testcase["classname"].split("ibm/mas_devops/")[1] + else: + testcase = resultDoc["testsuites"]["testsuite"]["testcase"] testcase["name"] = testcase["name"].replace("[localhost] localhost: ", "") # Playbooks don't have ibm/mas_devops in the classname but do have /opt/app-root. # Roles have both ibm/mas_devops and /opt/app-root. @@ -121,11 +132,11 @@ } }, '$set': { - f"products.ibm-mas-devops.productId": productId, - f"products.ibm-mas-devops.channelId": channelId, - f"products.ibm-mas-devops.version": cliVersion, - f"products.ibm-mas-devops.ansibleDevopsVersion": ansibleDevopsVersion, - f"products.ibm-mas-devops.results.{suite}": suiteSummary + f"products.{productId}.productId": productId, + f"products.{productId}.channelId": channelId, + f"products.{productId}.version": cliVersion, + f"products.{productId}.ansibleDevopsVersion": ansibleDevopsVersion, + f"products.{productId}.results.{suite}": suiteSummary } }, upsert=True diff --git a/image/cli/app-root/src/wait-for-tekton.sh b/image/cli/app-root/src/wait-for-tekton.sh index 5c49ffe39b..65f27f33a5 100644 --- a/image/cli/app-root/src/wait-for-tekton.sh +++ b/image/cli/app-root/src/wait-for-tekton.sh @@ -85,7 +85,10 @@ done echo "Completion Time = $COMPLETION_TIME" echo "Retries Used = $RETRIES_USED" -RESULT=$(oc -n ${NAMESPACE} get ${TYPE}/$NAME -o jsonpath='{.status.conditions[0].status}') +RESULT="" +while [[ "$RESULT" == "" ]]; do + RESULT=$(oc -n ${NAMESPACE} get ${TYPE}/$NAME -o jsonpath='{.status.conditions[0].status}') +done if [[ "$RESULT" == "True" ]]; then echo "Result = ${TYPE} completed successfully" diff --git a/image/cli/mascli/functions/gitops_cluster b/image/cli/mascli/functions/gitops_cluster index 252fbbaf26..b51adb7868 100644 --- a/image/cli/mascli/functions/gitops_cluster +++ b/image/cli/mascli/functions/gitops_cluster @@ -58,8 +58,12 @@ Cluster Promotion (Optional): --cluster-promotion-target-pr-title ${COLOR_YELLOW}CLUSTER_PROMOTION_TARGET_PR_TITLE${TEXT_RESET} The title of the PR if a PR is to be created --cluster-promotion-cluster-values ${COLOR_YELLOW}CLUSTER_PROMOTION_CLUSTER_VALUES${TEXT_RESET} A list of values in json format to update in the target git repo. -Notifications: - --slack-channel-id ${COLOR_YELLOW}SLACK_CHANNEL_ID${TEXT_RESET} Slack channel for ArgoCD to notify when an app sync has completed or failed +DevOps Details (Optional): + --devops-build-number ${COLOR_YELLOW}DEVOPS_BUILD_NUMBER${TEXT_RESET} The build number to associate with the junitreporter for each argocd app sync + --devops-mongo-uri ${COLOR_YELLOW}DEVOPS_MONGO_URI${TEXT_RESET} The Mongo uri used by the junitreporter to store test/run records + +Notifications (Optional): + --slack-channel-id ${COLOR_YELLOW}SLACK_CHANNEL_ID${TEXT_RESET} Slack channel for ArgoCD to notify when an app sync has completed or failed Other Commands: -h, --help Show this help message @@ -200,6 +204,15 @@ function gitops_cluster_noninteractive() { export CLUSTER_PROMOTION_CLUSTER_VALUES=$1 && shift ;; + + # DevOps Details + --devops-build-number) + export DEVOPS_BUILD_NUMBER=$1 && shift + ;; + --devops-mongo-uri) + export DEVOPS_MONGO_URI=$1 && shift + ;; + # IBM CIS Cert Manager --dns-provider) export DNS_PROVIDER=$1 && shift @@ -241,6 +254,10 @@ function gitops_cluster_noninteractive() { [[ -z "$SECRETS_PATH" ]] && gitops_cluster_help "SECRETS_PATH is not set" + if [[ -n "$DEVOPS_MONGO_URI" ]]; then + [[ -z "$DEVOPS_BUILD_NUMBER" ]] && gitops_cluster_help "DEVOPS_BUILD_NUMBER is not set" + fi + if [[ "$CLUSTER_PROMOTION" == "true" ]]; then [[ -z "$CLUSTER_PROMOTION_TARGET_GITHUB_PAT" ]] && gitops_cluster_help "CLUSTER_PROMOTION_TARGET_GITHUB_PAT is not set" [[ -z "$CLUSTER_PROMOTION_TARGET_GITHUB_HOST" ]] && gitops_cluster_help "CLUSTER_PROMOTION_TARGET_GITHUB_HOST is not set" @@ -354,6 +371,12 @@ function gitops_cluster() { reset_colors fi + echo "${TEXT_DIM}" + echo_h2 "DevOps Details" " " + echo_reset_dim "Devops Build Number ............. ${COLOR_MAGENTA}${DEVOPS_BUILD_NUMBER}" + echo_reset_dim "Devops Mongo Uri ................ ${COLOR_MAGENTA}${DEVOPS_MONGO_URI:0:8}" + reset_colors + # Set up secrets # --------------------------------------------------------------------------- echo @@ -367,6 +390,15 @@ function gitops_cluster() { export SECRET_NAME_CIS=${ACCOUNT_ID}${SM_DELIM}${CLUSTER_ID}${SM_DELIM}cis export SECRET_KEY_IBM_APIKEY=${SECRET_NAME_CIS}#ibm_apikey + export SECRET_NAME_DEVOPS_MONGO=${ACCOUNT_ID}${SM_DELIM}${CLUSTER_ID}${SM_DELIM}devops + export SECRET_KEY_DEVOPS_MONGO=${SECRET_NAME_DEVOPS_MONGO}#devops_mongo_uri + + if [ -n "$DEVOPS_MONGO_URI" ];then + echo "- Update DEVOPS_MONGO_URI secret" + TAGS="[{\"Key\": \"source\", \"Value\": \"gitops_cluster\"}, {\"Key\": \"account\", \"Value\": \"${ACCOUNT_ID}\"}, {\"Key\": \"cluster\", \"Value\": \"${CLUSTER_ID}\"}]" + sm_update_secret $SECRET_NAME_DEVOPS_MONGO "{\"devops_mongo_uri\": \"${DEVOPS_MONGO_URI}\"}" "${TAGS}" + fi + if [ -z $GIT_SSH ]; then export GIT_SSH="false" fi diff --git a/image/cli/mascli/functions/gitops_db2u b/image/cli/mascli/functions/gitops_db2u index 67d8db2977..a5dec9a8ce 100644 --- a/image/cli/mascli/functions/gitops_db2u +++ b/image/cli/mascli/functions/gitops_db2u @@ -127,7 +127,7 @@ function gitops_db2u_noninteractive() { [[ -z "$ACCOUNT_ID" ]] && gitops_db2u_help "ACCOUNT_ID is not set" [[ -z "$REGION" ]] && gitops_db2u_help "REGION is not set" [[ -z "$CLUSTER_ID" ]] && gitops_db2u_help "CLUSTER_ID is not set" - [[ -z "$MAS_INSTANCE_ID" ]] && gitops_cluster_help "MAS_INSTANCE_ID is not set" + [[ -z "$MAS_INSTANCE_ID" ]] && gitops_db2u_help "MAS_INSTANCE_ID is not set" if [[ "$GITHUB_PUSH" == "true" ]]; then diff --git a/image/cli/mascli/functions/gitops_dro b/image/cli/mascli/functions/gitops_dro index 8e5d92cf31..a578d209a2 100644 --- a/image/cli/mascli/functions/gitops_dro +++ b/image/cli/mascli/functions/gitops_dro @@ -140,7 +140,7 @@ function gitops_dro_noninteractive() { [[ -z "$GITOPS_WORKING_DIR" ]] && gitops_dro_help "GITOPS_WORKING_DIR is not set" [[ -z "$ACCOUNT_ID" ]] && gitops_dro_help "ACCOUNT_ID is not set" [[ -z "$CLUSTER_ID" ]] && gitops_dro_help "CLUSTER_ID is not set" - [[ -z "$REGION_ID" && -z "$SM_AWS_REGION" ]] && gitops_cluster_help "REGION_ID or SM_AWS_REGION is not set" + [[ -z "$REGION_ID" && -z "$SM_AWS_REGION" ]] && gitops_dro_help "REGION_ID or SM_AWS_REGION is not set" if [[ "$GITHUB_PUSH" == "true" ]]; then [[ -z "$GITHUB_HOST" ]] && gitops_dro_help "GITHUB_HOST is not set" diff --git a/image/cli/mascli/functions/gitops_mas_fvt_preparer b/image/cli/mascli/functions/gitops_mas_fvt_preparer index 2ec69c5a41..a87b01819a 100644 --- a/image/cli/mascli/functions/gitops_mas_fvt_preparer +++ b/image/cli/mascli/functions/gitops_mas_fvt_preparer @@ -82,8 +82,11 @@ function gitops_mas_fvt_preparer() { export SYNC_WITH_INSTALL=false #If this is the FVT Core run then don't call finalize at the end of this run if [[ "$LAUNCHER_ID" == "core" ]]; then - export RUN_FINALIZE=false + export FINALIZE=false + export SET_FINISHED=false fi + export DEPROVISION=false + #FVT pipeline to run export PIPELINE_NAME=$FVT_PIPELINE_NAME ansible-playbook ibm.mas_fvt.setup_pipeline diff --git a/image/cli/mascli/functions/gitops_suite_app_config b/image/cli/mascli/functions/gitops_suite_app_config index 8956bf995b..9af6ef64e3 100644 --- a/image/cli/mascli/functions/gitops_suite_app_config +++ b/image/cli/mascli/functions/gitops_suite_app_config @@ -36,6 +36,7 @@ Maximo Application Suite: --mas-manual-cert-mgmt ${COLOR_YELLOW}MAS_MANUAL_CERT_MGMT${TEXT_RESET} MAS Manual Cert Management --mas-manual-certs-yaml ${COLOR_YELLOW}MAS_MANUAL_CERTS_YAML${TEXT_RESET} YAML file location containing combined MAS Manual Certs of manage app --ingress ${COLOR_YELLOW}INGRESS${TEXT_RESET} true/false, If true, ingress-controller for cis-proxy will be configured + --run-sanity-test ${COLOR_YELLOW}RUN_SANITY_TEST${TEXT_RESET} true/false, If true, then the sanity tests are run against the app Below is a sample yaml file template representing manual_certs dictionary ( key: << value base64 encoded content of cert file >>) where key is <>_<> name and value will be base64 encoded of the respective ca/tls file, @@ -154,6 +155,9 @@ function gitops_suite_app_config_noninteractive() { -W|--mas-workspace-id) export MAS_WORKSPACE_ID=$1 && shift ;; + --run-sanity-test) + export RUN_SANITY_TEST=$1 && shift + ;; --ingress) export INGRESS=$1 && shift ;; @@ -283,6 +287,8 @@ function gitops_suite_app_config() { export CPD_INSTANCE_NAMESPACE=${CPD_INSTANCE_NAMESPACE:-"ibm-cpd-${MAS_INSTANCE_ID}-instance"} # Disable provision public ingress controller by default export INGRESS=${INGRESS:-"false"} + # Disable sanity tests by default + export RUN_SANITY_TEST=${RUN_SANITY_TEST:-"false"} echo reset_colors echo_h2 "Review Settings" @@ -342,6 +348,7 @@ function gitops_suite_app_config() { echo_reset_dim "MAS Manual Cert Mgt ..................... ${COLOR_MAGENTA}${MAS_MANUAL_CERT_MGMT}" echo_reset_dim "MAS MANUAL CERTS YAML ................... ${COLOR_MAGENTA}${MAS_MANUAL_CERTS_YAML}" echo_reset_dim "Public Ingress Controller ............... ${COLOR_MAGENTA}${INGRESS}" + echo_reset_dim "Run Sanity Test ......................... ${COLOR_MAGENTA}${RUN_SANITY_TEST}" reset_colors diff --git a/image/cli/mascli/functions/gitops_utils b/image/cli/mascli/functions/gitops_utils index e631c81f2d..495aea32c2 100644 --- a/image/cli/mascli/functions/gitops_utils +++ b/image/cli/mascli/functions/gitops_utils @@ -3,6 +3,10 @@ AVP_TYPE="aws" # I haven't added support for IBM DELIMIITER="/" +function logts() { + echo "[$(date '+%Y-%m-%d %H:%M:%S.%3N')]" +} + function sm_login() { if [[ "$AVP_TYPE" == "aws" ]]; then echo "Logging into AWS SecretsManager ..." @@ -251,11 +255,15 @@ function clone_target_git_repo() { SSH_PATH=$6 CURRENT_DIR=$PWD cd $LOCAL_DIR - - echo "git: Cloning $GITHUB_HOST:$GITHUB_ORG/$GITHUB_REPO branch $GIT_BRANCH into $LOCAL_DIR working directory" if [ "$SSH_PATH" == "false" ]; then + echo "" + echo "$(logts) git clone https://git:****@$GITHUB_HOST/$GITHUB_ORG/$GITHUB_REPO.git -b $GIT_BRANCH" + echo "-------------------------------------------------" git clone https://git:$GITHUB_PAT@$GITHUB_HOST/$GITHUB_ORG/$GITHUB_REPO.git -b $GIT_BRANCH || exit 1 else + echo "" + echo "$(logts) git -c \"core.sshCommand=ssh -i $SSH_PATH -F /dev/null\" clone git@$GITHUB_HOST:$GITHUB_ORG/$GITHUB_REPO.git -b $GIT_BRANCH" + echo "-------------------------------------------------" git -c "core.sshCommand=ssh -i $SSH_PATH -F /dev/null" clone git@$GITHUB_HOST:$GITHUB_ORG/$GITHUB_REPO.git -b $GIT_BRANCH || exit 1 fi cd $PWD @@ -274,7 +282,9 @@ function save_to_target_git_repo() { echo "git: Changing to directory $LOCAL_DIR" cd $LOCAL_DIR || exit 1 - echo "git: Adding all files in $LOCAL_DIR working directory" + echo "" + echo "$(logts) git add -v ." + echo "-------------------------------------------------" FILES_ADDED_OUTPUT="$(git add -v .)" return_code=$? if [ $return_code -ne 0 ]; then @@ -285,22 +295,32 @@ function save_to_target_git_repo() { echo "git: Added ${FILES_ADDED} files" if [ "$FILES_ADDED" != "0" ]; then - echo "git: Committing files using message $COMMIT_MSG" + echo "" + echo "$(logts) git commit -m \"$COMMIT_MSG\"" + echo "-------------------------------------------------" git commit -m "$COMMIT_MSG" || exit 1 retries=5 interval=30 index=0 while true; do - echo "git: fetch origin $GIT_BRANCH" + echo "" + echo "$(logts) git fetch origin $GIT_BRANCH" + echo "-------------------------------------------------" git fetch origin $GIT_BRANCH || exit 1 - echo "git: pull origin --rebase" + echo "" + echo "$(logts) git pull origin --rebase" + echo "-------------------------------------------------" git pull origin --rebase || exit 1 - echo "git: pull origin $GIT_BRANCH --rebase" + echo "" + echo "$(logts) git pull origin $GIT_BRANCH --rebase" + echo "-------------------------------------------------" git pull origin $GIT_BRANCH --rebase || exit 1 - echo "git: Pushing changes to branch $GIT_BRANCH" + echo "" + echo "$(logts) git push -u origin $GIT_BRANCH" + echo "-------------------------------------------------" git push -u origin $GIT_BRANCH return_code=$? if [ $return_code -eq 0 ]; then @@ -340,11 +360,13 @@ function unlock_git_repo() { if [[ -d "${GITOPS_REPO_DIR}" ]]; then echo "" - echo "Deleting "${GIT_LOCK_BRANCH}" from remote" + echo "$(logts) git push origin --delete ${GIT_LOCK_BRANCH}" + echo "-------------------------------------------------" git -C "${GITOPS_REPO_DIR}" push origin --delete "${GIT_LOCK_BRANCH}" || exit 1 echo "" - echo "Deleting ${GITOPS_REPO_DIR} from filesystem" + echo "$(logts) rm -rf \"${GITOPS_REPO_DIR}\"" + echo "-------------------------------------------------" rm -rf "${GITOPS_REPO_DIR}" || exit 1 fi } @@ -352,6 +374,7 @@ function unlock_git_repo() { + function git_lock_branch_name() { LOCK_NAME=$1 @@ -395,25 +418,21 @@ function clone_and_lock_target_git_repo() { for (( c=1; c<="${RETRIES}"; c++ )); do echo "" - echo "= clone_and_lock_git_repo: attempt ${c} of ${RETRIES}" + echo "clone_and_lock_git_repo: attempt ${c} of ${RETRIES}" echo "=================================================" # Remove any clones created by prior attempts rm -rf "${GITOPS_REPO_DIR}" - echo - echo "- clone_target_git_repo: ${GITHUB_HOST} ${GITHUB_ORG} ${GITHUB_REPO} ${GIT_BRANCH} ${LOCAL_DIR} ${SSH_PATH}" - echo "-------------------------------------------------" clone_target_git_repo "${GITHUB_HOST}" "${GITHUB_ORG}" "${GITHUB_REPO}" "${GIT_BRANCH}" "${LOCAL_DIR}" "${SSH_PATH}" - # If the lock branch exists currently on the remote, retry after a delay echo - echo "- clone_and_lock_git_repo: ls-remote --heads origin ${GIT_LOCK_BRANCH}" + echo "$(logts) git ls-remote --heads origin ${GIT_LOCK_BRANCH}" echo "-------------------------------------------------" LS_REMOTE_STDOUT=$(git -C "${GITOPS_REPO_DIR}" ls-remote --heads origin ${GIT_LOCK_BRANCH}) if [[ -n "${LS_REMOTE_STDOUT}" ]]; then - echo "clone_and_lock_git_repo: Lock branch ${GIT_LOCK_BRANCH} currently in use by another process, retry in ${RETRY_DELAY_SECONDS}s" + echo "Lock branch ${GIT_LOCK_BRANCH} currently in use by another process, retry in ${RETRY_DELAY_SECONDS}s" echo "..." sleep ${RETRY_DELAY_SECONDS} continue @@ -425,27 +444,43 @@ function clone_and_lock_target_git_repo() { # Create the lock branch locally echo - echo "- clone_and_lock_git_repo: checkout -b ${GIT_LOCK_BRANCH}" + echo "$(logts) git checkout -b ${GIT_LOCK_BRANCH}" echo "-------------------------------------------------" git -C "${GITOPS_REPO_DIR}" checkout -b "${GIT_LOCK_BRANCH}" - # To definitively acquire the "lock", we create and commit a temporary "lock file"; - # This will mean that, amongst n scripts running in parallel and in sync (i.e. where all invokations have passed the initial git ls-remote check), - # at most 1 invokation will be able to successfully perform the push below. - touch "${GITOPS_REPO_DIR}/${LOCKFILE_NAME}" + # To definitively acquire the "lock", we attempt to create, commit and push a temporary "lock file"; + # This will mean that, amongst n processes running in parallel and in sync (i.e. where all processes have passed the initial git ls-remote check), + # at most 1 process will be able to successfully perform the push below. + + # Additionally, we need to ensure the commit hash generated by git is unique amongst all concurrent processes competing for the lock. + # The commit hash is generated from tree hash (e.g. file content), parent commit hash, committer information, commit message and timestamp (with second-level precision). + + # It's entirely possible that these could all be the same across 2 or more competing processes. If this happens, 2 or more processes may successfully + # execute the push below. + # One process will create the branch (reporting "[new branch]"), the others will see that the remote has the same commit hashes in its history and will just report "Everything up-to-date". + + # If this happens, 2 or more competing processes will have successfully acquired the lock, which defeats the point of the lock and will likely result + # in an unresolvable merge conflict in one or more of the competing processes when they attempt to merge their updates to GIT_BRANCH. + + # To fix this, we need to ensure each process generates a unique commmit hash. The easiest way to do this (without requiring additional parameters) + # is to stick a UUID in the lockfile. This will result in a different tree hash and thus overall commit hash in all competing processes. + cat /proc/sys/kernel/random/uuid > "${GITOPS_REPO_DIR}/${LOCKFILE_NAME}" + echo "" + echo "Created ${GITOPS_REPO_DIR}/${LOCKFILE_NAME} with content:" + cat "${GITOPS_REPO_DIR}/${LOCKFILE_NAME}" echo - echo "- clone_and_lock_git_repo: add ${LOCKFILE_NAME}" + echo "$(logts) git add ${LOCKFILE_NAME}" echo "-------------------------------------------------" git -C "${GITOPS_REPO_DIR}" add ${LOCKFILE_NAME} echo - echo "- clone_and_lock_git_repo: commit -m 'Acquire lock branch'" + echo "$(logts) git commit -m 'Acquire lock branch'" echo "-------------------------------------------------" git -C "${GITOPS_REPO_DIR}" commit -m 'Acquire lock branch' echo - echo "- clone_and_lock_git_repo: push --atomic -u origin ${GIT_LOCK_BRANCH}" + echo "$(logts) git push --atomic -u origin ${GIT_LOCK_BRANCH}" echo "-------------------------------------------------" git -C "${GITOPS_REPO_DIR}" push --atomic -u origin "${GIT_LOCK_BRANCH}" GIT_PUSH_RC=$? @@ -454,20 +489,57 @@ function clone_and_lock_target_git_repo() { # Now we've created the remote lock branch, we are blocking any other invokations of this script # Register an exit trap to ensure we delete the remote branch whatever happens trap "unlock_git_repo ${GIT_LOCK_BRANCH} ${GITOPS_REPO_DIR}" EXIT + echo "" - echo "= clone_and_lock_git_repo: acquired lock on branch ${GIT_LOCK_BRANCH}; proceeding..." + echo "acquired lock on branch ${GIT_LOCK_BRANCH}; ensuring that we have the latest from ${GIT_BRANCH}..." + + # It's possible that *conflicting* commits (i.e. from another run sharing the same GIT_LOCK_BRANCH) + # have been made to GIT_BRANCH between cloning GIT_BRANCH here (clone_target_git_repo call above) + # and successfully acquiring GIT_LOCK_BRANCH + + # The sequence of events that hit this race condition are as follows: + # - this process clones GIT_BRANCH that has commits up to X + # - another process with the same GIT_LOCK_BRANCH pushes commit Y to GIT_BRANCH and deletes the GIT_LOCK_BRANCH + # - this process successfully acquires GIT_LOCK_BRANCH and so proceeds + # - but the version of GIT_BRANCH cloned in this process does not have commit Y in it, so the GIT_LOCK_BRANCH does not include Y + + # because Y (in this case) originates from a process sharing GIT_LOCK_BRANCH, it's likely that it affects the same + # file that this process is about to update and so is likely to lead to an unresolvable merge conflict when we attempt to + # merge GIT_LOCK_BRANCH updates back into GIT_BRANCH in the save_and_unlock_target_git_repo call at the end + + # So, now we've acquired GIT_LOCK_BRANCH (thus ensuring no further conflicting commits can be made to master), + # we need to ensure we are basing our changes on the latest version of GIT_BRANCH. + + # This is acheived by rebasing GIT_LOCK_BRANCH on GIT_BRANCH then forcing the remote lock branch to line up using a --force push + # NOTE: --force is safe here since we are the sole current "owners" of GIT_LOCK_BRANCH + # so any commits made to GIT_LOCK_BRANCH by any other concurrent processes can be disregarded + + # NOTE: of course other processes could be making other commits to git at any time during execution of this process. + # this is fine since they *must* be from processes that do not share GIT_LOCK_BRANCH, so will not affect + # the same files updated by this process and so will be auto-mergable. + + echo + echo "$(logts) git pull origin $GIT_BRANCH --rebase" + echo "-------------------------------------------------" + git -C "${GITOPS_REPO_DIR}" pull origin $GIT_BRANCH --rebase || exit 1 + + echo + echo "$(logts) git push --force -u origin ${GIT_LOCK_BRANCH}" + echo "-------------------------------------------------" + git -C "${GITOPS_REPO_DIR}" push --force -u "origin" "${GIT_LOCK_BRANCH}" echo "=================================================" + return 0 fi echo "" - echo "- clone_and_lock_git_repo: failed to acquire Lock branch ${GIT_LOCK_BRANCH}, retry in ${RETRY_DELAY_SECONDS}s" + echo "failed to acquire Lock branch ${GIT_LOCK_BRANCH}, retry in ${RETRY_DELAY_SECONDS}s" echo "..." sleep ${RETRY_DELAY_SECONDS} done - echo "= clone_and_lock_git_repo: non-recoverable failure" + echo "clone_and_lock_git_repo: non-recoverable failure" echo "=================================================" return 1 @@ -491,34 +563,34 @@ function git_push_with_retries { for (( c=1; c<="${RETRIES}"; c++ )); do echo - echo "= git_push_with_retries: attempt ${c} of ${RETRIES}" + echo "git_push_with_retries: attempt ${c} of ${RETRIES}" echo "=================================================" echo - echo "- git_push_with_retries: pull origin $GIT_BRANCH --rebase" + echo "$(logts) git pull origin $GIT_BRANCH --rebase" echo "-------------------------------------------------" git -C "${GITOPS_REPO_DIR}" pull origin "${GIT_BRANCH}" --rebase echo - echo "- git_push_with_retries: push -u origin ${GIT_BRANCH}" + echo "$(logts) git push -u origin ${GIT_BRANCH}" echo "-------------------------------------------------" git -C "${GITOPS_REPO_DIR}" push -u origin "${GIT_BRANCH}" rc=$? if [[ $rc == "0" ]]; then echo "" - echo "= git_push_with_retries: success" + echo "git_push_with_retries: success" echo "=================================================" return 0 fi echo "" - echo "- git_push_with_retries: failed (rc: ${rc}), retry in ${RETRY_DELAY_SECONDS}s" + echo "git_push_with_retries: failed (rc: ${rc}), retry in ${RETRY_DELAY_SECONDS}s" echo "..." sleep $RETRY_DELAY_SECONDS done echo "" - echo "= git_push_with_retries: non-recoverable failure" + echo "git_push_with_retries: non-recoverable failure" echo "=================================================" return 1 } @@ -535,7 +607,7 @@ function git_push_with_retries { # fi function save_and_unlock_target_git_repo { echo - echo "= save_and_unlock_target_git_repo" + echo "save_and_unlock_target_git_repo" echo "=================================================" GITHUB_REPO="$1" GIT_BRANCH="$2" @@ -552,12 +624,12 @@ function save_and_unlock_target_git_repo { # commit and push all changes echo - echo "- save_and_unlock_target_git_repo: add -v ." + echo "$(logts) git add -v ." echo "-------------------------------------------------" git -C "${GITOPS_REPO_DIR}" add -v . || exit 1 echo - echo "- save_and_unlock_target_git_repo: commit -m ${GIT_COMMIT_MSG}" + echo "$(logts) git commit -m ${GIT_COMMIT_MSG}" echo "-------------------------------------------------" git -C "${GITOPS_REPO_DIR}" commit -m "${GIT_COMMIT_MSG}" @@ -569,23 +641,23 @@ function save_and_unlock_target_git_repo { fi echo - echo "- save_and_unlock_target_git_repo: push -u origin ${GIT_LOCK_BRANCH}" + echo "$(logts) git push -u origin ${GIT_LOCK_BRANCH}" echo "-------------------------------------------------" git -C "${GITOPS_REPO_DIR}" push -u origin "${GIT_LOCK_BRANCH}" || exit 1 # Merge back to master echo - echo "- save_and_unlock_target_git_repo: switch ${GIT_BRANCH}" + echo "$(logts) git switch ${GIT_BRANCH}" echo "-------------------------------------------------" git -C "${GITOPS_REPO_DIR}" switch "${GIT_BRANCH}" || exit 1 echo - echo "- save_and_unlock_target_git_repo: pull origin $GIT_BRANCH --rebase" + echo "$(logts) git pull origin $GIT_BRANCH --rebase" echo "-------------------------------------------------" git -C "${GITOPS_REPO_DIR}" pull origin $GIT_BRANCH --rebase || exit 1 echo - echo "- save_and_unlock_target_git_repo: merge --squash ${GIT_LOCK_BRANCH}" + echo "$(logts) git merge --squash ${GIT_LOCK_BRANCH}" echo "-------------------------------------------------" git -C "${GITOPS_REPO_DIR}" merge --squash "${GIT_LOCK_BRANCH}" || exit 1 @@ -601,7 +673,7 @@ function save_and_unlock_target_git_repo { fi echo - echo "- save_and_unlock_target_git_repo:: commit -m ${GIT_COMMIT_MSG}" + echo "$(logts) git commit -m ${GIT_COMMIT_MSG}" echo "-------------------------------------------------" git -C "${GITOPS_REPO_DIR}" commit -m "${GIT_COMMIT_MSG}" @@ -624,7 +696,7 @@ function save_and_unlock_target_git_repo { echo - echo "= save_and_unlock_target_git_repo: success" + echo "save_and_unlock_target_git_repo: success" echo "=================================================" } @@ -761,10 +833,14 @@ function check_argo_app_synced() { function check_argo_app_healthy() { APPLICATION=$1 - CLUSTER_WATCHER=$2 + MAX_CHECKS=$2 COUNT=0 while true; do - echo "argo:check_argo_app_healthy : Checking health status for $APPLICATION" + if [[ -n "$MAX_CHECKS" ]]; then + echo "argo:check_argo_app_healthy : Checking health status for $APPLICATION up to $MAX_CHECKS times" + else + echo "argo:check_argo_app_healthy : Checking health status for $APPLICATION with no timeout" + fi HEALTH_STATUS=$(argocd app get $APPLICATION -o json 2> /dev/null | jq -r .status.health.status) if [ "$HEALTH_STATUS" == "Healthy" ]; then echo "Health Status is Healthy" @@ -773,10 +849,10 @@ function check_argo_app_healthy() { ((COUNT++)) echo "argo:check_argo_app_healthy : Health Status is $HEALTH_STATUS, Waiting 30s before checking status again - $COUNT" sleep 30 - if ! (( $COUNT % 5 )) ; then - if [[ -n "$CLUSTER_WATCHER" ]]; then - # sync watcher as sometimes current application health status not reflected rightly (like returned empty status) - argocd_sync $CLUSTER_WATCHER + if [[ -n "$MAX_CHECKS" ]]; then + if [[ $COUNT -eq $MAX_CHECKS ]]; then + echo "argo:check_argo_app_healthy : App not healthy after $MAX_CHECKS checks, exiting" + exit 1 fi fi fi diff --git a/image/cli/mascli/functions/internal/install_config_storage_classes b/image/cli/mascli/functions/internal/install_config_storage_classes index dd8ca79c3d..3ad586ca0b 100644 --- a/image/cli/mascli/functions/internal/install_config_storage_classes +++ b/image/cli/mascli/functions/internal/install_config_storage_classes @@ -65,6 +65,18 @@ function install_config_storage_classes() { fi fi + if [[ "$STORAGE_CLASS_RWX" == "" ]]; then + oc get storageclass nfs-client &>> $LOGFILE + if [[ $? == "0" ]]; then + echo -e "${COLOR_GREEN}Storage provider auto-detected: NFS Client${TEXT_RESET}" + echo "${TEXT_DIM} - Storage class (ReadWriteOnce): nfs-client" + echo "${TEXT_DIM} - Storage class (ReadWriteMany): nfs-client" + STORAGE_CLASS_PROVIDER=ocs + STORAGE_CLASS_RWO=nfs-client + STORAGE_CLASS_RWX=nfs-client + fi + fi + # 3. Azure if [[ "$STORAGE_CLASS_RWX" == "" ]]; then oc get storageclass managed-premium &>> $LOGFILE diff --git a/image/cli/mascli/functions/internal/save_config b/image/cli/mascli/functions/internal/save_config index 95aba04a8f..9a728ca370 100644 --- a/image/cli/mascli/functions/internal/save_config +++ b/image/cli/mascli/functions/internal/save_config @@ -111,9 +111,6 @@ export REGISTRY_PRIVATE_HOST="$REGISTRY_PRIVATE_HOST" export REGISTRY_PRIVATE_PORT="$REGISTRY_PRIVATE_PORT" export REGISTRY_PRIVATE_CA_FILE="$REGISTRY_PRIVATE_CA_FILE" -export REDHAT_CONNECT_USERNAME="$REDHAT_CONNECT_USERNAME" -export REDHAT_CONNECT_PASSWORD="$REDHAT_CONNECT_PASSWORD" - export MIRROR_MODE_SELECTION="$MIRROR_MODE_SELECTION" export OCP_RELEASE_SELECTION="$OCP_RELEASE_SELECTION" export MIRROR_REDHAT_PLATFORM="$MIRROR_REDHAT_PLATFORM" diff --git a/image/cli/mascli/functions/mirror_images b/image/cli/mascli/functions/mirror_images index c0f14de2f4..7cfa297efe 100644 --- a/image/cli/mascli/functions/mirror_images +++ b/image/cli/mascli/functions/mirror_images @@ -24,8 +24,6 @@ Registry Prefix (Optional): Source Registry Entitlements (Required based on what content you choose to mirror): --ibm-entitlement ${COLOR_YELLOW}IBM_ENTITLEMENT_KEY${TEXT_RESET} IBM Entitlement Key - --redhat-username ${COLOR_YELLOW}REDHAT_CONNECT_USERNAME${TEXT_RESET} Red Hat Connect Username (only required when mirroring UDS images) - --redhat-password ${COLOR_YELLOW}REDHAT_CONNECT_PASSWORD${TEXT_RESET} Red Hat Connect Password (only required when mirroring UDS images) --artifactory-username ${COLOR_YELLOW}ARTIFACTORY_USERNAME${TEXT_RESET} Artifactory Username --artifactory-token ${COLOR_YELLOW}ARTIFACTORY_TOKEN${TEXT_RESET} Artifactory Token @@ -39,7 +37,6 @@ Content Selection (Core Platform): Content Selection (Applications): --mirror-assist Mirror images for IBM Maximo Assist - --mirror-hputilities Mirror images for IBM Maximo Health & Predict Utilities --mirror-iot Mirror images for IBM Maximo IoT --mirror-manage Mirror images for IBM Maximo Manage --mirror-icd Mirror image for IBM Maximo IT (Separately entitled IBM Maximo Manage extension) @@ -63,8 +60,10 @@ Content Selection (Other Dependencies): --mirror-mongo Mirror images for MongoDb Community Edition --mirror-mongo-v5 Mirror images for MongoDb Community Edition version 5 --mirror-mongo-v6 Mirror images for MongoDb Community Edition version 6 + --mirror-mongo-v7 Mirror images for MongoDb Community Edition version 7 --mirror-db2 Mirror images for IBM Db2 --mirror-appconnect Mirror images for IBM AppConnect + --mirror-odf Mirror images for ODF Content Selection (All images included): --mirror-everything Mirror all MAS related images (including dependencies) @@ -94,16 +93,17 @@ function mirror_everything() { # Dependencies (Other) MIRROR_CATALOG=true MIRROR_COMMONSERVICES=true - MIRROR_UDS=true MIRROR_SLS=true MIRROR_TRUSTSTOREMGR=true MIRROR_MONGOCE=true MIRROR_MONGOCE_V4=true MIRROR_MONGOCE_V5=true MIRROR_MONGOCE_V6=true + MIRROR_MONGOCE_V7=true MIRROR_DB2U=true MIRROR_APPCONNECT=true + MIRROR_ODF=true # Dependencies (CP4D) MIRROR_CP4D=true @@ -117,7 +117,6 @@ function mirror_to_registry_noninteractive() { # Main content MIRROR_MAS_CORE=false MIRROR_MAS_ASSIST=false - MIRROR_MAS_HPUTILITIES=false MIRROR_MAS_IOT=false MIRROR_MAS_MANAGE=false MIRROR_MAS_ICD=false @@ -129,13 +128,13 @@ function mirror_to_registry_noninteractive() { # Dependencies MIRROR_CATALOG=false MIRROR_COMMONSERVICES=false - MIRROR_UDS=false MIRROR_SLS=false MIRROR_TRUSTSTOREMGR=false MIRROR_MONGOCE=false MIRROR_MONGOCE_V4=false MIRROR_MONGOCE_V5=false MIRROR_MONGOCE_V6=false + MIRROR_MONGOCE_V7=false MIRROR_DB2U=false MIRROR_CP4D=false MIRROR_WSL=false @@ -143,6 +142,7 @@ function mirror_to_registry_noninteractive() { MIRROR_SPARK=false MIRROR_COGNOS=false MIRROR_APPCONNECT=false + MIRROR_ODF=false while [[ $# -gt 0 ]] do @@ -165,7 +165,7 @@ function mirror_to_registry_noninteractive() { REGISTRY_PUBLIC_PORT=$1 && shift ;; -x| --prefix) - REGISTRY_PREFIX=$1 && shift + REGISTRY_PREFIX=$1 && shift ;; -u|--username) REGISTRY_USERNAME=$1 && shift @@ -178,12 +178,6 @@ function mirror_to_registry_noninteractive() { --ibm-entitlement) IBM_ENTITLEMENT_KEY=$1 && shift ;; - --redhat-username) - REDHAT_CONNECT_USERNAME=$1 && shift - ;; - --redhat-password) - REDHAT_CONNECT_PASSWORD=$1 && shift - ;; --artifactory-username) ARTIFACTORY_USERNAME=$1 && shift ;; @@ -211,9 +205,6 @@ function mirror_to_registry_noninteractive() { --mirror-assist) MIRROR_MAS_ASSIST=true ;; - --mirror-hputilities) - MIRROR_MAS_HPUTILITIES=true - ;; --mirror-iot) MIRROR_MAS_IOT=true ;; @@ -221,6 +212,8 @@ function mirror_to_registry_noninteractive() { MIRROR_MAS_MANAGE=true ;; --mirror-icd) + # Handle case where user selects to mirror ICD without selecting to mirror manage explicitly + MIRROR_MAS_MANAGE=true MIRROR_MAS_ICD=true ;; --mirror-monitor) @@ -240,9 +233,6 @@ function mirror_to_registry_noninteractive() { --mirror-cfs) MIRROR_COMMONSERVICES=true ;; - --mirror-uds) - MIRROR_UDS=true - ;; --mirror-sls) MIRROR_SLS=true ;; @@ -261,12 +251,18 @@ function mirror_to_registry_noninteractive() { --mirror-mongo-v6) MIRROR_MONGOCE_V6=true ;; + --mirror-mongo-v7) + MIRROR_MONGOCE_V7=true + ;; --mirror-db2) MIRROR_DB2U=true ;; --mirror-appconnect) MIRROR_APPCONNECT=true ;; + --mirror-odf) + MIRROR_ODF=true + ;; # Content Selection (Cloud Pak for Data) --mirror-cp4d) @@ -319,11 +315,6 @@ function mirror_to_registry_noninteractive() { [[ -z "$REGISTRY_PASSWORD" ]] && mirror_to_registry_help "REGISTRY_PASSWORD is not set" fi - if [[ $MIRROR_UDS == "true" ]]; then - [[ -z "$REDHAT_CONNECT_USERNAME" ]] && mirror_to_registry_help "REDHAT_CONNECT_USERNAME is not set" - [[ -z "$REDHAT_CONNECT_PASSWORD" ]] && mirror_to_registry_help "REDHAT_CONNECT_PASSWORD is not set" - fi - if [[ "$MIRROR_EVERYTHING" == "true" ]]; then mirror_everything fi @@ -398,7 +389,6 @@ function mirror_to_registry_interactive() { prompt_for_confirm "IBM Maximo Application Suite - Visual Inspection" MIRROR_MAS_VISUALINSPECTION prompt_for_confirm_default_yes "IBM Foundational Services" MIRROR_COMMONSERVICES - prompt_for_confirm_default_yes "IBM User Data Services" MIRROR_UDS prompt_for_confirm_default_yes "IBM Suite License Service" MIRROR_SLS prompt_for_confirm_default_yes "IBM Truststore Manager" MIRROR_TRUSTSTOREMGR if prompt_for_confirm_default_yes "MongoDb Community Edition"; then @@ -444,8 +434,9 @@ function mirror_to_registry_interactive() { prompt_for_confirm "IBM Watson Machine Learning" MIRROR_WML prompt_for_confirm "IBM Analytics Engine (Spark)" MIRROR_SPARK prompt_for_confirm "IBM Cognos Analytics" MIRROR_COGNOS - + prompt_for_confirm "IBM AppConnect" MIRROR_APPCONNECT + prompt_for_confirm "RedHat ODF" MIRROR_ODF fi if [[ "$MIRROR_MAS_ICD" == "true" ]]; then @@ -461,10 +452,6 @@ function mirror_to_registry_interactive() { echo_h2 "Configure Authentication" prompt_for_secret "IBM Entitlement Key" IBM_ENTITLEMENT_KEY "Re-use saved IBM Entitlement Key?" - if [[ $MIRROR_UDS == "true" ]]; then - prompt_for_input "Red Hat Connect Username" REDHAT_CONNECT_USERNAME - prompt_for_secret "Red Hat Connect Password" REDHAT_CONNECT_PASSWORD "Re-use saved password?" - fi } @@ -482,7 +469,7 @@ function mirror_one_thing() { echo -en "\033[u" # Restore cursor position if [[ $mirror_result == "0" ]]; then echo -e "${COLOR_GREEN}[SUCCESS] ${MOT_NAME}: ${MOT_LOGFILE}${TEXT_RESET}" - else + else echo -e "${COLOR_RED}[FAILURE] ${MOT_NAME}: ${MOT_LOGFILE}${TEXT_RESET}" echo cat "$MOT_LOGFILE" @@ -526,13 +513,13 @@ function mirror_to_registry() { # Dependency control export MIRROR_CATALOG export MIRROR_COMMONSERVICES - export MIRROR_UDS export MIRROR_SLS export MIRROR_TRUSTSTOREMGR export MIRROR_MONGOCE export MIRROR_MONGOCE_V4 export MIRROR_MONGOCE_V5 export MIRROR_MONGOCE_V6 + export MIRROR_MONGOCE_V7 export MIRROR_DB2U export MIRROR_CP4D export MIRROR_WML @@ -540,27 +527,27 @@ function mirror_to_registry() { export MIRROR_SPARK export MIRROR_COGNOS export MIRROR_APPCONNECT + export MIRROR_ODF export MIRROR_MAS_ICD export MIRROR_EVERYTHING # Authentication export IBM_ENTITLEMENT_KEY - export REDHAT_CONNECT_USERNAME - export REDHAT_CONNECT_PASSWORD export ARTIFACTORY_USERNAME export ARTIFACTORY_TOKEN if [[ "$MIRROR_CATALOG" == true || "$MIRROR_COMMONSERVICES" == true || - "$MIRROR_UDS" == true || "$MIRROR_SLS" == true || "$MIRROR_TRUSTSTOREMGR" == true || "$MIRROR_MONGOCE" == true || "$MIRROR_MONGOCE_V4" == true || "$MIRROR_MONGOCE_V5" == true || "$MIRROR_MONGOCE_V6" == true || + "$MIRROR_MONGOCE_V7" == true || "$MIRROR_DB2U" == true || "$MIRROR_APPCONNECT" == true || + "$MIRROR_ODF" == true || "$MIRROR_CP4D" == true || "$MIRROR_WSL" == true || "$MIRROR_WML" == true || @@ -628,15 +615,16 @@ function mirror_to_registry() { reset_colors echo_h4 "Content Selection (Other Dependencies)" " " show_mirror_status "IBM Cloud Pak Foundation Services ..." $MIRROR_COMMONSERVICES - show_mirror_status "IBM User Data Services .............." $MIRROR_UDS show_mirror_status "IBM Suite License Service ..........." $MIRROR_SLS show_mirror_status "IBM Truststore Manager .............." $MIRROR_TRUSTSTOREMGR show_mirror_status "MongoDb Community Edition ..........." $MIRROR_MONGOCE show_mirror_status "+ Version 4 ........................." $MIRROR_MONGOCE_V4 show_mirror_status "+ Version 5 ........................." $MIRROR_MONGOCE_V5 show_mirror_status "+ Version 6 ........................." $MIRROR_MONGOCE_V6 + show_mirror_status "+ Version 7 ........................." $MIRROR_MONGOCE_V7 show_mirror_status "IBM Db2 ............................." $MIRROR_DB2U show_mirror_status "IBM AppConnect ......................" $MIRROR_APPCONNECT + show_mirror_status "RedHat ODF .........................." $MIRROR_ODF echo reset_colors @@ -657,7 +645,6 @@ function mirror_to_registry() { mirror_one_thing $MIRROR_MAS_CORE "IBM Maximo Application Suite Core" "$LOG_PREFIX-core.log" mirror_core mirror_one_thing $MIRROR_MAS_ASSIST "IBM Maximo Assist" "$LOG_PREFIX-assist.log" mirror_add_assist - mirror_one_thing $MIRROR_MAS_HPUTILITIES "IBM Maximo Health & Predict Utilities" "$LOG_PREFIX-hputilities.log" mirror_add_hputilities mirror_one_thing $MIRROR_MAS_IOT "IBM Maximo IoT" "$LOG_PREFIX-iot.log" mirror_add_iot mirror_one_thing $MIRROR_MAS_MANAGE "IBM Maximo Manage" "$LOG_PREFIX-manage.log" mirror_add_manage mirror_one_thing $MIRROR_MAS_MONITOR "IBM Maximo Monitor" "$LOG_PREFIX-monitor.log" mirror_add_monitor @@ -665,4 +652,4 @@ function mirror_to_registry() { mirror_one_thing $MIRROR_MAS_OPTIMIZER "IBM Maximo Optimizer" "$LOG_PREFIX-optimizer.log" mirror_add_optimizer mirror_one_thing $MIRROR_MAS_VISUALINSPECTION "IBM Maximo Visual Inspection" "$LOG_PREFIX-visualinspection.log" mirror_add_visualinspection mirror_one_thing $MIRROR_DEPS "Selected Dependencies" "$LOG_PREFIX-dependencies.log" mirror_dependencies -} \ No newline at end of file +} diff --git a/image/cli/mascli/functions/must_gather b/image/cli/mascli/functions/must_gather index a4d64ba86b..d03dddcc3b 100644 --- a/image/cli/mascli/functions/must_gather +++ b/image/cli/mascli/functions/must_gather @@ -198,7 +198,7 @@ function mustgather() { echo_h3 "Cluster Resources" startTimer - for RESOURCE in nodes storageclasses clusterversions + for RESOURCE in nodes storageclasses clusterversions imagecontentsourcepolicy do $MG_SCRIPT_DIR/mg-collect-resources -r $RESOURCE -d $OUTPUT_DIR/resources done @@ -245,22 +245,21 @@ function mustgather() { fi echo_h3 "IBM Db2 Universal Operator" - NAMESPACE_LOOKUP=$(oc get namespace db2u --ignore-not-found) - if [[ "$NAMESPACE_LOOKUP" != "" ]]; then + DB2U_NAMESPACES=$(oc get db2ucluster -A --ignore-not-found -o jsonpath='{.items[*].metadata.namespace}' | tr " " "\n" |sort | uniq) + for DB2U_NAMESPACE in $DB2U_NAMESPACES + do $MG_SCRIPT_DIR/mg-summary-db2u &> ${OUTPUT_DIR}/db2u.txt - genericMustGather db2u - else - echo_highlight "Unable to find db2u namespace" - fi + genericMustGather $DB2U_NAMESPACE + done echo_h3 "IBM Data Reporter Operator" - NAMESPACE_LOOKUP=$(oc get namespace redhat-marketplace --ignore-not-found) - if [[ "$NAMESPACE_LOOKUP" != "" ]]; then + DRO_NAMESPACE_LOOKUP=$(oc get DataReporterConfig -A --ignore-not-found -o jsonpath='{.items[*].metadata.namespace}') + if [[ "$DRO_NAMESPACE_LOOKUP" != "" ]]; then $MG_SCRIPT_DIR/mg-summary-dro &> ${OUTPUT_DIR}/dro.txt - genericMustGather redhat-marketplace DataReporterConfig,MarketplaceConfig,MeterReport,MeterBase,RazeeDeployment,MeterDefinition + genericMustGather $DRO_NAMESPACE_LOOKUP DataReporterConfig,MarketplaceConfig,MeterReport,MeterBase,RazeeDeployment,MeterDefinition else - echo_highlight "Unable to find redhat-marketplace namespace" - fi + echo_highlight "Unable to find namespace for DRO" + fi echo_h3 "Red Hat Certificate Manager" NAMESPACE_LOOKUP=$(oc get namespace cert-manager-operator --ignore-not-found) @@ -278,6 +277,21 @@ function mustgather() { echo_highlight "Unable to find cert-manager namespace" fi + echo_h3 "Kafka" + KAFKA_NAMESPACES=$(oc get Kafka -A --ignore-not-found -o jsonpath='{.items[*].metadata.namespace}') + for KAFKA_NAMESPACE in $KAFKA_NAMESPACES + do + $MG_SCRIPT_DIR/mg-summary-kafka &> ${OUTPUT_DIR}/kafka.txt + genericMustGather $KAFKA_NAMESPACE Kafka,KafkaUser + done + + echo_h3 "Grafana" + GRAFANA_NAMESPACES=$(oc get Grafana -A --ignore-not-found -o jsonpath='{.items[*].metadata.namespace}') + for GRAFANA_NAMESPACE in $GRAFANA_NAMESPACES + do + $MG_SCRIPT_DIR/mg-summary-kafka &> ${OUTPUT_DIR}/kafka.txt + genericMustGather $GRAFANA_NAMESPACE Grafana,GrafanaDatasource + done MONGOCE_NAMESPACES=$(oc get mongodbcommunity --all-namespaces --ignore-not-found -o jsonpath='{.items[*].metadata.namespace}') for MONGOCE_NAMESPACE in $MONGOCE_NAMESPACES diff --git a/image/cli/mascli/must-gather/mg-collect-mas-manage b/image/cli/mascli/must-gather/mg-collect-mas-manage index fa3ad2ea65..2ecdf17bd8 100644 --- a/image/cli/mascli/must-gather/mg-collect-mas-manage +++ b/image/cli/mascli/must-gather/mg-collect-mas-manage @@ -6,6 +6,14 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" NAMESPACE=$1 OUTPUT_DIR=$2 +# Collect build Resources +# ----------------------------------------------------------------------------- +echo_h4 "Collect Build Resources" +for RESOURCE in build buildconfig imagestream imagestreamtag +do + $DIR/mg-collect-resources -n $NAMESPACE -r $RESOURCE -d $OUTPUT_DIR/resources +done + # Collect Manage Logs # ----------------------------------------------------------------------------- echo_h4 "Collect Manage Files" diff --git a/image/cli/mascli/templates/gitops/appset-configs/cluster/instance/masapp/ibm-mas-masapp-config.yaml.j2 b/image/cli/mascli/templates/gitops/appset-configs/cluster/instance/masapp/ibm-mas-masapp-config.yaml.j2 index f95540b1c9..c0ec360969 100644 --- a/image/cli/mascli/templates/gitops/appset-configs/cluster/instance/masapp/ibm-mas-masapp-config.yaml.j2 +++ b/image/cli/mascli/templates/gitops/appset-configs/cluster/instance/masapp/ibm-mas-masapp-config.yaml.j2 @@ -35,6 +35,12 @@ mas_manual_cert_mgmt: true mas_manual_cert_mgmt: false {% endif %} +{% if RUN_SANITY_TEST == 'true' %} +run_sanity_test: true +{% else %} +run_sanity_test: false +{% endif %} + {% if INGRESS == 'true' %} ingress: true {% else %} diff --git a/image/cli/mascli/templates/gitops/appset-configs/cluster/phase1/ibm-mas-cluster-base.yaml.j2 b/image/cli/mascli/templates/gitops/appset-configs/cluster/phase1/ibm-mas-cluster-base.yaml.j2 index ced34f101d..f38d23c48e 100644 --- a/image/cli/mascli/templates/gitops/appset-configs/cluster/phase1/ibm-mas-cluster-base.yaml.j2 +++ b/image/cli/mascli/templates/gitops/appset-configs/cluster/phase1/ibm-mas-cluster-base.yaml.j2 @@ -21,3 +21,9 @@ notifications: custom_labels: {{ CUSTOM_LABELS | indent(2) }} {% endif %} + +{% if DEVOPS_MONGO_URI is defined and DEVOPS_MONGO_URI !='' %} +devops: + mongo_uri: "" + build_number: {{ DEVOPS_BUILD_NUMBER }} +{% endif %} diff --git a/image/cli/mascli/templates/gitops/bootstrap/argocd.yaml b/image/cli/mascli/templates/gitops/bootstrap/argocd.yaml index 4550e45d26..8337104e7a 100644 --- a/image/cli/mascli/templates/gitops/bootstrap/argocd.yaml +++ b/image/cli/mascli/templates/gitops/bootstrap/argocd.yaml @@ -940,8 +940,10 @@ spec: end hs.status = "Progressing" hs.message = "Unknown" - if obj.status.state ~= nil then - hs.message = obj.status.state + if obj.status ~= nil then + if obj.status.state ~= nil then + hs.message = obj.status.state + end end return hs diff --git a/image/cli/mascli/templates/gitops/bootstrap/configmap.yaml b/image/cli/mascli/templates/gitops/bootstrap/configmap.yaml index 5063799856..3b4f369660 100644 --- a/image/cli/mascli/templates/gitops/bootstrap/configmap.yaml +++ b/image/cli/mascli/templates/gitops/bootstrap/configmap.yaml @@ -18,6 +18,11 @@ data: - sh - "-c" - "find . -name 'Chart.yaml' && find . -name 'values.yaml'" + init: + command: + - sh + - "-c" + - helm dependency update; generate: command: - bash diff --git a/image/cli/masfvt/finally.yml b/image/cli/masfvt/finally.yml index feff745be3..ea6326f49b 100644 --- a/image/cli/masfvt/finally.yml +++ b/image/cli/masfvt/finally.yml @@ -9,7 +9,7 @@ # Pipeline Run Info devops_build_number: "{{ lookup('env', 'DEVOPS_BUILD_NUMBER') | default('0', True) }}" - pipelinerun_name: "{{ lookup('env', 'PIPELINERUN_NAME') | default('mas-fvt-finally', True) }}-{{ devops_build_number }}" + pipelinerun_name: "{{ lookup('env', 'PIPELINERUN_NAME') | default('mas-fvt-finally-' ~ devops_build_number, True) }}" mas_instance_id: "{{ lookup('env', 'MAS_INSTANCE_ID') }}" pipelinerun_namespace: "{{ lookup('env', 'PIPELINERUN_NAMESPACE') | default('mas-' ~ mas_instance_id ~ '-pipelines', True) }}" tasks: diff --git a/mkdocs.yml b/mkdocs.yml index 8dffedf295..fbf61315f1 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -16,30 +16,34 @@ nav: - "Update": guides/update.md - "Upgrade": guides/upgrade.md - "Uninstall": guides/uninstall.md - - "OpenShift Management": - - "provision-fyre": commands/provision-fyre.md - - "provision-roks": commands/provision-roks.md - - "provision-rosa": commands/provision-rosa.md - - "configure-airgap": commands/configure-airgap.md - - "Image Mirroring": - - "setup-registry": commands/setup-registry.md - - "teardown-registry": commands/teardown-registry.md - - "mirror-images": commands/mirror-images.md - - "mirror-redhat-images": commands/mirror-redhat-images.md - - "MAS Management": - - "configtool-oidc": commands/configtool-oidc.md + - "Examples": + - "EAM Migration": examples/eam-migration.md + - "Mirror Db2 Images": examples/mirror-db2.md + - "Command Reference": - "install": commands/install.md - "update": commands/update.md - "upgrade": commands/upgrade.md - "uninstall": commands/uninstall.md - - "Troubleshooting": - "must-gather": commands/must-gather.md - - "Catalogs": + + - "configure-airgap": commands/configure-airgap.md + - "mirror-images": commands/mirror-images.md + - "mirror-redhat-images": commands/mirror-redhat-images.md + + - "setup-registry": commands/setup-registry.md + - "teardown-registry": commands/teardown-registry.md + + - "provision-fyre": commands/provision-fyre.md + - "provision-roks": commands/provision-roks.md + - "provision-rosa": commands/provision-rosa.md + + - "configtool-oidc": commands/configtool-oidc.md + - "Operator Catalogs": - "All Catalogs": catalogs/index.md + - "Oct 03 2024": catalogs/v9-241003-amd64.md - "Aug 27 2024": catalogs/v9-240827-amd64.md - "Jul 30 2024": catalogs/v9-240730-amd64.md - "Jun 25 2024": catalogs/v9-240625-amd64.md - - "May 28 2024": catalogs/v8-240528-amd64.md - "Reference": - "Dependencies": reference/dependencies.md - "Topology": reference/topology.md diff --git a/python/src/mas/cli/install/app.py b/python/src/mas/cli/install/app.py index 04954e66b5..ae1c23275d 100644 --- a/python/src/mas/cli/install/app.py +++ b/python/src/mas/cli/install/app.py @@ -185,8 +185,12 @@ def configMongoDb(self) -> None: self.printH1("Configure MongoDb") self.promptForString("Install namespace", "mongodb_namespace", default="mongoce") + def configSpecialCharacters(self): + self.printH1("Configure special characters for userID and username") + self.yesOrNo("Do you want to allow special characters for user IDs and usernames?", "mas_special_characters") + def configCP4D(self): - if self.getParam("mas_catalog_version") in ["v9-240625-amd64", "v9-240730-amd64", "v9-240827-amd64"]: + if self.getParam("mas_catalog_version") in ["v9-240625-amd64", "v9-240730-amd64", "v9-240827-amd64", "v9-241003-amd64"]: logger.debug(f"Using automatic CP4D product version: {self.getParam('cpd_product_version')}") self.setParam("cpd_product_version", "4.8.0") elif self.getParam("cpd_product_version") == "": @@ -261,6 +265,7 @@ def configMAS(self): self.configCATrust() self.configDNSAndCerts() self.configSSOProperties() + self.configSpecialCharacters() self.configGuidedTour() def configCATrust(self) -> None: @@ -483,7 +488,15 @@ def configStorageClasses(self): self.storageClassProvider = "ocs" self.params["storage_class_rwo"] = "ocs-storagecluster-ceph-rbd" self.params["storage_class_rwx"] = "ocs-storagecluster-cephfs" - # 3. Azure + # 3. NFS Client + elif getStorageClass(self.dynamicClient, "nfs-client") is not None: + print_formatted_text(HTML("Storage provider auto-detected: NFS Client")) + print_formatted_text(HTML(" - Storage class (ReadWriteOnce): nfs-client")) + print_formatted_text(HTML(" - Storage class (ReadWriteMany): nfs-client")) + self.storageClassProvider = "nfs" + self.params["storage_class_rwo"] = "nfs-client" + self.params["storage_class_rwx"] = "nfs-client" + # 4. Azure elif getStorageClass(self.dynamicClient, "managed-premium") is not None: print_formatted_text(HTML("Storage provider auto-detected: Azure Managed")) print_formatted_text(HTML(" - Storage class (ReadWriteOnce): managed-premium")) @@ -491,7 +504,7 @@ def configStorageClasses(self): self.storageClassProvider = "azure" self.params["storage_class_rwo"] = "managed-premium" self.params["storage_class_rwx"] = "azurefiles-premium" - # 4. AWS + # 5. AWS elif getStorageClass(self.dynamicClient, "gp2") is not None: print_formatted_text(HTML("Storage provider auto-detected: AWS gp2")) print_formatted_text(HTML(" - Storage class (ReadWriteOnce): gp2")) @@ -947,6 +960,45 @@ def install(self, argv): self.installOptions = [ { "#": 1, + "catalog": "v9-241003-amd64", + "release": "9.0.x", + "core": "9.0.3", + "assist": "9.0.2", + "iot": "9.0.3", + "manage": "9.0.3", + "monitor": "9.0.3", + "optimizer": "9.0.3", + "predict": "9.0.2", + "inspection": "9.0.3" + }, + { + "#": 2, + "catalog": "v9-241003-amd64", + "release": "8.11.x", + "core": "8.11.15", + "assist": "8.8.6", + "iot": "8.8.13", + "manage": "8.7.12", + "monitor": "8.11.11", + "optimizer": "8.5.9", + "predict": "8.9.5", + "inspection": "8.9.6" + }, + { + "#": 3, + "catalog": "v9-241003-amd64", + "release": "8.10.x", + "core": "8.10.18", + "assist": "8.7.7", + "iot": "8.7.17", + "manage": "8.6.18", + "monitor": "8.10.14", + "optimizer": "8.4.10", + "predict": "8.8.3", + "inspection": "8.8.4" + }, + { + "#": 4, "catalog": "v9-240827-amd64", "release": "9.0.x", "core": "9.0.2", @@ -960,7 +1012,7 @@ def install(self, argv): "aibroker": "9.0.1" }, { - "#": 2, + "#": 5, "catalog": "v9-240827-amd64", "release": "8.11.x", "core": "8.11.14", @@ -974,7 +1026,7 @@ def install(self, argv): "aibroker": "9.0.1" }, { - "#": 3, + "#": 6, "catalog": "v9-240827-amd64", "release": "8.10.x", "core": "8.10.17", @@ -988,7 +1040,7 @@ def install(self, argv): "aibroker": "9.0.1" }, { - "#": 4, + "#": 7, "catalog": "v9-240730-amd64", "release": "9.0.x", "core": "9.0.1", @@ -1002,7 +1054,7 @@ def install(self, argv): "aibroker": "9.0.1" }, { - "#": 5, + "#": 8, "catalog": "v9-240730-amd64", "release": "8.11.x", "core": "8.11.13", @@ -1015,7 +1067,7 @@ def install(self, argv): "inspection": "8.9.4" }, { - "#": 6, + "#": 9, "catalog": "v9-240730-amd64", "release": "8.10.x", "core": "8.10.16", @@ -1026,45 +1078,6 @@ def install(self, argv): "optimizer": "8.4.8", "predict": "8.8.3", "inspection": "8.8.4" - }, - { - "#": 7, - "catalog": "v9-240625-amd64", - "release": "9.0.x", - "core": "9.0.0", - "assist": "9.0.0", - "iot": "9.0.0", - "manage": "9.0.0", - "monitor": "9.0.0", - "optimizer": "9.0.0", - "predict": "9.0.0", - "inspection": "9.0.0" - }, - { - "#": 8, - "catalog": "v9-240625-amd64", - "release": "8.11.x", - "core": "8.11.12", - "assist": "N/A", - "iot": "8.8.10", - "manage": "8.7.9", - "monitor": "8.11.8", - "optimizer": "8.5.6", - "predict": "8.9.3", - "inspection": "8.9.3" - }, - { - "#": 9, - "catalog": "v9-240625-amd64", - "release": "8.10.x", - "core": "8.10.15", - "assist": "N/A", - "iot": "8.7.14", - "manage": "8.6.15", - "monitor": "8.10.11", - "optimizer": "8.4.7", - "predict": "N/A", - "inspection": "8.8.4" } ] diff --git a/python/src/mas/cli/install/argBuilder.py b/python/src/mas/cli/install/argBuilder.py index 53432d8089..be2d2b88bb 100644 --- a/python/src/mas/cli/install/argBuilder.py +++ b/python/src/mas/cli/install/argBuilder.py @@ -60,6 +60,9 @@ def buildCommand(self) -> str: command += f" --mas-workspace-id {self.getParam('mas_workspace_id')}" command += f" --mas-workspace-name \"{self.getParam('mas_workspace_name')}\"{newline}" + if self.getParam('mas_special_characters') == "true": + command += f" --allow-special-chars \"{self.getParam('mas_special_characters')}\"{newline}" + # ECK Integration # ----------------------------------------------------------------------------- if self.getParam('eck_action') == "install": diff --git a/python/src/mas/cli/install/argParser.py b/python/src/mas/cli/install/argParser.py index fc66d27766..bf7989ad58 100644 --- a/python/src/mas/cli/install/argParser.py +++ b/python/src/mas/cli/install/argParser.py @@ -75,7 +75,16 @@ def isValidFile(parser, arg) -> str: required=False, help="Subscription channel for the Core Platform" ) - +# MAS Special characters +# ----------------------------------------------------------------------------- +masSpecialCharacters = installArgParser.add_argument_group("Mas Special Characters") +masSpecialCharacters.add_argument( + "--allow-special-chars", + dest="mas_special_characters", + required=False, + help="Allow special chars for users username/ID", + action="store_true" +) # ECK Integration # ----------------------------------------------------------------------------- eckArgGroup = installArgParser.add_argument_group("ECK Integration") diff --git a/python/src/mas/cli/update/app.py b/python/src/mas/cli/update/app.py index e4d1504f48..ad290687ac 100644 --- a/python/src/mas/cli/update/app.py +++ b/python/src/mas/cli/update/app.py @@ -37,6 +37,7 @@ def update(self, argv): """ self.args = updateArgParser.parse_args(args=argv) self.noConfirm = self.args.no_confirm + self.devMode = self.args.dev_mode if self.args.mas_catalog_version: # Non-interactive mode @@ -47,11 +48,19 @@ def update(self, argv): "mongodb_namespace", "mongodb_v5_upgrade", "mongodb_v6_upgrade", + "mongodb_v7_upgrade", "kafka_namespace", "kafka_provider", "dro_migration", "dro_storage_class", - "dro_namespace" + "dro_namespace", + "skip_pre_check", + "dev_mode", + "cpd_product_version", + # Dev Mode + "artifactory_username", + "artifactory_token" + ] for key, value in vars(self.args).items(): # These fields we just pass straight through to the parameters and fail if they are not set @@ -66,7 +75,7 @@ def update(self, argv): self.setParam(key, value) # Arguments that we don't need to do anything with - elif key in ["skip_pre_check", "no_confirm", "help"]: + elif key in [ "no_confirm", "help"]: pass # Fail if there's any arguments we don't know how to handle @@ -90,7 +99,8 @@ def update(self, argv): self.chooseCatalog() # Validations - self.validateCatalog() + if not self.devMode: + self.validateCatalog() self.printH1("Dependency Update Checks") with Halo(text='Checking for IBM Watson Discovery', spinner=self.spinner) as h: @@ -165,7 +175,6 @@ def update(self, argv): "Please carefully review your choices above, correcting mistakes now is much easier than after the update has begun" ]) continueWithUpdate = self.yesOrNo("Proceed with these settings") - # Prepare the namespace and launch the installation pipeline if self.noConfirm or continueWithUpdate: self.createTektonFileWithDigest() @@ -235,13 +244,13 @@ def chooseCatalog(self) -> None: self.printH1("Select IBM Maximo Operator Catalog Version") self.printDescription([ "Select MAS Catalog", - " 1) Aug 27 2024 Update (MAS 9.0.2, 8.11.14, & 8.10.17)", - " 2) July 30 2024 Update (MAS 9.0.1, 8.11.13, & 8.10.16)", - " 3) June 25 2024 Update (MAS 9.0.0, 8.11.12, & 8.10.15)" + " 1) Oct 03 2024 Update (MAS 9.0.3, 8.11.15, & 8.10.18)", + " 2) Aug 27 2024 Update (MAS 9.0.2, 8.11.14, & 8.10.17)", + " 3) July 30 2024 Update (MAS 9.0.1, 8.11.13, & 8.10.16)" ]) catalogOptions = [ - "v9-240827-amd64", "v9-240730-amd64", "v9-240625-amd64" + "v9-241003-amd64", "v9-240827-amd64", "v9-240730-amd64" ] self.promptForListSelect("Select catalog version", catalogOptions, "mas_catalog_version", default=1) @@ -332,13 +341,19 @@ def detectMongoDb(self) -> None: # the case bundles in there anymore # Longer term we will centralise this information inside the mas-devops python collection, # where it can be made available to both the ansible collection and this python package. + defaultMongoVersion = "6.0.12" mongoVersions = { "v9-240625-amd64": "6.0.12", "v9-240730-amd64": "6.0.12", - "v9-240827-amd64": "6.0.12" + "v9-240827-amd64": "6.0.12", + "v9-241003-amd64": "6.0.12" } + catalogVersion = self.getParam('mas_catalog_version') + if catalogVersion in mongoVersions: + targetMongoVersion = mongoVersions[self.getParam('mas_catalog_version')] + else: + targetMongoVersion = defaultMongoVersion - targetMongoVersion = mongoVersions[self.getParam('mas_catalog_version')] self.setParam("mongodb_version", targetMongoVersion) targetMongoVersionMajor = targetMongoVersion.split(".")[0] @@ -424,16 +439,20 @@ def detectUDS(self) -> None: else: h.stop_and_persist(symbol=self.successIcon, text="IBM User Data Services needs to be migrated to IBM Data Reporter Operator") self.showUDSUpdateNotice() - if not self.yesOrNo("Confirm migration from UDS to DRO", "dro_migration"): - # If the user did not approve the update, abort - exit(1) - self.printDescription([ - "", - "Select the storage class for DRO to use from the list below:" - ]) - for storageClass in getStorageClasses(self.dynamicClient): - print_formatted_text(HTML(f" - {storageClass.metadata.name}")) - self.promptForString("DRO storage class", "dro_storage_class", validator=StorageClassValidator()) + if self.getParam("dro_migration") == "true" and self.getParam("dro_storage_class") is None: + if not self.yesOrNo("Confirm migration from UDS to DRO", "dro_migration"): + # If the user did not approve the update, abort + exit(1) + self.printDescription([ + "", + "Select the storage class for DRO to use from the list below:" + ]) + for storageClass in getStorageClasses(self.dynamicClient): + print_formatted_text(HTML(f" - {storageClass.metadata.name}")) + self.promptForString("DRO storage class", "dro_storage_class", validator=StorageClassValidator()) + + if self.getParam("dro_migration") == "true": + self.setParam("uds_action", "install-dro") except (ResourceNotFoundError, NotFoundError) as e: # UDS has never been installed on this cluster @@ -449,7 +468,8 @@ def detectCP4D(self) -> bool: cp4dVersions = { "v9-240625-amd64": "4.8.0", "v9-240730-amd64": "4.8.0", - "v9-240827-amd64": "4.8.0" + "v9-240827-amd64": "4.8.0", + "v9-241003-amd64": "4.8.0" } @@ -471,7 +491,10 @@ def detectCP4D(self) -> bool: if len(cpds) > 0: cpdInstanceNamespace = cpds[0]["metadata"]["namespace"] cpdInstanceVersion = cpds[0]["spec"]["version"] - cpdTargetVersion = cp4dVersions[self.getParam("mas_catalog_version")] + if self.args.cpd_product_version: + cpdTargetVersion = self.getParam("cpd_product_version") + else: + cpdTargetVersion = cp4dVersions[self.getParam("mas_catalog_version")] currentCpdVersionMajorMinor = f"{cpdInstanceVersion.split('.')[0]}.{cpdInstanceVersion.split('.')[1]}" targetCpdVersionMajorMinor = f"{cpdTargetVersion.split('.')[0]}.{cpdTargetVersion.split('.')[1]}" @@ -487,7 +510,7 @@ def detectCP4D(self) -> bool: "Dependency Update Notice", f"Cloud Pak For Data is currently running version {cpdInstanceVersion} and will be updated to version {cpdTargetVersion}", "It is recommended that you backup your Cloud Pak for Data instance before proceeding:", - " https://www.ibm.com/docs/en/cloud-paks/cp-data/4.8.x?topic=administering-backing-up-restoring-cloud-pak-data" + " https://www.ibm.com/docs/en/cloud-paks/cp-data/5.0.x?topic=administering-backing-up-restoring-cloud-pak-data" ]) # Lookup the storage classes already used by CP4D diff --git a/python/src/mas/cli/update/argParser.py b/python/src/mas/cli/update/argParser.py index 17c1f5ede1..714bed2370 100644 --- a/python/src/mas/cli/update/argParser.py +++ b/python/src/mas/cli/update/argParser.py @@ -63,6 +63,14 @@ help="Required to confirm a major version update for MongoDb to version 6", ) +depsArgGroup.add_argument( + '--mongodb-v7-upgrade', + required=False, + action="store_const", + const="true", + help="Required to confirm a major version update for MongoDb to version 7", +) + depsArgGroup.add_argument( '--kafka-namespace', required=False, @@ -96,8 +104,36 @@ help="Set Custom Namespace for DRO(Default: redhat-marketplace)", ) +# Development Mode +# ----------------------------------------------------------------------------- +devArgGroup = updateArgParser.add_argument_group("Development Mode") +devArgGroup.add_argument( + "--artifactory-username", + required=False, + help="Username for access to development builds on Artifactory" +) +devArgGroup.add_argument( + "--artifactory-token", + required=False, + help="API Token for access to development builds on Artifactory" +) +# More Options +# ----------------------------------------------------------------------------- otherArgGroup = updateArgParser.add_argument_group('More') +otherArgGroup.add_argument( + "--dev-mode", + required=False, + action="store_true", + default=False, + help="Configure installation for development mode", +) +otherArgGroup.add_argument( + "--cp4d-version", + dest="cpd_product_version", + required=False, + help="Product version of CP4D to use" +) otherArgGroup.add_argument( '--no-confirm', required=False, diff --git a/tekton/src/params/install.yml.j2 b/tekton/src/params/install.yml.j2 index 2fd2b80f55..fe102ae170 100644 --- a/tekton/src/params/install.yml.j2 +++ b/tekton/src/params/install.yml.j2 @@ -233,7 +233,10 @@ - name: cpd_install_cognos type: string default: "" - +- name: cpd_install_all + type: string + default: "" + # Dependencies - UDS # ----------------------------------------------------------------------------- - name: uds_contact_email @@ -280,6 +283,10 @@ type: string description: COS action to be performed (provision or deprovision) default: "" +- name: cos_use_hmac + type: string + description: Optional boolean variable weather hmac is enabled or not + default: "" # MAS Integration - Grafana # ----------------------------------------------------------------------------- @@ -438,6 +445,11 @@ default: "True" description: Optional parameter to enable or disable guided tour +# Special characters configuration +- name: mas_special_characters + type: string + default: '' + # SSO Configuration # ----------------------------------------------------------------------------- - name: idle_timeout @@ -633,7 +645,7 @@ default: "" - name: mas_arcgis_channel type: string - description: Default channel for IBM Maximo Location Services for ESRI + description: Default channel for IBM Maximo Location Services for ESRI default: "" # default is handled by ansible-devops # MAS Application Configuration - Health Application diff --git a/tekton/src/pipelines/fvt-deprovision-after.yml.j2 b/tekton/src/pipelines/fvt-deprovision-after.yml.j2 index f1565af8d7..8173962a05 100644 --- a/tekton/src/pipelines/fvt-deprovision-after.yml.j2 +++ b/tekton/src/pipelines/fvt-deprovision-after.yml.j2 @@ -53,6 +53,9 @@ spec: - name: cos_action type: string default: "" + - name: cos_use_hmac + type: string + default: "" # IBM Event Streams - name: eventstreams_resourcegroup @@ -85,7 +88,7 @@ spec: value: $(params.pipelinerun_name) - name: delay value: 1200 # 20 minutes between checking the status of the pipelinerun - - name: retries + - name: max_retries value: 60 # attempts before giving up (approximately 20 hours) - name: ignore_failure value: $(params.ignore_failure) diff --git a/tekton/src/pipelines/fvt-launcher.yml.j2 b/tekton/src/pipelines/fvt-launcher.yml.j2 index 30843ad62f..56ab4f2faa 100644 --- a/tekton/src/pipelines/fvt-launcher.yml.j2 +++ b/tekton/src/pipelines/fvt-launcher.yml.j2 @@ -98,6 +98,10 @@ spec: type: string default: "true" description: "Set this to 'false' to stop the finalize task from running for this launcher" + - name: set_finished + type: string + default: "true" + description: "Set this to 'false' to stop the the fvt test being marked as complete" # Deprovision Resources # ------------------------------------------------------------------------- @@ -936,10 +940,12 @@ spec: value: "$(params.deprovision)" - name: finalize value: "$(params.finalize)" + - name: set_finished + value: "$(params.set_finished)" - name: image_pull_policy value: $(params.image_pull_policy) - name: pipelinerun_name - value: "$(params.mas_instance_id)-fvt-finally" + value: "$(context.pipelineRun.name)-fvt-finally" workspaces: # The generated configuration files diff --git a/tekton/src/pipelines/fvt-optimizer.yml.j2 b/tekton/src/pipelines/fvt-optimizer.yml.j2 index 4af966641d..8fee785ae3 100644 --- a/tekton/src/pipelines/fvt-optimizer.yml.j2 +++ b/tekton/src/pipelines/fvt-optimizer.yml.j2 @@ -84,11 +84,10 @@ spec: - input: "$(params.ivt_digest_core)" operator: notin values: [""] - - # 2. Run "optimizer_fvt" (CTF) + # 2. Run "api_python_optim_model" (CTF) # ----------------------------------------------------------------------------- - - name: fvt-optimizer + - name: fvt-optimizer-python-model params: - name: mas_instance_id value: $(params.mas_instance_id) @@ -104,7 +103,7 @@ spec: - name: fvt_image_digest value: $(params.fvt_digest_ctf) - name: fvt_test_suite - value: optimizer_fvt # pytest_marker in Common Test Framework + value: api_python_optim_model # pytest_marker in Common Test Framework - name: product_channel value: $(params.mas_app_channel_optimizer) - name: product_id @@ -123,6 +122,158 @@ spec: workspaces: - name: configs workspace: shared-configs + + # 3. Run "api_java_optim_model" (CTF) + # ----------------------------------------------------------------------------- + - name: fvt-optimizer-java-model + params: + - name: mas_instance_id + value: $(params.mas_instance_id) + - name: mas_workspace_id + value: $(params.mas_workspace_id) + + - name: fvt_image_registry + value: $(params.fvt_image_registry) + - name: fvt_image_namespace + value: ai-solutions + - name: fvt_image_name + value: common-test-framework + - name: fvt_image_digest + value: $(params.fvt_digest_ctf) + - name: fvt_test_suite + value: api_java_optim_model # pytest_marker in Common Test Framework + - name: product_channel + value: $(params.mas_app_channel_optimizer) + - name: product_id + value: ibm-mas-optimizer + + taskRef: + kind: Task + name: mas-fvt-run-suite + # Only if we've set a digest of the Predict FVT to run + when: + - input: "$(params.fvt_digest_ctf)" + operator: notin + values: [""] + runAfter: + - fvt-optimizer-python-model + workspaces: + - name: configs + workspace: shared-configs + + # 4. Run "api_model_endpoints" (CTF) + # ----------------------------------------------------------------------------- + - name: fvt-optimizer-model-endpoints + params: + - name: mas_instance_id + value: $(params.mas_instance_id) + - name: mas_workspace_id + value: $(params.mas_workspace_id) + + - name: fvt_image_registry + value: $(params.fvt_image_registry) + - name: fvt_image_namespace + value: ai-solutions + - name: fvt_image_name + value: common-test-framework + - name: fvt_image_digest + value: $(params.fvt_digest_ctf) + - name: fvt_test_suite + value: api_model_endpoints # pytest_marker in Common Test Framework + - name: product_channel + value: $(params.mas_app_channel_optimizer) + - name: product_id + value: ibm-mas-optimizer + + taskRef: + kind: Task + name: mas-fvt-run-suite + # Only if we've set a digest of the Predict FVT to run + when: + - input: "$(params.fvt_digest_ctf)" + operator: notin + values: [""] + runAfter: + - fvt-optimizer-python-model + workspaces: + - name: configs + workspace: shared-configs + + # 5. Run "api_job_endpoints" (CTF) + # ----------------------------------------------------------------------------- + - name: fvt-optimizer-job-endpoints + params: + - name: mas_instance_id + value: $(params.mas_instance_id) + - name: mas_workspace_id + value: $(params.mas_workspace_id) + + - name: fvt_image_registry + value: $(params.fvt_image_registry) + - name: fvt_image_namespace + value: ai-solutions + - name: fvt_image_name + value: common-test-framework + - name: fvt_image_digest + value: $(params.fvt_digest_ctf) + - name: fvt_test_suite + value: api_job_endpoints # pytest_marker in Common Test Framework + - name: product_channel + value: $(params.mas_app_channel_optimizer) + - name: product_id + value: ibm-mas-optimizer + + taskRef: + kind: Task + name: mas-fvt-run-suite + # Only if we've set a digest of the Predict FVT to run + when: + - input: "$(params.fvt_digest_ctf)" + operator: notin + values: [""] + runAfter: + - fvt-optimizer-python-model + workspaces: + - name: configs + workspace: shared-configs + + # 6. Run "api_project_endpoints" (CTF) + # ----------------------------------------------------------------------------- + - name: fvt-optimizer-project-endpoints + params: + - name: mas_instance_id + value: $(params.mas_instance_id) + - name: mas_workspace_id + value: $(params.mas_workspace_id) + + - name: fvt_image_registry + value: $(params.fvt_image_registry) + - name: fvt_image_namespace + value: ai-solutions + - name: fvt_image_name + value: common-test-framework + - name: fvt_image_digest + value: $(params.fvt_digest_ctf) + - name: fvt_test_suite + value: api_project_endpoints # pytest_marker in Common Test Framework + - name: product_channel + value: $(params.mas_app_channel_optimizer) + - name: product_id + value: ibm-mas-optimizer + + taskRef: + kind: Task + name: mas-fvt-run-suite + # Only if we've set a digest of the Predict FVT to run + when: + - input: "$(params.fvt_digest_ctf)" + operator: notin + values: [""] + runAfter: + - fvt-optimizer-python-model + workspaces: + - name: configs + workspace: shared-configs finally: # 1. Run CV diff --git a/tekton/src/pipelines/gitops/deprovision-cluster.yml.j2 b/tekton/src/pipelines/gitops/deprovision-cluster.yml.j2 index f7978b07db..c772613c15 100644 --- a/tekton/src/pipelines/gitops/deprovision-cluster.yml.j2 +++ b/tekton/src/pipelines/gitops/deprovision-cluster.yml.j2 @@ -48,14 +48,21 @@ spec: # 0. Wait for the deprovsion mas pipeline to complete # ------------------------------------------------------------------------- - name: wait-for-deprovision + timeout: "0" + taskRef: + kind: Task + name: mas-devops-wait-for-tekton params: - - name: pipelinerun_name + - name: type + value: pipelinerun + - name: name value: $(params.pipelinerun_name) + - name: delay + value: 120 # seconds between checking the status of the pipelinerun + - name: max_retries + value: 120 # attempts before giving up - name: ignore_failure - value: $(params.ignore_failure) - taskRef: - kind: Task - name: mas-fvt-wait-for-pipelinerun + value: $(params.ignore_failure) # fails and exit once the first failure is detected {% endif %} - name: gitops-deprovision-rosa diff --git a/tekton/src/pipelines/gitops/deprovision-mas-deps.yml.j2 b/tekton/src/pipelines/gitops/deprovision-mas-deps.yml.j2 index 0ec1d13f9a..1df93d80eb 100644 --- a/tekton/src/pipelines/gitops/deprovision-mas-deps.yml.j2 +++ b/tekton/src/pipelines/gitops/deprovision-mas-deps.yml.j2 @@ -84,26 +84,65 @@ spec: - name: ibmcloud_apikey type: string default: "" + - name: cos_use_hmac + type: string + default: "" tasks: {% if wait_for_deprovision == true %} # 0. Wait for the deprovsion mas pipeline to complete # ------------------------------------------------------------------------- - name: wait-for-deprovision + timeout: "0" + taskRef: + kind: Task + name: mas-devops-wait-for-tekton params: - - name: pipelinerun_name + - name: type + value: pipelinerun + - name: name value: $(params.pipelinerun_name) + - name: delay + value: 120 # seconds between checking the status of the pipelinerun + - name: max_retries + value: 120 # attempts before giving up - name: ignore_failure - value: $(params.ignore_failure) - taskRef: - kind: Task - name: mas-fvt-wait-for-pipelinerun + value: $(params.ignore_failure) # fails and exit once the first failure is detected {% endif %} - - name: gitops-deprovision-mongo + + # Deprovision EFS + # ------------------------------------------------------------------------- + - name: gitops-deprovision-efs {% if wait_for_deprovision == true %} runAfter: - wait-for-deprovision {% endif %} + params: + {{ lookup('template', pipeline_src_dir ~ '/taskdefs/gitops/common/secrets-params.yml.j2') | indent(8) }} + - name: cluster_name + value: $(params.cluster_name) + - name: mas_instance_id + value: $(params.mas_instance_id) + - name: cloud_provider + value: $(params.cloud_provider) + - name: avp_aws_secret_key + value: $(params.avp_aws_secret_key) + - name: avp_aws_access_key + value: $(params.avp_aws_access_key) + - name: efs_action + value: $(params.efs_action) + workspaces: + - name: configs + workspace: configs + taskRef: + kind: Task + name: gitops-deprovision-efs + + # Deprovision Mongo + # ------------------------------------------------------------------------- + - name: gitops-deprovision-mongo + runAfter: + - gitops-deprovision-efs params: - name: cluster_name value: $(params.cluster_name) @@ -129,11 +168,12 @@ spec: workspaces: - name: configs workspace: configs + + # Deprovision Kafka + # ------------------------------------------------------------------------- - name: gitops-deprovision-kafka -{% if wait_for_deprovision == true %} runAfter: - - wait-for-deprovision -{% endif %} + - gitops-deprovision-efs params: - name: cluster_name value: $(params.cluster_name) @@ -162,13 +202,11 @@ spec: - name: configs workspace: configs - # 11. Deprovision COS + # Deprovision COS # ------------------------------------------------------------------------- - name: gitops-deprovision-cos -{% if wait_for_deprovision == true %} runAfter: - - wait-for-deprovision -{% endif %} + - gitops-deprovision-efs params: {{ lookup('template', pipeline_src_dir ~ '/taskdefs/gitops/common/secrets-params.yml.j2') | indent(8) }} @@ -176,20 +214,16 @@ spec: - name: github_pat value: $(params.github_pat) - - name: cluster_name value: $(params.cluster_name) - name: account value: $(params.account) - - name: avp_aws_secret_key value: $(params.avp_aws_secret_key) - name: avp_aws_access_key value: $(params.avp_aws_access_key) - - name: mas_instance_id value: $(params.mas_instance_id) - - name: cos_action value: $(params.cos_action) - name: cos_type @@ -198,39 +232,11 @@ spec: value: $(params.ibmcloud_resourcegroup) - name: ibmcloud_apikey value: $(params.ibmcloud_apikey) - + - name: cos_use_hmac + value: $(params.cos_use_hmac) workspaces: - name: configs workspace: configs taskRef: kind: Task name: gitops-deprovision-cos - - # Uninstall AWS Elastic File Service (EFS) - - name: gitops-deprovision-efs -{% if wait_for_deprovision == true %} - runAfter: - - wait-for-deprovision -{% endif %} - params: - {{ lookup('template', pipeline_src_dir ~ '/taskdefs/gitops/common/secrets-params.yml.j2') | indent(8) }} - - name: cluster_name - value: $(params.cluster_name) - - name: mas_instance_id - value: $(params.mas_instance_id) - - name: cloud_provider - value: $(params.cloud_provider) - - name: avp_aws_secret_key - value: $(params.avp_aws_secret_key) - - name: avp_aws_access_key - value: $(params.avp_aws_access_key) - - name: efs_action - value: $(params.efs_action) - - workspaces: - - name: configs - workspace: configs - - taskRef: - kind: Task - name: gitops-deprovision-efs diff --git a/tekton/src/pipelines/gitops/gitops-mas-apps.yml.j2 b/tekton/src/pipelines/gitops/gitops-mas-apps.yml.j2 index bba6d644a5..1eb6e68623 100644 --- a/tekton/src/pipelines/gitops/gitops-mas-apps.yml.j2 +++ b/tekton/src/pipelines/gitops/gitops-mas-apps.yml.j2 @@ -467,6 +467,10 @@ spec: type: string default: "false" + - name: run_sanity_test + type: string + default: "false" + tasks: # 2. Kafka # ------------------------------------------------------------------------- diff --git a/tekton/src/pipelines/gitops/gitops-mas-cluster.yml.j2 b/tekton/src/pipelines/gitops/gitops-mas-cluster.yml.j2 index 6b705e7f42..da10aa7105 100644 --- a/tekton/src/pipelines/gitops/gitops-mas-cluster.yml.j2 +++ b/tekton/src/pipelines/gitops/gitops-mas-cluster.yml.j2 @@ -107,6 +107,9 @@ spec: - name: cluster_promotion_cluster_values type: string default: '' + - name: devops_build_number + type: string + default: '' - name: dns_provider type: string default: cis @@ -169,6 +172,9 @@ spec: - name: cluster_promotion_cluster_values value: $(params.cluster_promotion_cluster_values) + - name: devops_build_number + value: $(params.devops_build_number) + - name: ocp_cluster_domain value: $(params.ocp_cluster_domain) - name: dns_provider diff --git a/tekton/src/pipelines/gitops/gitops-mas-deps.yml.j2 b/tekton/src/pipelines/gitops/gitops-mas-deps.yml.j2 index 1744047d1c..fb2eb9a791 100644 --- a/tekton/src/pipelines/gitops/gitops-mas-deps.yml.j2 +++ b/tekton/src/pipelines/gitops/gitops-mas-deps.yml.j2 @@ -85,6 +85,10 @@ spec: type: string description: COS action to be performed (provision or deprovision) default: "" + - name: cos_use_hmac + type: string + description: Optional boolean variable weather hmac is enabled or not + default: "" - name: ibmcloud_apikey type: string @@ -95,14 +99,21 @@ spec: # 0. Wait for the provsion pipeline to complete # ------------------------------------------------------------------------- - name: wait-for-provision + timeout: "0" + taskRef: + kind: Task + name: mas-devops-wait-for-tekton params: - - name: pipelinerun_name + - name: type + value: pipelinerun + - name: name value: $(params.pipelinerun_name) + - name: delay + value: 120 # seconds between checking the status of the pipelinerun + - name: max_retries + value: 120 # attempts before giving up - name: ignore_failure - value: $(params.ignore_failure) - taskRef: - kind: Task - name: mas-fvt-wait-for-pipelinerun + value: $(params.ignore_failure) # fails and exit once the first failure is detected {% endif %} - name: gitops-mongo {% if wait_for_provision == true %} @@ -214,6 +225,8 @@ spec: value: $(params.ibmcloud_resourcegroup) - name: ibmcloud_apikey value: $(params.ibmcloud_apikey) + - name: cos_use_hmac + value: $(params.cos_use_hmac) workspaces: - name: configs diff --git a/tekton/src/pipelines/gitops/gitops-mas-fvt-preparer-pipeline.yml.j2 b/tekton/src/pipelines/gitops/gitops-mas-fvt-preparer-pipeline.yml.j2 index 850d3d5d5a..7587cae095 100644 --- a/tekton/src/pipelines/gitops/gitops-mas-fvt-preparer-pipeline.yml.j2 +++ b/tekton/src/pipelines/gitops/gitops-mas-fvt-preparer-pipeline.yml.j2 @@ -38,6 +38,8 @@ spec: type: string - name: artifactory_generic_release_url type: string + - name: artifactory_generic_logs_url + type: string - name: fvt_ansible_version type: string @@ -81,6 +83,8 @@ spec: - name: mas_workspace_id type: string + - name: mas_channel + type: string - name: launchfvt_core type: string @@ -186,6 +190,8 @@ spec: - name: artifactory_generic_release_url value: $(params.artifactory_generic_release_url) + - name: artifactory_generic_logs_url + value: $(params.artifactory_generic_logs_url) - name: fvt_ansible_version value: $(params.fvt_ansible_version) @@ -229,6 +235,8 @@ spec: - name: mas_workspace_id value: $(params.mas_workspace_id) + - name: mas_channel + value: $(params.mas_channel) - name: launchfvt_core value: $(params.launchfvt_core) diff --git a/tekton/src/pipelines/gitops/gitops-mas-initiator.yml.j2 b/tekton/src/pipelines/gitops/gitops-mas-initiator.yml.j2 index 3223869e25..1cfbb1622a 100644 --- a/tekton/src/pipelines/gitops/gitops-mas-initiator.yml.j2 +++ b/tekton/src/pipelines/gitops/gitops-mas-initiator.yml.j2 @@ -114,14 +114,21 @@ spec: # 0. Wait for the provsion pipeline to complete # ------------------------------------------------------------------------- - name: wait-for-provision + timeout: "0" + taskRef: + kind: Task + name: mas-devops-wait-for-tekton params: - - name: pipelinerun_name + - name: type + value: pipelinerun + - name: name value: $(params.pipelinerun_name) + - name: delay + value: 120 # seconds between checking the status of the pipelinerun + - name: max_retries + value: 120 # attempts before giving up - name: ignore_failure - value: $(params.ignore_failure) - taskRef: - kind: Task - name: mas-fvt-wait-for-pipelinerun + value: $(params.ignore_failure) # fails and exit once the first failure is detected {% endif %} - name: gitops-mas-initiator {% if wait_for_provision == true %} diff --git a/tekton/src/pipelines/gitops/provision-bootstrap-cluster.yml.j2 b/tekton/src/pipelines/gitops/provision-bootstrap-cluster.yml.j2 index 0bfd6ba787..18d88d1d7c 100644 --- a/tekton/src/pipelines/gitops/provision-bootstrap-cluster.yml.j2 +++ b/tekton/src/pipelines/gitops/provision-bootstrap-cluster.yml.j2 @@ -64,14 +64,21 @@ spec: # 0. Wait for the deprovsion pipeline to complete # ------------------------------------------------------------------------- - name: wait-for-deprovision + timeout: "0" + taskRef: + kind: Task + name: mas-devops-wait-for-tekton params: - - name: pipelinerun_name + - name: type + value: pipelinerun + - name: name value: $(params.pipelinerun_name) + - name: delay + value: 120 # seconds between checking the status of the pipelinerun + - name: max_retries + value: 120 # attempts before giving up - name: ignore_failure - value: $(params.ignore_failure) - taskRef: - kind: Task - name: mas-fvt-wait-for-pipelinerun + value: $(params.ignore_failure) # fails and exit once the first failure is detected {% endif %} - name: gitops-rosa {% if wait_for_deprovision == true %} diff --git a/tekton/src/pipelines/install.yml.j2 b/tekton/src/pipelines/install.yml.j2 index 11c0708a42..d0d3c24910 100644 --- a/tekton/src/pipelines/install.yml.j2 +++ b/tekton/src/pipelines/install.yml.j2 @@ -54,7 +54,7 @@ spec: # 1.2 Red Hat Certificate Manager {{ lookup('template', pipeline_src_dir ~ '/taskdefs/cluster-setup/cert-manager.yml.j2') | indent(4) }} runAfter: - - pre-install-check + - ibm-catalogs # 1.3 Configure Grafana {{ lookup('template', pipeline_src_dir ~ '/taskdefs/cluster-setup/grafana.yml.j2') | indent(4) }} @@ -63,7 +63,7 @@ spec: operator: in values: ["install"] runAfter: - - pre-install-check + - ibm-catalogs # 1.4 Configure ECK {{ lookup('template', pipeline_src_dir ~ '/taskdefs/cluster-setup/eck.yml.j2') | indent(4) }} @@ -121,6 +121,7 @@ spec: {{ lookup('template', pipeline_src_dir ~ '/taskdefs/cp4d/cp4d-platform.yml.j2') | indent(4) }} runAfter: - cert-manager + - ibm-catalogs # 3.2 Watson Studio {{ lookup('template', pipeline_src_dir ~ '/taskdefs/cp4d/cp4d-wsl.yml.j2') | indent(4) }} diff --git a/tekton/src/pipelines/rollback.yml.j2 b/tekton/src/pipelines/rollback.yml.j2 index 6a621a99af..f288f85168 100644 --- a/tekton/src/pipelines/rollback.yml.j2 +++ b/tekton/src/pipelines/rollback.yml.j2 @@ -77,7 +77,7 @@ spec: value: $(params.pipelinerun_name) - name: delay value: 600 # seconds between checking the status of the pipelinerun - - name: retries + - name: max_retries value: 50 # attempts before giving up - name: ignore_failure value: "False" # fails and exit once the first failure is detected diff --git a/tekton/src/pipelines/taskdefs/cluster-setup/ocp-verify-all.yml.j2 b/tekton/src/pipelines/taskdefs/cluster-setup/ocp-verify-all.yml.j2 index b8db26f044..4533a25f80 100644 --- a/tekton/src/pipelines/taskdefs/cluster-setup/ocp-verify-all.yml.j2 +++ b/tekton/src/pipelines/taskdefs/cluster-setup/ocp-verify-all.yml.j2 @@ -13,4 +13,4 @@ when: - input: "$(params.skip_pre_check)" operator: notin - values: ["true"] + values: ["True"] diff --git a/tekton/src/pipelines/taskdefs/cluster-setup/ocp-verify.yml.j2 b/tekton/src/pipelines/taskdefs/cluster-setup/ocp-verify.yml.j2 index eb91e5b9e8..4c90e3a885 100644 --- a/tekton/src/pipelines/taskdefs/cluster-setup/ocp-verify.yml.j2 +++ b/tekton/src/pipelines/taskdefs/cluster-setup/ocp-verify.yml.j2 @@ -25,4 +25,4 @@ when: - input: "$(params.skip_pre_check)" operator: notin - values: ["true"] + values: ["True"] diff --git a/tekton/src/pipelines/taskdefs/core/suite-install.yml.j2 b/tekton/src/pipelines/taskdefs/core/suite-install.yml.j2 index edbeaf591c..ac28b43d69 100644 --- a/tekton/src/pipelines/taskdefs/core/suite-install.yml.j2 +++ b/tekton/src/pipelines/taskdefs/core/suite-install.yml.j2 @@ -42,6 +42,8 @@ value: $(params.default_idp) - name: seamless_login value: $(params.seamless_login) + - name: mas_special_characters + value: $(params.mas_special_characters) - name: sso_cookie_name value: $(params.sso_cookie_name) - name: allow_default_sso_cookie_name diff --git a/tekton/src/pipelines/taskdefs/cp4d/cp4d-aiopenscale.yml.j2 b/tekton/src/pipelines/taskdefs/cp4d/cp4d-aiopenscale.yml.j2 index f43aca4227..cea24b0160 100644 --- a/tekton/src/pipelines/taskdefs/cp4d/cp4d-aiopenscale.yml.j2 +++ b/tekton/src/pipelines/taskdefs/cp4d/cp4d-aiopenscale.yml.j2 @@ -25,7 +25,7 @@ name: mas-devops-cp4d-service # Only needed if Predict is being installed when: - - input: "$(params.mas_app_channel_predict)" + - input: "$(params.mas_app_channel_predict)$(params.cpd_install_all)" operator: notin values: [""] - input: "$(params.cpd_install_openscale)" diff --git a/tekton/src/pipelines/taskdefs/cp4d/cp4d-cognos.yml.j2 b/tekton/src/pipelines/taskdefs/cp4d/cp4d-cognos.yml.j2 index f62b063c0c..b5394b9f5a 100644 --- a/tekton/src/pipelines/taskdefs/cp4d/cp4d-cognos.yml.j2 +++ b/tekton/src/pipelines/taskdefs/cp4d/cp4d-cognos.yml.j2 @@ -23,7 +23,7 @@ name: mas-devops-cp4d-service # Only needed if Manage is being installed and Cognos is chosen to be installed when: - - input: "$(params.mas_app_channel_manage)" + - input: "$(params.mas_app_channel_manage)$(params.cpd_install_all)" operator: notin values: [""] - input: "$(params.cpd_install_cognos)" diff --git a/tekton/src/pipelines/taskdefs/cp4d/cp4d-platform.yml.j2 b/tekton/src/pipelines/taskdefs/cp4d/cp4d-platform.yml.j2 index 5823e2f360..a285d20894 100644 --- a/tekton/src/pipelines/taskdefs/cp4d/cp4d-platform.yml.j2 +++ b/tekton/src/pipelines/taskdefs/cp4d/cp4d-platform.yml.j2 @@ -18,6 +18,6 @@ name: mas-devops-cp4d # Only needed if either Predict, Assist, Health w/ WSL, or Cognos are being installed when: - - input: "$(params.mas_app_channel_predict)$(params.mas_app_channel_assist)$(params.mas_appws_bindings_health_wsl_flag)$(params.cpd_install_cognos)" + - input: "$(params.mas_app_channel_predict)$(params.mas_app_channel_assist)$(params.mas_appws_bindings_health_wsl_flag)$(params.cpd_install_cognos)$(params.cpd_install_all)" operator: notin values: [""] \ No newline at end of file diff --git a/tekton/src/pipelines/taskdefs/cp4d/cp4d-spark.yml.j2 b/tekton/src/pipelines/taskdefs/cp4d/cp4d-spark.yml.j2 index 93bc53dc58..3342ec0fc1 100644 --- a/tekton/src/pipelines/taskdefs/cp4d/cp4d-spark.yml.j2 +++ b/tekton/src/pipelines/taskdefs/cp4d/cp4d-spark.yml.j2 @@ -23,7 +23,7 @@ name: mas-devops-cp4d-service # Only needed if Predict is being installed when: - - input: "$(params.mas_app_channel_predict)" + - input: "$(params.mas_app_channel_predict)$(params.cpd_install_all)" operator: notin values: [""] workspaces: diff --git a/tekton/src/pipelines/taskdefs/cp4d/cp4d-spss.yml.j2 b/tekton/src/pipelines/taskdefs/cp4d/cp4d-spss.yml.j2 index 983d2cdfdc..c107fda35c 100644 --- a/tekton/src/pipelines/taskdefs/cp4d/cp4d-spss.yml.j2 +++ b/tekton/src/pipelines/taskdefs/cp4d/cp4d-spss.yml.j2 @@ -25,7 +25,7 @@ name: mas-devops-cp4d-service # Only needed if Predict is being installed when: - - input: "$(params.mas_app_channel_predict)" + - input: "$(params.mas_app_channel_predict)$(params.cpd_install_all)" operator: notin values: [""] - input: "$(params.cpd_install_spss)" diff --git a/tekton/src/pipelines/taskdefs/cp4d/cp4d-wml.yml.j2 b/tekton/src/pipelines/taskdefs/cp4d/cp4d-wml.yml.j2 index 12fc9f0bf2..d3464cab03 100644 --- a/tekton/src/pipelines/taskdefs/cp4d/cp4d-wml.yml.j2 +++ b/tekton/src/pipelines/taskdefs/cp4d/cp4d-wml.yml.j2 @@ -23,7 +23,7 @@ name: mas-devops-cp4d-service # Only needed if Predict is being installed when: - - input: "$(params.mas_app_channel_predict)" + - input: "$(params.mas_app_channel_predict)$(params.cpd_install_all)" operator: notin values: [""] workspaces: diff --git a/tekton/src/pipelines/taskdefs/cp4d/cp4d-wsl.yml.j2 b/tekton/src/pipelines/taskdefs/cp4d/cp4d-wsl.yml.j2 index 61a7c84e52..6272a88708 100644 --- a/tekton/src/pipelines/taskdefs/cp4d/cp4d-wsl.yml.j2 +++ b/tekton/src/pipelines/taskdefs/cp4d/cp4d-wsl.yml.j2 @@ -23,7 +23,7 @@ name: mas-devops-cp4d-service # Only needed if either Predict or Health w/ WSL are being installed when: - - input: "$(params.mas_app_channel_predict)$(params.mas_appws_bindings_health_wsl_flag)" + - input: "$(params.mas_app_channel_predict)$(params.mas_appws_bindings_health_wsl_flag)$(params.cpd_install_all)" operator: notin values: [""] workspaces: diff --git a/tekton/src/pipelines/taskdefs/dependencies/cos.yml.j2 b/tekton/src/pipelines/taskdefs/dependencies/cos.yml.j2 index 5933a13b7f..14dc4fc1fe 100644 --- a/tekton/src/pipelines/taskdefs/dependencies/cos.yml.j2 +++ b/tekton/src/pipelines/taskdefs/dependencies/cos.yml.j2 @@ -21,6 +21,8 @@ - name: custom_labels value: $(params.custom_labels) + - name: cos_use_hmac + value: $(params.cos_use_hmac) taskRef: kind: Task name: mas-devops-cos diff --git a/tekton/src/pipelines/taskdefs/fvt-core/phase1-under5min.yml.j2 b/tekton/src/pipelines/taskdefs/fvt-core/phase1-under5min.yml.j2 index 641a2713c2..44afd89201 100644 --- a/tekton/src/pipelines/taskdefs/fvt-core/phase1-under5min.yml.j2 +++ b/tekton/src/pipelines/taskdefs/fvt-core/phase1-under5min.yml.j2 @@ -8,6 +8,17 @@ value: catalogapi runAfter: {{ runAfter }} +# grafana ~5m +# ----------------------------------------------------------------------------- +- name: grafana + {{ lookup('template', 'taskdefs/fvt-core/common/taskref.yml.j2') | indent(2) }} + params: + {{ lookup('template', 'taskdefs/fvt-core/common/params.yml.j2') | indent(4) }} + - name: fvt_test_suite + value: grafana + runAfter: + - catalogapi + # ibmadminissuer ~5m # ----------------------------------------------------------------------------- - name: ibmadminissuer @@ -17,7 +28,7 @@ - name: fvt_test_suite value: ibmadminissuer runAfter: - - catalogapi + - grafana # milestonesapi ~5m # ----------------------------------------------------------------------------- diff --git a/tekton/src/pipelines/taskdefs/fvt-manage-is/phase1.yml.j2 b/tekton/src/pipelines/taskdefs/fvt-manage-is/phase1.yml.j2 index 0b523243fd..83e36139e6 100644 --- a/tekton/src/pipelines/taskdefs/fvt-manage-is/phase1.yml.j2 +++ b/tekton/src/pipelines/taskdefs/fvt-manage-is/phase1.yml.j2 @@ -3,8 +3,6 @@ # - fvt-health-testng-preparedata # Health # - fvt-health-testng-desktop # Health # - fvt-health-python # Health -# - fvt-manage-scheduler-api # Scheduler -# - fvt-manage-scheduler-setup # Scheduler # ----------------------------------------------------------------------------- # Health @@ -131,30 +129,12 @@ runAfter: - fvt-health-testng-preparedata - -# Scheduler -# ----------------------------------------------------------------------------- -# Scheduler - API Tests -- name: fvt-manage-scheduler-api - {{ lookup('template', pipeline_src_dir ~ '/taskdefs/fvt-manage/api/taskref.yml.j2') | indent(2) }} - params: - {{ lookup('template', pipeline_src_dir ~ '/taskdefs/fvt-manage/api/params.yml.j2') | indent(4) }} - - name: fvt_test_suite - value: scheduler-api - runAfter: - - fvt-manage-setup-is - -# Scheduler - UI Tests -- name: fvt-manage-scheduler-setup - {{ lookup('template', pipeline_src_dir ~ '/taskdefs/fvt-manage/ui/taskref.yml.j2') | indent(2) }} - {{ lookup('template', pipeline_src_dir ~ '/taskdefs/fvt-manage/ui/when.yml.j2') | indent(2) }} +# Minimum Verification Test for Operational Map Test Suites +- name: fvt-manage-operationalmap-api + {{ lookup('template', 'taskdefs/fvt-manage/api/taskref.yml.j2') | indent(2) }} params: - {{ lookup('template', pipeline_src_dir ~ '/taskdefs/fvt-manage/ui/params.yml.j2') | indent(4) }} + {{ lookup('template', 'taskdefs/fvt-manage/api/params.yml.j2') | indent(4) }} - name: fvt_test_suite - value: scheduler-setup-data - - name: fvt_mas_appws_component - value: scheduler - - name: fvt_test_driver - value: tpae + value: operationalmap-api runAfter: - fvt-manage-setup-is diff --git a/tekton/src/pipelines/taskdefs/fvt-manage-is/phase2.yml.j2 b/tekton/src/pipelines/taskdefs/fvt-manage-is/phase2.yml.j2 index 040eb3988f..0e8d9d42b0 100644 --- a/tekton/src/pipelines/taskdefs/fvt-manage-is/phase2.yml.j2 +++ b/tekton/src/pipelines/taskdefs/fvt-manage-is/phase2.yml.j2 @@ -20,8 +20,6 @@ runAfter: - fvt-health-testng-desktop - fvt-health-python - - fvt-manage-scheduler-api - - fvt-manage-scheduler-setup # ACM - UI - name: fvt-manage-acm-ui @@ -30,7 +28,7 @@ params: {{ lookup('template', 'taskdefs/fvt-manage/ui/params.yml.j2') | indent(4) }} - name: fvt_test_suite - value: acm-1 + value: acm-ui-bvt - name: fvt_mas_appws_component value: acm - name: fvt_test_driver @@ -38,9 +36,6 @@ runAfter: - fvt-health-testng-desktop - fvt-health-python - - fvt-manage-scheduler-api - - fvt-manage-scheduler-setup - # HSE # ----------------------------------------------------------------------------- @@ -54,8 +49,6 @@ runAfter: - fvt-health-testng-desktop - fvt-health-python - - fvt-manage-scheduler-api - - fvt-manage-scheduler-setup # HSE - UI - name: fvt-manage-hse-ui @@ -72,9 +65,6 @@ runAfter: - fvt-health-testng-desktop - fvt-health-python - - fvt-manage-scheduler-api - - fvt-manage-scheduler-setup - # Service Provider # ----------------------------------------------------------------------------- @@ -88,8 +78,6 @@ runAfter: - fvt-health-testng-desktop - fvt-health-python - - fvt-manage-scheduler-api - - fvt-manage-scheduler-setup # Service Provider - UI - name: fvt-manage-serviceprovider-ui @@ -98,7 +86,7 @@ params: {{ lookup('template', 'taskdefs/fvt-manage/ui/params.yml.j2') | indent(4) }} - name: fvt_test_suite - value: sp-1 + value: sp-ui-bvt - name: fvt_mas_appws_component value: serviceprovider - name: fvt_test_driver @@ -106,5 +94,3 @@ runAfter: - fvt-health-testng-desktop - fvt-health-python - - fvt-manage-scheduler-api - - fvt-manage-scheduler-setup diff --git a/tekton/src/pipelines/taskdefs/fvt-manage-is/phase3.yml.j2 b/tekton/src/pipelines/taskdefs/fvt-manage-is/phase3.yml.j2 index 3f2e8ae7d4..82c340d7ab 100644 --- a/tekton/src/pipelines/taskdefs/fvt-manage-is/phase3.yml.j2 +++ b/tekton/src/pipelines/taskdefs/fvt-manage-is/phase3.yml.j2 @@ -35,7 +35,7 @@ params: {{ lookup('template', 'taskdefs/fvt-manage/ui/params.yml.j2') | indent(4) }} - name: fvt_test_suite - value: nuc-1 + value: nuc-ui-bvt - name: fvt_mas_appws_component value: nuclear - name: fvt_test_driver @@ -73,7 +73,7 @@ params: {{ lookup('template', 'taskdefs/fvt-manage/ui/params.yml.j2') | indent(4) }} - name: fvt_test_suite - value: tr-1 + value: tr-ui-bvt - name: fvt_mas_appws_component value: transportation - name: fvt_test_driver diff --git a/tekton/src/pipelines/taskdefs/fvt-manage/phase2.yml.j2 b/tekton/src/pipelines/taskdefs/fvt-manage/phase2.yml.j2 index 589e049246..d4f04e2a52 100644 --- a/tekton/src/pipelines/taskdefs/fvt-manage/phase2.yml.j2 +++ b/tekton/src/pipelines/taskdefs/fvt-manage/phase2.yml.j2 @@ -2,6 +2,7 @@ # PHASE 2 # - fvt-manage-base-api-system (pytest) # - fvt-manage-base-api-mif (pytest) +# - fvt-manage-base-api-scheduler-setup-os (pytest) # ------------------------------------------------------------- # Manage FVT System @@ -23,3 +24,13 @@ value: base-api-mif runAfter: - fvt-manage-base-api-ivt + +# Manage Scheduler FVT - Setup Objects Structure +- name: fvt-manage-base-api-scheduler-setup-os + {{ lookup('template', pipeline_src_dir ~ '/taskdefs/fvt-manage/api/taskref.yml.j2') | indent(2) }} + params: + {{ lookup('template', pipeline_src_dir ~ '/taskdefs/fvt-manage/api/params.yml.j2') | indent(4) }} + - name: fvt_test_suite + value: base-api-scheduler-setup-os + runAfter: + - fvt-manage-base-api-ivt diff --git a/tekton/src/pipelines/taskdefs/fvt-manage/phase3.yml.j2 b/tekton/src/pipelines/taskdefs/fvt-manage/phase3.yml.j2 index efefef34b5..cb2ef1b20c 100644 --- a/tekton/src/pipelines/taskdefs/fvt-manage/phase3.yml.j2 +++ b/tekton/src/pipelines/taskdefs/fvt-manage/phase3.yml.j2 @@ -4,6 +4,8 @@ # - fvt-manage-base-ui-helplinks (selenium) # - fvt-manage-base-ui-wo-basic (selenium) # - fvt-manage-base-ui-mas-navigation (selenium) +# - fvt-manage-base-ui-requestreport-pages (selenium) +# - fvt-manage-base-api-scheduler-qualification (pytest) # ------------------------------------------------------------- # Manage FVT Classification @@ -19,6 +21,7 @@ runAfter: - fvt-manage-base-api-system - fvt-manage-base-api-mif + - fvt-manage-base-api-scheduler-setup-os # Manage FVT Help Links - name: fvt-manage-base-ui-helplinks @@ -33,6 +36,7 @@ runAfter: - fvt-manage-base-api-system - fvt-manage-base-api-mif + - fvt-manage-base-api-scheduler-setup-os # Manage FVT Work Order Basic Scenario - name: fvt-manage-base-ui-wo-basic @@ -47,6 +51,7 @@ runAfter: - fvt-manage-base-api-system - fvt-manage-base-api-mif + - fvt-manage-base-api-scheduler-setup-os # Manage FVT Mas Navigation Scenario - name: fvt-manage-base-ui-mas-navigation @@ -61,3 +66,31 @@ runAfter: - fvt-manage-base-api-system - fvt-manage-base-api-mif + - fvt-manage-base-api-scheduler-setup-os + +# Manage FVT Generate Request Pages for Reports +- name: fvt-manage-base-ui-requestreport-pages + {{ lookup('template', 'taskdefs/fvt-manage/ui/taskref.yml.j2') | indent(2) }} + {{ lookup('template', 'taskdefs/fvt-manage/ui/when.yml.j2') | indent(2) }} + params: + {{ lookup('template', 'taskdefs/fvt-manage/ui/params.yml.j2') | indent(4) }} + - name: fvt_test_suite_prefix + value: base-ui + - name: fvt_test_suite + value: requestreport-pages + runAfter: + - fvt-manage-base-api-system + - fvt-manage-base-api-mif + - fvt-manage-base-api-scheduler-setup-os + +# Manage Scheduler FVT - Qualification +- name: fvt-manage-base-api-scheduler-qualification + {{ lookup('template', pipeline_src_dir ~ '/taskdefs/fvt-manage/api/taskref.yml.j2') | indent(2) }} + params: + {{ lookup('template', pipeline_src_dir ~ '/taskdefs/fvt-manage/api/params.yml.j2') | indent(4) }} + - name: fvt_test_suite + value: base-api-scheduler-qualification + runAfter: + - fvt-manage-base-api-system + - fvt-manage-base-api-mif + - fvt-manage-base-api-scheduler-setup-os diff --git a/tekton/src/pipelines/taskdefs/fvt-manage/phase4.yml.j2 b/tekton/src/pipelines/taskdefs/fvt-manage/phase4.yml.j2 index ce851ca86e..be9df63c89 100644 --- a/tekton/src/pipelines/taskdefs/fvt-manage/phase4.yml.j2 +++ b/tekton/src/pipelines/taskdefs/fvt-manage/phase4.yml.j2 @@ -22,8 +22,10 @@ - fvt-manage-base-ui-helplinks - fvt-manage-base-ui-wo-basic - fvt-manage-base-ui-mas-navigation + - fvt-manage-base-api-scheduler-qualification + - fvt-manage-base-ui-requestreport-pages -# Manage FVT BIRT Reports +# Manage FVT BIRT Reports - name: fvt-manage-base-ui-birt-report {{ lookup('template', pipeline_src_dir ~ '/taskdefs/fvt-manage/ui/when.yml.j2') | indent(2) }} taskRef: @@ -36,6 +38,8 @@ - fvt-manage-base-ui-helplinks - fvt-manage-base-ui-wo-basic - fvt-manage-base-ui-mas-navigation + - fvt-manage-base-api-scheduler-qualification + - fvt-manage-base-ui-requestreport-pages # Manage FVT New User Update/Delete/Verufy - name: fvt-manage-base-ui-user-crud @@ -52,6 +56,8 @@ - fvt-manage-base-ui-helplinks - fvt-manage-base-ui-wo-basic - fvt-manage-base-ui-mas-navigation + - fvt-manage-base-api-scheduler-qualification + - fvt-manage-base-ui-requestreport-pages # Manage FVT User Consumption verification - name: fvt-manage-base-ui-user-consumption @@ -68,6 +74,8 @@ - fvt-manage-base-ui-helplinks - fvt-manage-base-ui-wo-basic - fvt-manage-base-ui-mas-navigation + - fvt-manage-base-api-scheduler-qualification + - fvt-manage-base-ui-requestreport-pages # Manage FVT Communication Template - name: fvt-manage-base-ui-communication-temp @@ -84,3 +92,5 @@ - fvt-manage-base-ui-helplinks - fvt-manage-base-ui-wo-basic - fvt-manage-base-ui-mas-navigation + - fvt-manage-base-api-scheduler-qualification + - fvt-manage-base-ui-requestreport-pages diff --git a/tekton/src/pipelines/taskdefs/fvt-mobile/pytest/phase3-apps.yml.j2 b/tekton/src/pipelines/taskdefs/fvt-mobile/pytest/phase3-apps.yml.j2 index cc69f89b21..34d16796c0 100644 --- a/tekton/src/pipelines/taskdefs/fvt-mobile/pytest/phase3-apps.yml.j2 +++ b/tekton/src/pipelines/taskdefs/fvt-mobile/pytest/phase3-apps.yml.j2 @@ -3,7 +3,9 @@ params: {{ lookup('template', 'taskdefs/fvt-mobile/common/params-pytest.yml.j2') | indent(4) }} - name: fvt_test_suite - value: mobile-api-sr + value: mobile-api-sr + - name: enable_perf_debug + value: "True" runAfter: - fvt-mobile-pytest-setup diff --git a/tekton/src/pipelines/taskdefs/gitops/apps/assist-workspace.yml.j2 b/tekton/src/pipelines/taskdefs/gitops/apps/assist-workspace.yml.j2 index f9800602d0..19c9046d3b 100644 --- a/tekton/src/pipelines/taskdefs/gitops/apps/assist-workspace.yml.j2 +++ b/tekton/src/pipelines/taskdefs/gitops/apps/assist-workspace.yml.j2 @@ -28,6 +28,8 @@ value: $(params.mas_app_kind_assist) - name: ingress value: $(params.ingress) + - name: run_sanity_test + value: $(params.run_sanity_test) taskRef: name: gitops-suite-app-config kind: Task diff --git a/tekton/src/pipelines/taskdefs/gitops/apps/iot-workspace.yml.j2 b/tekton/src/pipelines/taskdefs/gitops/apps/iot-workspace.yml.j2 index 97177c6e4f..5c099a5c39 100644 --- a/tekton/src/pipelines/taskdefs/gitops/apps/iot-workspace.yml.j2 +++ b/tekton/src/pipelines/taskdefs/gitops/apps/iot-workspace.yml.j2 @@ -28,6 +28,8 @@ value: $(params.mas_app_kind_iot) - name: ingress value: $(params.ingress) + - name: run_sanity_test + value: $(params.run_sanity_test) taskRef: name: gitops-suite-app-config kind: Task diff --git a/tekton/src/pipelines/taskdefs/gitops/apps/manage-workspace.yml.j2 b/tekton/src/pipelines/taskdefs/gitops/apps/manage-workspace.yml.j2 index affd89f5e1..5b694804dd 100644 --- a/tekton/src/pipelines/taskdefs/gitops/apps/manage-workspace.yml.j2 +++ b/tekton/src/pipelines/taskdefs/gitops/apps/manage-workspace.yml.j2 @@ -40,6 +40,8 @@ value: $(params.mas_manual_certs_yaml) - name: ingress value: $(params.ingress) + - name: run_sanity_test + value: $(params.run_sanity_test) taskRef: name: gitops-suite-app-config kind: Task diff --git a/tekton/src/pipelines/taskdefs/gitops/apps/monitor-workspace.yml.j2 b/tekton/src/pipelines/taskdefs/gitops/apps/monitor-workspace.yml.j2 index 6efc38aa7d..eb16e22c1d 100644 --- a/tekton/src/pipelines/taskdefs/gitops/apps/monitor-workspace.yml.j2 +++ b/tekton/src/pipelines/taskdefs/gitops/apps/monitor-workspace.yml.j2 @@ -28,6 +28,8 @@ value: $(params.mas_app_kind_monitor) - name: ingress value: $(params.ingress) + - name: run_sanity_test + value: $(params.run_sanity_test) taskRef: name: gitops-suite-app-config kind: Task diff --git a/tekton/src/pipelines/taskdefs/gitops/apps/optimizer-workspace.yml.j2 b/tekton/src/pipelines/taskdefs/gitops/apps/optimizer-workspace.yml.j2 index 99883a1f97..d427c5e949 100644 --- a/tekton/src/pipelines/taskdefs/gitops/apps/optimizer-workspace.yml.j2 +++ b/tekton/src/pipelines/taskdefs/gitops/apps/optimizer-workspace.yml.j2 @@ -28,6 +28,8 @@ value: $(params.mas_app_kind_optimizer) - name: ingress value: $(params.ingress) + - name: run_sanity_test + value: $(params.run_sanity_test) taskRef: name: gitops-suite-app-config kind: Task diff --git a/tekton/src/pipelines/taskdefs/gitops/apps/predict-workspace.yml.j2 b/tekton/src/pipelines/taskdefs/gitops/apps/predict-workspace.yml.j2 index 06e6e88cb2..07c34f44ac 100644 --- a/tekton/src/pipelines/taskdefs/gitops/apps/predict-workspace.yml.j2 +++ b/tekton/src/pipelines/taskdefs/gitops/apps/predict-workspace.yml.j2 @@ -37,6 +37,8 @@ value: $(params.mas_app_kind_predict) - name: ingress value: $(params.ingress) + - name: run_sanity_test + value: $(params.run_sanity_test) taskRef: name: gitops-suite-app-config kind: Task diff --git a/tekton/src/pipelines/taskdefs/gitops/apps/visualinspection-workspace.yml.j2 b/tekton/src/pipelines/taskdefs/gitops/apps/visualinspection-workspace.yml.j2 index 9d334790e9..9951c72bde 100644 --- a/tekton/src/pipelines/taskdefs/gitops/apps/visualinspection-workspace.yml.j2 +++ b/tekton/src/pipelines/taskdefs/gitops/apps/visualinspection-workspace.yml.j2 @@ -28,6 +28,8 @@ value: $(params.mas_app_kind_visualinspection) - name: ingress value: $(params.ingress) + - name: run_sanity_test + value: $(params.run_sanity_test) taskRef: name: gitops-suite-app-config kind: Task diff --git a/tekton/src/pipelines/update.yml.j2 b/tekton/src/pipelines/update.yml.j2 index 8c5bab7cfc..bac813a717 100644 --- a/tekton/src/pipelines/update.yml.j2 +++ b/tekton/src/pipelines/update.yml.j2 @@ -122,6 +122,10 @@ spec: type: string description: Approves the MongoDb upgrade to version 6 if needed default: "" + - name: mongodb_v7_upgrade + type: string + description: Approves the MongoDb upgrade to version 7 if needed + default: "" # kafka update # ------------------------------------------------------------------------- @@ -224,7 +228,7 @@ spec: value: $(params.pipelinerun_name) - name: delay value: 600 # seconds between checking the status of the pipelinerun - - name: retries + - name: max_retries value: 50 # attempts before giving up - name: ignore_failure value: "False" # fails and exit once the first failure is detected @@ -404,6 +408,8 @@ spec: value: $(params.mongodb_version) - name: mongodb_v6_upgrade value: $(params.mongodb_v6_upgrade) + - name: mongodb_v7_upgrade + value: $(params.mongodb_v7_upgrade) - name: mongodb_replicas value: $(params.mongodb_replicas) @@ -443,7 +449,7 @@ spec: value: $(params.uds_storage_class) - name: uds_action value: $(params.uds_action) - - name: DRO_NAMESPACE + - name: dro_namespace value: $(params.dro_namespace) - name: devops_suite_name value: update-uds diff --git a/tekton/src/pipelines/upgrade.yml.j2 b/tekton/src/pipelines/upgrade.yml.j2 index ffbe519499..0621ac01c6 100644 --- a/tekton/src/pipelines/upgrade.yml.j2 +++ b/tekton/src/pipelines/upgrade.yml.j2 @@ -59,7 +59,7 @@ spec: value: $(params.pipelinerun_name) - name: delay value: 600 # seconds between checking the status of the pipelinerun - - name: retries + - name: max_retries value: 50 # attempts before giving up - name: ignore_failure value: "False" # fails and exit once the first failure is detected diff --git a/tekton/src/tasks/dependencies/cos.yml.j2 b/tekton/src/tasks/dependencies/cos.yml.j2 index cd2d782836..26b03734c7 100644 --- a/tekton/src/tasks/dependencies/cos.yml.j2 +++ b/tekton/src/tasks/dependencies/cos.yml.j2 @@ -43,6 +43,10 @@ spec: type: string description: Name of COS instance in IBM Cloud account default: "" + - name: cos_use_hmac + type: string + description: Optional boolean variable weather hmac is enabled or not + default: "" stepTemplate: @@ -72,6 +76,8 @@ spec: value: $(params.cos_resourcegroup) - name: IBMCLOUD_RESOURCEGROUP value: $(params.ibmcloud_resourcegroup) + - name: COS_USE_HMAC + value: $(params.cos_use_hmac) steps: - name: cos command: diff --git a/tekton/src/tasks/dependencies/mongodb.yml.j2 b/tekton/src/tasks/dependencies/mongodb.yml.j2 index cf33771a75..bc5738baa8 100644 --- a/tekton/src/tasks/dependencies/mongodb.yml.j2 +++ b/tekton/src/tasks/dependencies/mongodb.yml.j2 @@ -54,6 +54,10 @@ spec: type: string description: Approves the MongoDb upgrade to version 6 if needed default: "" + - name: mongodb_v7_upgrade + type: string + description: Approves the MongoDb upgrade to version 7 if needed + default: "" # Dependencies - IBM Cloud MongoDb # ------------------------------------------------------------------------- @@ -115,6 +119,8 @@ spec: value: $(params.mongodb_v5_upgrade) - name: MONGODB_V6_UPGRADE value: $(params.mongodb_v6_upgrade) + - name: MONGODB_V7_UPGRADE + value: $(params.mongodb_v7_upgrade) # Dependencies - IBM Cloud MongoDb - name: IBM_MONGO_NAME diff --git a/tekton/src/tasks/fvt/fvt-finalize.yml.j2 b/tekton/src/tasks/fvt/fvt-finalize.yml.j2 index 27cef6ebed..c3cf109a99 100644 --- a/tekton/src/tasks/fvt/fvt-finalize.yml.j2 +++ b/tekton/src/tasks/fvt/fvt-finalize.yml.j2 @@ -9,6 +9,8 @@ spec: - name: set_finished type: string + default: "true" + description: "Set this to 'false' to stop the the fvt test being marked as complete" steps: - name: finalize diff --git a/tekton/src/tasks/fvt/fvt-manage-last-phase.yml.j2 b/tekton/src/tasks/fvt/fvt-manage-last-phase.yml.j2 index 7b9de82db8..e8332fc1f7 100644 --- a/tekton/src/tasks/fvt/fvt-manage-last-phase.yml.j2 +++ b/tekton/src/tasks/fvt/fvt-manage-last-phase.yml.j2 @@ -145,8 +145,8 @@ spec: steps: - # Manage FVT MAS UserTimeout - - name: fvt-manage-mas-usertimeout + # Manage FVT Application Designer + - name: fvt-manage-application-designer image: '$(params.fvt_image_registry)/fvt-manage/fvt-ibm-mas-manage@$(params.fvt_image_digest)' imagePullPolicy: $(params.image_pull_policy) timeout: 150m # Ensure bad FVTs don't run forever @@ -158,10 +158,10 @@ spec: name: dshm env: - name: FVT_TEST_SUITE - value: masuser-timeout + value: application-designer - # Manage FVT Application Designer - - name: fvt-manage-application-designer + # Manage FVT Start Center + - name: fvt-manage-startcenter-config image: '$(params.fvt_image_registry)/fvt-manage/fvt-ibm-mas-manage@$(params.fvt_image_digest)' imagePullPolicy: $(params.image_pull_policy) timeout: 150m # Ensure bad FVTs don't run forever @@ -173,10 +173,10 @@ spec: name: dshm env: - name: FVT_TEST_SUITE - value: application-designer + value: startcenter-config - # Manage FVT Start Center - - name: fvt-manage-startcenter-config + # Manage FVT Create Workflow Design & Approve WO Assignments + - name: fvt-manage-workflow-designer image: '$(params.fvt_image_registry)/fvt-manage/fvt-ibm-mas-manage@$(params.fvt_image_digest)' imagePullPolicy: $(params.image_pull_policy) timeout: 150m # Ensure bad FVTs don't run forever @@ -188,10 +188,10 @@ spec: name: dshm env: - name: FVT_TEST_SUITE - value: startcenter-config - - # Manage FVT Create Workflow Design & Approve WO Assignments - - name: fvt-manage-workflow-designer + value: workflow-designer + + # Manage FVT MAS UserTimeout + - name: fvt-manage-mas-usertimeout image: '$(params.fvt_image_registry)/fvt-manage/fvt-ibm-mas-manage@$(params.fvt_image_digest)' imagePullPolicy: $(params.image_pull_policy) timeout: 150m # Ensure bad FVTs don't run forever @@ -203,4 +203,4 @@ spec: name: dshm env: - name: FVT_TEST_SUITE - value: workflow-designer + value: masuser-timeout diff --git a/tekton/src/tasks/fvt/fvt-mobile-pytest.yml.j2 b/tekton/src/tasks/fvt/fvt-mobile-pytest.yml.j2 index f3b92c6940..b35a65232d 100644 --- a/tekton/src/tasks/fvt/fvt-mobile-pytest.yml.j2 +++ b/tekton/src/tasks/fvt/fvt-mobile-pytest.yml.j2 @@ -51,6 +51,10 @@ spec: # Test-specific Information (all optional) # ------------------------------------------------------------------------- + - name: enable_perf_debug + type: string + description: Used to determine if response time will be displayed and saved or not + default: "False" - name: upload_file type: string description: Used only by fvt-mobile-version step to upload version file to artifactory @@ -110,7 +114,9 @@ spec: - name: UPLOAD_FILE value: "$(params.upload_file)" - + - name: ENABLE_PERF_DEBUG + value: "$(params.enable_perf_debug)" + - name: WORKSPACE_MANAGEDATA_PATH value: "$(params.workspace_managedata_path)" - name: INPUT_DATA_FILE @@ -206,7 +212,7 @@ spec: - name: fvt-mobile-version command: - python3 - - /opt/app-root/src/mobile-version-finder.py + - /opt/app-root/src/mobilever.py image: quay.io/ibmmas/cli:latest imagePullPolicy: $(params.image_pull_policy) onError: continue diff --git a/tekton/src/tasks/gitops/gitops-cluster.yml.j2 b/tekton/src/tasks/gitops/gitops-cluster.yml.j2 index b2144d16a1..2eb9e93e35 100644 --- a/tekton/src/tasks/gitops/gitops-cluster.yml.j2 +++ b/tekton/src/tasks/gitops/gitops-cluster.yml.j2 @@ -63,6 +63,10 @@ spec: type: string default: '' + - name: devops_build_number + type: string + default: '' + - name: dns_provider type: string default: cis @@ -122,6 +126,9 @@ spec: value: $(params.cluster_promotion_target_pr_title) - name: CLUSTER_PROMOTION_CLUSTER_VALUES value: $(params.cluster_promotion_cluster_values) + + - name: DEVOPS_BUILD_NUMBER + value: $(params.devops_build_number) - name: DNS_PROVIDER value: $(params.dns_provider) diff --git a/tekton/src/tasks/gitops/gitops-cos.yml.j2 b/tekton/src/tasks/gitops/gitops-cos.yml.j2 index 2c06076f57..83f3fb2d67 100644 --- a/tekton/src/tasks/gitops/gitops-cos.yml.j2 +++ b/tekton/src/tasks/gitops/gitops-cos.yml.j2 @@ -32,6 +32,8 @@ spec: type: string - name: ibmcloud_apikey type: string + - name: cos_use_hmac + type: string stepTemplate: name: gitops-cos @@ -62,17 +64,19 @@ spec: value: $(params.ibmcloud_resourcegroup) - name: IBMCLOUD_APIKEY value: $(params.ibmcloud_apikey) + - name: COS_USE_HMAC + value: $(params.cos_use_hmac) steps: - args: - |- git config --global user.name "MAS Automation" git config --global user.email "you@example.com" git config --global user.password $GITHUB_PAT - + export MAS_CONFIG_DIR=/workspace/configs/$MAS_INSTANCE_ID-cos mkdir -p /workspace/configs/$MAS_INSTANCE_ID-cos mkdir -p /tmp/init-cos - + mas gitops-cos -a $ACCOUNT -c $CLUSTER_NAME \ --dir /tmp/init-cos \ --secrets-path $SECRET_PATH diff --git a/tekton/src/tasks/gitops/gitops-deprovision-cos.yml.j2 b/tekton/src/tasks/gitops/gitops-deprovision-cos.yml.j2 index 7fb8eb90f3..ae090cb1d2 100644 --- a/tekton/src/tasks/gitops/gitops-deprovision-cos.yml.j2 +++ b/tekton/src/tasks/gitops/gitops-deprovision-cos.yml.j2 @@ -37,6 +37,8 @@ spec: type: string - name: ibmcloud_apikey type: string + - name: cos_use_hmac + type: string stepTemplate: name: gitops-deprovision-cos @@ -75,6 +77,8 @@ spec: value: $(params.ibmcloud_resourcegroup) - name: IBMCLOUD_APIKEY value: $(params.ibmcloud_apikey) + - name: COS_USE_HMAC + value: $(params.cos_use_hmac) steps: - args: - |- diff --git a/tekton/src/tasks/gitops/gitops-mas-fvt-preparer.yml.j2 b/tekton/src/tasks/gitops/gitops-mas-fvt-preparer.yml.j2 index 82be77fbbe..ec3bbb4c6d 100644 --- a/tekton/src/tasks/gitops/gitops-mas-fvt-preparer.yml.j2 +++ b/tekton/src/tasks/gitops/gitops-mas-fvt-preparer.yml.j2 @@ -69,6 +69,8 @@ spec: - name: artifactory_generic_release_url type: string + - name: artifactory_generic_logs_url + type: string - name: fvt_ansible_version type: string @@ -196,6 +198,8 @@ spec: value: $(params.fvt_image_registry) - name: ARTIFACTORY_GENERIC_RELEASE_URL value: $(params.artifactory_generic_release_url) + - name: ARTIFACTORY_GENERIC_LOGS_URL + value: $(params.artifactory_generic_logs_url) - name: FVT_ANSIBLE_VERSION value: $(params.fvt_ansible_version) - name: MAS_WORKSPACE_ID @@ -292,6 +296,12 @@ spec: - args: - |- + set -o pipefail + trap '[[ $? -eq 1 ]] && mas must-gather --directory /workspace/mustgather --extra-namespaces selenium' ERR EXIT + + export ARTIFACTORY_TOKEN=${FVT_ARTIFACTORY_TOKEN} + export ARTIFACTORY_UPLOAD_DIR=${ARTIFACTORY_GENERIC_LOGS_URL}/mas-fvt/${MAS_INSTANCE_ID}/${DEVOPS_BUILD_NUMBER} + CLI_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" . $CLI_DIR/functions/gitops_utils @@ -360,55 +370,84 @@ spec: SUITE_APP_NAME="suite.${CLUSTER_NAME}.${MAS_INSTANCE_ID}" WORKSPACE_APP="${MAS_WORKSPACE_ID}.suite.${CLUSTER_NAME}.${MAS_INSTANCE_ID}" - check_argo_app_healthy "${MONGO_CONFIG_APP}" - check_argo_app_healthy "${SLS_CONFIG_APP}" - check_argo_app_healthy "${BAS_CONFIG_APP}" - check_argo_app_healthy "${SLS_APP_NAME}" - check_argo_app_healthy "${SUITE_APP_NAME}" - check_argo_app_healthy "${WORKSPACE_APP}" + check_argo_app_healthy "${SLS_APP_NAME}" 180 #90 minutes + check_argo_app_healthy "${MONGO_CONFIG_APP}" 30 #15 minutes + check_argo_app_healthy "${SLS_CONFIG_APP}" 30 + check_argo_app_healthy "${BAS_CONFIG_APP}" 30 + check_argo_app_healthy "${SUITE_APP_NAME}" 30 + check_argo_app_healthy "${WORKSPACE_APP}" 30 fi if [[ "$LAUNCHER_ID" == "apps" ]]; then + # The following order is defined by the sync wave order in https://github.com/ibm-mas/gitops/tree/main/root-applications/ibm-mas-instance-root/templates + # First wave (has to include the prereqs cp4d, db2) + if [[ "$LAUNCHFVT_MANAGE" == "true" ]]; then + MASAPP_APP="manage.${CLUSTER_NAME}.${MAS_INSTANCE_ID}" + check_argo_app_healthy "${MASAPP_APP}" 240 + fi + if [[ "$LAUNCHFVT_MOBILE" == "true" ]]; then + MASAPP_APP="manage.${CLUSTER_NAME}.${MAS_INSTANCE_ID}" + check_argo_app_healthy "${MASAPP_APP}" 240 + fi + # Second wave if [[ "$LAUNCHFVT_ASSIST" == "true" ]]; then MASAPP_APP="assist.${CLUSTER_NAME}.${MAS_INSTANCE_ID}" - check_argo_app_healthy "${MASAPP_APP}" - check_argo_app_healthy "${MAS_WORKSPACE_ID}.${MASAPP_APP}" + check_argo_app_healthy "${MASAPP_APP}" 120 + fi + if [[ "$LAUNCHFVT_VISUALINSPECTION" == "true" ]]; then + MASAPP_APP="visualinspection.${CLUSTER_NAME}.${MAS_INSTANCE_ID}" + check_argo_app_healthy "${MASAPP_APP}" 120 fi if [[ "$LAUNCHFVT_IOT" == "true" ]]; then MASAPP_APP="iot.${CLUSTER_NAME}.${MAS_INSTANCE_ID}" - check_argo_app_healthy "${MASAPP_APP}" - check_argo_app_healthy "${MAS_WORKSPACE_ID}.${MASAPP_APP}" + check_argo_app_healthy "${MASAPP_APP}" 240 fi if [[ "$LAUNCHFVT_MANAGE" == "true" ]]; then MASAPP_APP="manage.${CLUSTER_NAME}.${MAS_INSTANCE_ID}" - check_argo_app_healthy "${MASAPP_APP}" - check_argo_app_healthy "${MAS_WORKSPACE_ID}.${MASAPP_APP}" + check_argo_app_healthy "${MAS_WORKSPACE_ID}.${MASAPP_APP}" 840 fi if [[ "$LAUNCHFVT_MOBILE" == "true" ]]; then MASAPP_APP="manage.${CLUSTER_NAME}.${MAS_INSTANCE_ID}" - check_argo_app_healthy "${MASAPP_APP}" - check_argo_app_healthy "${MAS_WORKSPACE_ID}.${MASAPP_APP}" + check_argo_app_healthy "${MAS_WORKSPACE_ID}.${MASAPP_APP}" 840 fi + # Third wave + if [[ "$LAUNCHFVT_ASSIST" == "true" ]]; then + MASAPP_APP="assist.${CLUSTER_NAME}.${MAS_INSTANCE_ID}" + check_argo_app_healthy "${MAS_WORKSPACE_ID}.${MASAPP_APP}" 120 + fi + if [[ "$LAUNCHFVT_VISUALINSPECTION" == "true" ]]; then + MASAPP_APP="visualinspection.${CLUSTER_NAME}.${MAS_INSTANCE_ID}" + check_argo_app_healthy "${MAS_WORKSPACE_ID}.${MASAPP_APP}" 120 + fi + if [[ "$LAUNCHFVT_IOT" == "true" ]]; then + MASAPP_APP="iot.${CLUSTER_NAME}.${MAS_INSTANCE_ID}" + check_argo_app_healthy "${MAS_WORKSPACE_ID}.${MASAPP_APP}" 20 + fi + # Fourth wave if [[ "$LAUNCHFVT_MONITOR" == "true" ]]; then MASAPP_APP="monitor.${CLUSTER_NAME}.${MAS_INSTANCE_ID}" - check_argo_app_healthy "${MASAPP_APP}" - check_argo_app_healthy "${MAS_WORKSPACE_ID}.${MASAPP_APP}" + check_argo_app_healthy "${MASAPP_APP}" 80 fi if [[ "$LAUNCHFVT_OPTIMIZER" == "true" ]]; then MASAPP_APP="optimizer.${CLUSTER_NAME}.${MAS_INSTANCE_ID}" - check_argo_app_healthy "${MASAPP_APP}" - check_argo_app_healthy "${MAS_WORKSPACE_ID}.${MASAPP_APP}" + check_argo_app_healthy "${MASAPP_APP}" 60 + fi + # Fifth wave + if [[ "$LAUNCHFVT_MONITOR" == "true" ]]; then + MASAPP_APP="monitor.${CLUSTER_NAME}.${MAS_INSTANCE_ID}" + check_argo_app_healthy "${MAS_WORKSPACE_ID}.${MASAPP_APP}" 180 fi + if [[ "$LAUNCHFVT_OPTIMIZER" == "true" ]]; then + MASAPP_APP="optimizer.${CLUSTER_NAME}.${MAS_INSTANCE_ID}" + check_argo_app_healthy "${MAS_WORKSPACE_ID}.${MASAPP_APP}" 60 + fi + # Sixth wave if [[ "$LAUNCHFVT_PREDICT" == "true" ]]; then MASAPP_APP="predict.${CLUSTER_NAME}.${MAS_INSTANCE_ID}" - check_argo_app_healthy "${MASAPP_APP}" - check_argo_app_healthy "${MAS_WORKSPACE_ID}.${MASAPP_APP}" - fi - if [[ "$LAUNCHFVT_VISUALINSPECTION" == "true" ]]; then - MASAPP_APP="visualinspection.${CLUSTER_NAME}.${MAS_INSTANCE_ID}" - check_argo_app_healthy "${MASAPP_APP}" - check_argo_app_healthy "${MAS_WORKSPACE_ID}.${MASAPP_APP}" + check_argo_app_healthy "${MASAPP_APP}" 120 + check_argo_app_healthy "${MAS_WORKSPACE_ID}.${MASAPP_APP}" 120 fi + fi echo "argo:argocd proj windows add mas --kind deny --schedule * * * * * --duration 4h --applications *" diff --git a/tekton/src/tasks/gitops/gitops-suite-app-config.yml.j2 b/tekton/src/tasks/gitops/gitops-suite-app-config.yml.j2 index 9d053af444..47f29ee52e 100644 --- a/tekton/src/tasks/gitops/gitops-suite-app-config.yml.j2 +++ b/tekton/src/tasks/gitops/gitops-suite-app-config.yml.j2 @@ -73,6 +73,9 @@ spec: - name: ingress type: string default: "false" + - name: run_sanity_test + type: string + default: "false" stepTemplate: name: gitops-suite-app-config @@ -131,6 +134,8 @@ spec: value: $(params.mas_manual_certs_yaml) - name: INGRESS value: $(params.ingress) + - name: RUN_SANITY_TEST + value: $(params.run_sanity_test) envFrom: - configMapRef: name: environment-properties diff --git a/tekton/src/tasks/ivt/ivt-core.yml.j2 b/tekton/src/tasks/ivt/ivt-core.yml.j2 index de520ad4f7..42dc1f308d 100644 --- a/tekton/src/tasks/ivt/ivt-core.yml.j2 +++ b/tekton/src/tasks/ivt/ivt-core.yml.j2 @@ -108,7 +108,7 @@ spec: steps: - image: '$(params.fvt_image_registry)/mas-devops/ivt-core@$(params.fvt_image_digest)' imagePullPolicy: $(params.image_pull_policy) - timeout: 4h0m0s # SPS Multi-Scan can take over three hours to run for IoT + timeout: 6h40m0s # SPS Multi-Scan can take over three hours to run for IoT onError: continue # Ensure bad FVTs don't break the pipeline resources: {} workingDir: /opt/ibm/test/src diff --git a/tekton/src/tasks/suite-install.yml.j2 b/tekton/src/tasks/suite-install.yml.j2 index c0364d9142..489ef9aa93 100644 --- a/tekton/src/tasks/suite-install.yml.j2 +++ b/tekton/src/tasks/suite-install.yml.j2 @@ -82,6 +82,10 @@ spec: type: string description: Required to install development MAS catalogs + # Special characters configuration + - name: mas_special_characters + type: string + default: '' # SSO Configuration - name: idle_timeout type: string @@ -189,7 +193,8 @@ spec: value: $(params.default_idp) - name: SEAMLESS_LOGIN value: $(params.seamless_login) - + - name: MAS_SPECIAL_CHARACTERS + value: $(params.mas_special_characters) - name: SSO_COOKIE_NAME value: $(params.sso_cookie_name) - name: ALLOW_DEFAULT_SSO_COOKIE_NAME