From 86157b784587c340bffed8a12a3a0228c58da18f Mon Sep 17 00:00:00 2001 From: whitfiea Date: Thu, 5 Feb 2026 13:54:10 +0000 Subject: [PATCH 01/12] Add manage backup --- python/src/mas/cli/backup/app.py | 101 ++++++++++++++++++++++- tekton/generate-tekton-tasks.yml | 3 +- tekton/src/params/backup.yml.j2 | 81 +++++++++++++++++- tekton/src/pipelines/mas-backup.yml.j2 | 88 +++++++++++++++++++- tekton/src/tasks/dependencies/db2.yml.j2 | 54 ++++++++++++ tekton/src/tasks/suite-app-backup.yml.j2 | 67 +++++++++++++++ 6 files changed, 389 insertions(+), 5 deletions(-) create mode 100644 tekton/src/tasks/suite-app-backup.yml.j2 diff --git a/python/src/mas/cli/backup/app.py b/python/src/mas/cli/backup/app.py index 188e377966c..f60c258feba 100644 --- a/python/src/mas/cli/backup/app.py +++ b/python/src/mas/cli/backup/app.py @@ -22,7 +22,7 @@ from ..validators import InstanceIDValidator from .argParser import backupArgParser from mas.devops.ocp import createNamespace, getConsoleURL -from mas.devops.mas import listMasInstances, getDefaultStorageClasses +from mas.devops.mas import listMasInstances, getDefaultStorageClasses, getWorkspaceId from mas.devops.tekton import preparePipelinesNamespace, installOpenShiftPipelines, updateTektonDefinitions, launchBackupPipeline @@ -70,7 +70,12 @@ def backup(self, argv): "s3_bucket_name", "s3_region", "artifactory_url", - "artifactory_repository" + "artifactory_repository", + # Manage App Backup + "mas_app_id", + "mas_workspace_id", + "backup_manage_app", + "backup_manage_db" ] 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 @@ -128,6 +133,9 @@ def backup(self, argv): if self.args.clean_backup is None: self.promptForCleanBackup() + # Prompt for Manage app backup + self.promptForManageAppBackup() + self.promptForUploadConfiguration() # Set default values for optional parameters if not provided @@ -156,6 +164,16 @@ def backup(self, argv): self.printSummary("MongoDB Namespace", self.getParam("mongodb_namespace") if self.getParam("mongodb_namespace") else "mongoce") self.printSummary("SLS Namespace", self.getParam("sls_namespace") if self.getParam("sls_namespace") else "ibm-sls") + if self.getParam("backup_manage_app") == "true": + self.printH2("Manage Application Backup") + self.printSummary("Backup Manage App", "Yes") + self.printSummary("Workspace ID", self.getParam("mas_workspace_id")) + self.printSummary("Backup Manage incluster Db2 Database", "Yes" if self.getParam("backup_manage_db") == "true" else "No") + if self.getParam("backup_manage_db") == "true": + self.printSummary("Db2 Namespace", self.getParam("db2_namespace")) + self.printSummary("Db2 Instance Name", self.getParam("db2_instance_name")) + self.printSummary("Db2 Backup Type", self.getParam("backup_type")) + continueWithBackup = True if not self.noConfirm: print() @@ -365,3 +383,82 @@ def promptForUploadConfiguration(self) -> None: self.setParam("artifactory_repository", artifactoryRepository) else: self.setParam("upload_backup", "false") + + def promptForManageAppBackup(self) -> None: + """Prompt user for Manage application backup configuration""" + self.printH1("Manage Application Backup") + self.printDescription([ + "In addition to backing up the MAS Suite, you can also backup the Manage application.", + "This includes the Manage namespace resources and persistent volume data." + ]) + + backupManageApp = self.yesOrNo("Do you want to backup the Manage application") + + if backupManageApp: + self.setParam("backup_manage_app", "true") + self.setParam("mas_app_id", "manage") + + # Get workspace ID - try to auto-detect first + try: + instanceId = self.getParam("mas_instance_id") + workspaceId = getWorkspaceId(self.dynamicClient, instanceId) + if workspaceId: + self.printDescription([f"Detected Manage workspace: {workspaceId}"]) + useDetected = self.yesOrNo("Use this workspace") + if useDetected: + self.setParam("mas_workspace_id", workspaceId) + else: + workspaceId = self.promptForString("Enter Manage workspace ID") + self.setParam("mas_workspace_id", workspaceId) + else: + workspaceId = self.promptForString("Enter Manage workspace ID") + self.setParam("mas_workspace_id", workspaceId) + except Exception: + workspaceId = self.promptForString("Enter Manage workspace ID") + self.setParam("mas_workspace_id", workspaceId) + + # Ask about DB2 backup + self.printH2("Manage Database Backup") + self.printDescription([ + "The Manage application uses a Db2 database that should also be backed up.", + "This will backup the incluster Db2 database associated with the Manage workspace." + ]) + backupDb2 = self.yesOrNo("Do you want to backup the Manage database (Db2)") + + if backupDb2: + self.setParam("backup_manage_db", "true") + self.promptForDb2BackupConfiguration() + else: + self.setParam("backup_manage_db", "false") + else: + self.setParam("backup_manage_app", "false") + self.setParam("backup_manage_db", "false") + + def promptForDb2BackupConfiguration(self) -> None: + """Prompt user for Db2 backup configuration - reusable for any app that uses Db2""" + self.printH2("Db2 Configuration") + + # DB2 namespace + db2Namespace = self.promptForString("Enter Db2 namespace", default="db2u") + self.setParam("db2_namespace", db2Namespace) + + # DB2 instance name + db2InstanceName = self.promptForString("Enter Db2 instance name") + self.setParam("db2_instance_name", db2InstanceName) + + # Backup type + self.printDescription([ + "Db2 backup can be performed online (database remains available) or offline (database unavailable during backup).", + "Note: If your Db2 instance uses circular logging (default), you must use offline backup." + ]) + backupType = self.promptForListSelect( + "Select backup type", + ["online", "offline"], + "backup_type", + default=1 + ) + self.setParam("backup_type", backupType) + + # Set backup version to match main backup version + if self.getParam("backup_version"): + self.setParam("db2_backup_version", self.getParam("backup_version")) diff --git a/tekton/generate-tekton-tasks.yml b/tekton/generate-tekton-tasks.yml index b07f303abb4..a9bb0113138 100644 --- a/tekton/generate-tekton-tasks.yml +++ b/tekton/generate-tekton-tasks.yml @@ -136,8 +136,10 @@ dest: "{{ task_target_dir }}/{{ item }}.yaml" with_items: - clean-workspaces + - download-backup-archive - gencfg-workspace - must-gather + - suite-app-backup - suite-app-install - suite-app-uninstall - suite-app-upgrade @@ -155,7 +157,6 @@ - suite-upgrade - suite-verify - upload-backup-archive - - download-backup-archive # 7. Generate Tasks (OCP) # ------------------------------------------------------------------------- diff --git a/tekton/src/params/backup.yml.j2 b/tekton/src/params/backup.yml.j2 index b3e5418f3c5..325b289cdef 100644 --- a/tekton/src/params/backup.yml.j2 +++ b/tekton/src/params/backup.yml.j2 @@ -219,4 +219,83 @@ - name: mas_config_dir type: string default: "" - description: Directory for MAS configuration files during restore \ No newline at end of file + description: Directory for MAS configuration files during restore + +# Manage Application Backup Configuration +# ----------------------------------------------------------------------------- +- name: backup_manage_app + type: string + description: Whether to backup the Manage application (true/false) + default: "false" + +- name: backup_manage_db + type: string + description: Whether to backup the Manage database (Db2) (true/false) + default: "false" + +- name: mas_app_id + type: string + description: MAS application ID (e.g., manage) + default: "" + +- name: mas_workspace_id + type: string + description: MAS workspace ID for application backup + default: "" + +- name: mas_app_backup_version + type: string + description: Version/timestamp for the MAS app backup (defaults to backup_version if not provided) + default: "" + +# Db2 Backup Configuration +# ----------------------------------------------------------------------------- +- name: db2_namespace + type: string + description: Db2 namespace for backup + default: "" + +- name: db2_instance_name + type: string + description: Db2 instance name for backup + default: "" + +- name: db2_action + type: string + description: Action to perform for Db2 (backup) + default: "backup" + +- name: db2_backup_version + type: string + description: Version/timestamp for the Db2 backup (defaults to backup_version if not provided) + default: "" + +- name: backup_type + type: string + description: Type of Db2 backup (online or offline) + default: "online" + +- name: backup_vendor + type: string + description: Storage backend for Db2 backup files (disk or s3) + default: "disk" + +- name: backup_s3_endpoint + type: string + description: S3 endpoint URL for Db2 backups + default: "" + +- name: backup_s3_bucket + type: string + description: S3 bucket name for Db2 backups + default: "" + +- name: backup_s3_access_key + type: string + description: S3 access key for Db2 backups + default: "" + +- name: backup_s3_secret_key + type: string + description: S3 secret key for Db2 backups + default: "" \ No newline at end of file diff --git a/tekton/src/pipelines/mas-backup.yml.j2 b/tekton/src/pipelines/mas-backup.yml.j2 index 097a1454603..aae21028771 100644 --- a/tekton/src/pipelines/mas-backup.yml.j2 +++ b/tekton/src/pipelines/mas-backup.yml.j2 @@ -29,6 +29,8 @@ spec: # 5. Backup MongoDB # 6. Backup SLS # 7. Backup MAS Suite + # 8. Backup Manage Database (Db2) - Optional + # 9. Backup Manage Application - Optional # 1. Pipeline Start # ------------------------------------------------------------------------- @@ -224,7 +226,89 @@ spec: - mongodb - sls - # 8. Upload Backup Archive (Optional) + # 8. Backup Manage Database (Db2) - Optional + # ------------------------------------------------------------------------- + - name: manage-db2-backup + timeout: "0" + when: + - input: "$(params.backup_manage_db)" + operator: in + values: ["true", "True"] + params: + {{ lookup('template', pipeline_src_dir ~ '/taskdefs/common/cli-params.yml.j2') | indent(8) }} + + - name: mas_instance_id + value: $(params.mas_instance_id) + + - name: db2_namespace + value: $(params.db2_namespace) + - name: db2_instance_name + value: $(params.db2_instance_name) + - name: db2_action + value: backup + + # Backup specific parameters + - name: db2_backup_version + value: $(params.db2_backup_version) + - name: backup_type + value: $(params.backup_type) + - name: backup_vendor + value: $(params.backup_vendor) + - name: backup_s3_endpoint + value: $(params.backup_s3_endpoint) + - name: backup_s3_bucket + value: $(params.backup_s3_bucket) + - name: backup_s3_access_key + value: $(params.backup_s3_access_key) + - name: backup_s3_secret_key + value: $(params.backup_s3_secret_key) + + taskRef: + kind: Task + name: mas-devops-db2 + workspaces: + - name: configs + workspace: shared-configs + - name: backups + workspace: shared-backups + runAfter: + - suite-backup + + # 9. Backup Manage Application - Optional + # ------------------------------------------------------------------------- + - name: manage-app-backup + timeout: "0" + when: + - input: "$(params.backup_manage_app)" + operator: in + values: ["true", "True"] + params: + {{ lookup('template', pipeline_src_dir ~ '/taskdefs/common/cli-params.yml.j2') | indent(8) }} + + - name: mas_instance_id + value: $(params.mas_instance_id) + - name: mas_workspace_id + value: $(params.mas_workspace_id) + - name: mas_app_id + value: $(params.mas_app_id) + + - name: mas_backup_dir + value: /workspace/backups + - name: mas_app_backup_version + value: $(params.mas_app_backup_version) + + taskRef: + kind: Task + name: mas-devops-suite-app-backup + workspaces: + - name: configs + workspace: shared-configs + - name: backups + workspace: shared-backups + runAfter: + - suite-backup + + # 10. Upload Backup Archive (Optional) # ------------------------------------------------------------------------- - name: upload-backup-archive timeout: "0" @@ -266,6 +350,8 @@ spec: workspace: shared-backups runAfter: - suite-backup + - manage-db2-backup + - manage-app-backup finally: # 1. Clean Backup Workspaces (Optional) diff --git a/tekton/src/tasks/dependencies/db2.yml.j2 b/tekton/src/tasks/dependencies/db2.yml.j2 index e4c2fc3783c..2bccc56b840 100644 --- a/tekton/src/tasks/dependencies/db2.yml.j2 +++ b/tekton/src/tasks/dependencies/db2.yml.j2 @@ -165,6 +165,40 @@ spec: description: Optional MAS custom labels, comma separated list of key=value pairs default: "" + # Backup/Restore specific parameters + - name: db2_backup_version + type: string + description: Optional. Version/timestamp for the backup + default: "" + - name: mas_backup_dir + type: string + description: Directory to store backup files + default: "" + - name: backup_type + type: string + description: Type of backup (online or offline) + default: "" + - name: backup_vendor + type: string + description: Storage backend for database backup files (disk or s3) + default: "" + - name: backup_s3_endpoint + type: string + description: S3 endpoint URL for backups + default: "" + - name: backup_s3_bucket + type: string + description: S3 bucket name for backups + default: "" + - name: backup_s3_access_key + type: string + description: S3 access key for backups + default: "" + - name: backup_s3_secret_key + type: string + description: S3 secret key for backups + default: "" + stepTemplate: env: {{ lookup('template', task_src_dir ~ '/common/cli-env.yml.j2') | indent(6) }} @@ -280,6 +314,24 @@ spec: # Custom labels support - name: CUSTOM_LABELS value: $(params.custom_labels) + + # Backup/Restore specific + - name: MAS_BACKUP_DIR + value: /workspace/backups + - name: DB2_BACKUP_VERSION + value: $(params.db2_backup_version) + - name: BACKUP_TYPE + value: $(params.backup_type) + - name: BACKUP_VENDOR + value: $(params.backup_vendor) + - name: BACKUP_S3_ENDPOINT + value: $(params.backup_s3_endpoint) + - name: BACKUP_S3_BUCKET + value: $(params.backup_s3_bucket) + - name: BACKUP_S3_ACCESS_KEY + value: $(params.backup_s3_access_key) + - name: BACKUP_S3_SECRET_KEY + value: $(params.backup_s3_secret_key) steps: - name: db2 command: @@ -292,3 +344,5 @@ spec: workspaces: - name: configs optional: true + - name: backups + optional: true diff --git a/tekton/src/tasks/suite-app-backup.yml.j2 b/tekton/src/tasks/suite-app-backup.yml.j2 new file mode 100644 index 00000000000..41104416cd1 --- /dev/null +++ b/tekton/src/tasks/suite-app-backup.yml.j2 @@ -0,0 +1,67 @@ +--- +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: mas-devops-suite-app-backup +spec: + params: + {{ lookup('template', task_src_dir ~ '/common/cli-params.yml.j2') | indent(4) }} + + - name: mas_instance_id + type: string + description: Instance ID + + - name: mas_workspace_id + type: string + description: Workspace ID + default: "" + + - name: mas_app_id + type: string + description: Application ID (e.g., manage) + default: "" + + # Backup specific parameters + - name: mas_backup_dir + type: string + description: Directory to store backup files + default: "" + + - name: mas_app_backup_version + type: string + description: Version/timestamp for the MAS app backup + default: "" + + stepTemplate: + env: + {{ lookup('template', task_src_dir ~ '/common/cli-env.yml.j2') | indent(6) }} + + - name: MAS_INSTANCE_ID + value: $(params.mas_instance_id) + + - name: MAS_WORKSPACE_ID + value: $(params.mas_workspace_id) + + - name: MAS_APP_ID + value: $(params.mas_app_id) + + # Backup specific + - name: MAS_BACKUP_DIR + value: /workspace/backups + + - name: MAS_APP_BACKUP_VERSION + value: $(params.mas_app_backup_version) + + steps: + - name: suite-app-backup + command: + - /opt/app-root/src/run-role.sh + - suite_app_backup + image: quay.io/ibmmas/cli:latest + imagePullPolicy: $(params.image_pull_policy) + workingDir: /workspace/configs + + workspaces: + - name: configs + optional: true + - name: backups \ No newline at end of file From bee4d918225b9d4fbcb318d794dbffeae37a4c7f Mon Sep 17 00:00:00 2001 From: whitfiea Date: Thu, 5 Feb 2026 14:33:15 +0000 Subject: [PATCH 02/12] fix naming --- python/src/mas/cli/backup/app.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/python/src/mas/cli/backup/app.py b/python/src/mas/cli/backup/app.py index f60c258feba..9ec2797ac69 100644 --- a/python/src/mas/cli/backup/app.py +++ b/python/src/mas/cli/backup/app.py @@ -337,6 +337,8 @@ def promptForUploadConfiguration(self) -> None: if self.devMode: self.printDescription([ "Development mode is enabled. Choose upload destination:" + " 1. S3", + " 2. Artifactory", ]) uploadDestination = self.promptForListSelect( "Select upload destination", @@ -443,18 +445,24 @@ def promptForDb2BackupConfiguration(self) -> None: self.setParam("db2_namespace", db2Namespace) # DB2 instance name - db2InstanceName = self.promptForString("Enter Db2 instance name") + instanceId = self.getParam("mas_instance_id") + workspaceID = self.getParam("mas_workspace_id") + appId = self.getParam("mas_app_id") + db2InstanceName = self.promptForString("Enter Db2 instance name", default=f"mas-{instanceId}-{workspaceID}-{appId}") self.setParam("db2_instance_name", db2InstanceName) # Backup type self.printDescription([ "Db2 backup can be performed online (database remains available) or offline (database unavailable during backup).", "Note: If your Db2 instance uses circular logging (default), you must use offline backup." + "Backup Types:" + " 1. online", + " 2. offline", ]) backupType = self.promptForListSelect( - "Select backup type", - ["online", "offline"], - "backup_type", + message="Select backup type", + options=["online", "offline"], + param="backup_type", default=1 ) self.setParam("backup_type", backupType) From b3a10ab8973d29e07dc22f8000c1a5642a343de7 Mon Sep 17 00:00:00 2001 From: whitfiea Date: Thu, 5 Feb 2026 14:57:42 +0000 Subject: [PATCH 03/12] fix backup_type --- python/src/mas/cli/backup/app.py | 13 +++++++------ tekton/src/tasks/suite-app-backup.yml.j2 | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/python/src/mas/cli/backup/app.py b/python/src/mas/cli/backup/app.py index 9ec2797ac69..ec2009db7f7 100644 --- a/python/src/mas/cli/backup/app.py +++ b/python/src/mas/cli/backup/app.py @@ -10,7 +10,6 @@ # ***************************************************************************** import logging -import logging.handlers from datetime import datetime from halo import Halo from prompt_toolkit import print_formatted_text, HTML @@ -336,7 +335,7 @@ def promptForUploadConfiguration(self) -> None: # Determine upload destination based on dev_mode if self.devMode: self.printDescription([ - "Development mode is enabled. Choose upload destination:" + "Development mode is enabled. Choose upload destination:", " 1. S3", " 2. Artifactory", ]) @@ -454,18 +453,20 @@ def promptForDb2BackupConfiguration(self) -> None: # Backup type self.printDescription([ "Db2 backup can be performed online (database remains available) or offline (database unavailable during backup).", - "Note: If your Db2 instance uses circular logging (default), you must use offline backup." - "Backup Types:" + "Note: If your Db2 instance uses circular logging (default), you must use offline backup.", + "Backup Types:", " 1. online", " 2. offline", ]) - backupType = self.promptForListSelect( + self.promptForListSelect( message="Select backup type", options=["online", "offline"], param="backup_type", default=1 ) - self.setParam("backup_type", backupType) + + # Always set to local for pipeline as s3 upload is handled for the whole pipeline + self.setParam("backup_vendor", "local") # Set backup version to match main backup version if self.getParam("backup_version"): diff --git a/tekton/src/tasks/suite-app-backup.yml.j2 b/tekton/src/tasks/suite-app-backup.yml.j2 index 41104416cd1..deccfa86b73 100644 --- a/tekton/src/tasks/suite-app-backup.yml.j2 +++ b/tekton/src/tasks/suite-app-backup.yml.j2 @@ -1,4 +1,4 @@ ---- + --- apiVersion: tekton.dev/v1beta1 kind: Task metadata: @@ -64,4 +64,4 @@ spec: workspaces: - name: configs optional: true - - name: backups \ No newline at end of file + - name: backups From 38ee28e3b41d49d0e58ca2944015875ae26a4b5a Mon Sep 17 00:00:00 2001 From: whitfiea Date: Thu, 5 Feb 2026 15:15:28 +0000 Subject: [PATCH 04/12] fix task --- tekton/src/tasks/suite-app-backup.yml.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tekton/src/tasks/suite-app-backup.yml.j2 b/tekton/src/tasks/suite-app-backup.yml.j2 index deccfa86b73..aeffe678651 100644 --- a/tekton/src/tasks/suite-app-backup.yml.j2 +++ b/tekton/src/tasks/suite-app-backup.yml.j2 @@ -1,4 +1,4 @@ - --- +--- apiVersion: tekton.dev/v1beta1 kind: Task metadata: From ad63636ae2edd0b80d9af73120e0aa8bd63870ed Mon Sep 17 00:00:00 2001 From: whitfiea Date: Thu, 5 Feb 2026 16:31:39 +0000 Subject: [PATCH 05/12] fix backup_vendor value --- python/src/mas/cli/backup/app.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/src/mas/cli/backup/app.py b/python/src/mas/cli/backup/app.py index ec2009db7f7..c06113b62e7 100644 --- a/python/src/mas/cli/backup/app.py +++ b/python/src/mas/cli/backup/app.py @@ -465,8 +465,8 @@ def promptForDb2BackupConfiguration(self) -> None: default=1 ) - # Always set to local for pipeline as s3 upload is handled for the whole pipeline - self.setParam("backup_vendor", "local") + # Always set to disk for pipeline as s3 upload is handled for the whole pipeline + self.setParam("backup_vendor", "disk") # Set backup version to match main backup version if self.getParam("backup_version"): From ffa95fabfa5d497c448f7a1a6b6648274b2ab67e Mon Sep 17 00:00:00 2001 From: whitfiea Date: Thu, 5 Feb 2026 17:01:44 +0000 Subject: [PATCH 06/12] fix tekton defs --- python/src/mas/cli/backup/app.py | 4 ---- tekton/src/params/backup.yml.j2 | 10 ---------- tekton/src/pipelines/mas-backup.yml.j2 | 14 ++------------ .../taskdefs/backup-restore/backup-params.yml.j2 | 2 -- tekton/src/tasks/suite-backup.yml.j2 | 4 ++-- 5 files changed, 4 insertions(+), 30 deletions(-) delete mode 100644 tekton/src/pipelines/taskdefs/backup-restore/backup-params.yml.j2 diff --git a/python/src/mas/cli/backup/app.py b/python/src/mas/cli/backup/app.py index c06113b62e7..a0f3cb8a2ac 100644 --- a/python/src/mas/cli/backup/app.py +++ b/python/src/mas/cli/backup/app.py @@ -467,7 +467,3 @@ def promptForDb2BackupConfiguration(self) -> None: # Always set to disk for pipeline as s3 upload is handled for the whole pipeline self.setParam("backup_vendor", "disk") - - # Set backup version to match main backup version - if self.getParam("backup_version"): - self.setParam("db2_backup_version", self.getParam("backup_version")) diff --git a/tekton/src/params/backup.yml.j2 b/tekton/src/params/backup.yml.j2 index 325b289cdef..4d9335d7cc6 100644 --- a/tekton/src/params/backup.yml.j2 +++ b/tekton/src/params/backup.yml.j2 @@ -243,11 +243,6 @@ description: MAS workspace ID for application backup default: "" -- name: mas_app_backup_version - type: string - description: Version/timestamp for the MAS app backup (defaults to backup_version if not provided) - default: "" - # Db2 Backup Configuration # ----------------------------------------------------------------------------- - name: db2_namespace @@ -265,11 +260,6 @@ description: Action to perform for Db2 (backup) default: "backup" -- name: db2_backup_version - type: string - description: Version/timestamp for the Db2 backup (defaults to backup_version if not provided) - default: "" - - name: backup_type type: string description: Type of Db2 backup (online or offline) diff --git a/tekton/src/pipelines/mas-backup.yml.j2 b/tekton/src/pipelines/mas-backup.yml.j2 index aae21028771..28773fc1319 100644 --- a/tekton/src/pipelines/mas-backup.yml.j2 +++ b/tekton/src/pipelines/mas-backup.yml.j2 @@ -64,8 +64,6 @@ spec: params: {{ lookup('template', pipeline_src_dir ~ '/taskdefs/common/cli-params.yml.j2') | indent(8) }} - {{ lookup('template', pipeline_src_dir ~ '/taskdefs/backup-restore/backup-params.yml.j2') | indent(8) }} - - name: devops_suite_name value: backup-ibm-catalogs @@ -95,8 +93,6 @@ spec: params: {{ lookup('template', pipeline_src_dir ~ '/taskdefs/common/cli-params.yml.j2') | indent(8) }} - {{ lookup('template', pipeline_src_dir ~ '/taskdefs/backup-restore/backup-params.yml.j2') | indent(8) }} - - name: devops_suite_name value: backup-cert-manager @@ -124,8 +120,6 @@ spec: params: {{ lookup('template', pipeline_src_dir ~ '/taskdefs/common/cli-params.yml.j2') | indent(8) }} - {{ lookup('template', pipeline_src_dir ~ '/taskdefs/backup-restore/backup-params.yml.j2') | indent(8) }} - - name: devops_suite_name value: backup-mongodb @@ -162,8 +156,6 @@ spec: params: {{ lookup('template', pipeline_src_dir ~ '/taskdefs/common/cli-params.yml.j2') | indent(8) }} - {{ lookup('template', pipeline_src_dir ~ '/taskdefs/backup-restore/backup-params.yml.j2') | indent(8) }} - - name: mas_instance_id value: $(params.mas_instance_id) @@ -201,8 +193,6 @@ spec: params: {{ lookup('template', pipeline_src_dir ~ '/taskdefs/common/cli-params.yml.j2') | indent(8) }} - {{ lookup('template', pipeline_src_dir ~ '/taskdefs/backup-restore/backup-params.yml.j2') | indent(8) }} - - name: mas_instance_id value: $(params.mas_instance_id) @@ -249,7 +239,7 @@ spec: # Backup specific parameters - name: db2_backup_version - value: $(params.db2_backup_version) + value: $(params.backup_version) - name: backup_type value: $(params.backup_type) - name: backup_vendor @@ -295,7 +285,7 @@ spec: - name: mas_backup_dir value: /workspace/backups - name: mas_app_backup_version - value: $(params.mas_app_backup_version) + value: $(params.backup_version) taskRef: kind: Task diff --git a/tekton/src/pipelines/taskdefs/backup-restore/backup-params.yml.j2 b/tekton/src/pipelines/taskdefs/backup-restore/backup-params.yml.j2 deleted file mode 100644 index 079f5606193..00000000000 --- a/tekton/src/pipelines/taskdefs/backup-restore/backup-params.yml.j2 +++ /dev/null @@ -1,2 +0,0 @@ -- name: backup_version - value: $(params.backup_version) \ No newline at end of file diff --git a/tekton/src/tasks/suite-backup.yml.j2 b/tekton/src/tasks/suite-backup.yml.j2 index 936e1b84f82..19b07c5efc0 100644 --- a/tekton/src/tasks/suite-backup.yml.j2 +++ b/tekton/src/tasks/suite-backup.yml.j2 @@ -16,7 +16,7 @@ spec: type: string description: Directory to store backup files default: "" - - name: backup_version + - name: suite_backup_version type: string description: Version/timestamp for the backup default: "" @@ -34,7 +34,7 @@ spec: - name: MAS_BACKUP_DIR value: /workspace/backups - name: SUITE_BACKUP_VERSION - value: $(params.backup_version) + value: $(params.suite_backup_version) steps: - name: suite-backup From 2570ee04e486077ecdc10b6b63d4247e1291a5c1 Mon Sep 17 00:00:00 2001 From: whitfiea Date: Thu, 5 Feb 2026 17:55:59 +0000 Subject: [PATCH 07/12] set correct db2_backup_type env var --- tekton/src/tasks/dependencies/db2.yml.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tekton/src/tasks/dependencies/db2.yml.j2 b/tekton/src/tasks/dependencies/db2.yml.j2 index 2bccc56b840..d93299af212 100644 --- a/tekton/src/tasks/dependencies/db2.yml.j2 +++ b/tekton/src/tasks/dependencies/db2.yml.j2 @@ -320,7 +320,7 @@ spec: value: /workspace/backups - name: DB2_BACKUP_VERSION value: $(params.db2_backup_version) - - name: BACKUP_TYPE + - name: DB2_BACKUP_TYPE value: $(params.backup_type) - name: BACKUP_VENDOR value: $(params.backup_vendor) From 3b2cd29409348feeee7cde996140b77a0c52dbc3 Mon Sep 17 00:00:00 2001 From: whitfiea Date: Fri, 6 Feb 2026 08:39:40 +0000 Subject: [PATCH 08/12] conform to one timestamp --- docs/commands/restore.md | 30 +++++++++++++++--------------- docs/guides/backup-restore.md | 24 ++++++++++++------------ python/src/mas/cli/restore/app.py | 2 +- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/commands/restore.md b/docs/commands/restore.md index 22ecb851c0b..533a785de0e 100644 --- a/docs/commands/restore.md +++ b/docs/commands/restore.md @@ -122,14 +122,14 @@ mas restore Restore a specific MAS instance from a backup with default settings: ```bash -mas restore --instance-id inst1 --restore-version 20260117-191701 --no-confirm +mas restore --instance-id inst1 --restore-version 2020260117-191701 --no-confirm ``` ### Restore with Custom Storage Size Specify a custom storage size for the restore PVC: ```bash -mas restore --instance-id inst1 --restore-version 20260117-191701 --backup-storage-size 50Gi --no-confirm +mas restore --instance-id inst1 --restore-version 2020260117-191701 --backup-storage-size 50Gi --no-confirm ``` ### Restore with Changed MAS Domain @@ -138,7 +138,7 @@ Restore a backup and change the MAS domain in the Suite CR: ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --mas-domain-restore new.domain.com \ --no-confirm ``` @@ -149,7 +149,7 @@ Download a backup from S3 and restore it: ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --download-backup \ --aws-access-key-id AKIAIOSFODNN7EXAMPLE \ #pragma: allowlist secret --aws-secret-access-key wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY \ #pragma: allowlist secret @@ -164,7 +164,7 @@ Download and restore a backup with a custom archive name: ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --download-backup \ --custom-backup-archive-name custom-backup-name.tar.gz \ --aws-access-key-id AKIAIOSFODNN7EXAMPLE \ #pragma: allowlist secret @@ -180,7 +180,7 @@ Restore a backup without including Suite License Service (useful when using exte ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --exclude-sls \ --no-confirm ``` @@ -191,7 +191,7 @@ Restore using a custom SLS configuration file instead of the one from backup: ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --exclude-slscfg-from-backup \ --sls-cfg-file /path/to/sls-config.yaml \ --no-confirm @@ -203,7 +203,7 @@ Restore SLS configuration from backup but change the SLS URL: ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --include-slscfg-from-backup \ --sls-url-restore https://new-sls-url.com \ --no-confirm @@ -215,7 +215,7 @@ Restore using a custom DRO/BAS configuration file instead of the one from backup ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --exclude-drocfg-from-backup \ --dro-cfg-file /path/to/dro-config.yaml \ --no-confirm @@ -227,7 +227,7 @@ Restore and install a new DRO instance: ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --include-dro \ --ibm-entitlement-key YOUR_ENTITLEMENT_KEY \ #pragma: allowlist secret --contact-email admin@example.com \ @@ -243,7 +243,7 @@ Restore SLS instance with a custom domain: ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --include-sls \ --sls-domain custom-sls.domain.com \ --no-confirm @@ -255,7 +255,7 @@ Restore without installing Grafana: ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --exclude-grafana \ --no-confirm ``` @@ -264,14 +264,14 @@ mas restore \ Skip the pre-restore validation check (use with caution): ```bash -mas restore --instance-id inst1 --restore-version 20260117-191701 --skip-pre-check --no-confirm +mas restore --instance-id inst1 --restore-version 2020260117-191701 --skip-pre-check --no-confirm ``` ### Restore Without Workspace Cleanup Keep backup and config workspace contents after completion (useful for troubleshooting): ```bash -mas restore --instance-id inst1 --restore-version 20260117-191701 --no-clean-backup --no-confirm +mas restore --instance-id inst1 --restore-version 2020260117-191701 --no-clean-backup --no-confirm ``` !!! note @@ -283,7 +283,7 @@ A comprehensive example with all major options configured: ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --backup-storage-size 100Gi \ --mas-domain-restore new.domain.com \ --include-sls \ diff --git a/docs/guides/backup-restore.md b/docs/guides/backup-restore.md index 33a038c14ee..da447aa6997 100644 --- a/docs/guides/backup-restore.md +++ b/docs/guides/backup-restore.md @@ -578,7 +578,7 @@ Non-interactive mode is ideal for automation, scheduled restores, and CI/CD pipe ```bash docker run -ti --rm quay.io/ibmmas/cli mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --no-confirm ``` @@ -614,7 +614,7 @@ After launching the restore, a URL to the Tekton PipelineRun is displayed: ``` View progress: - https://console-openshift-console.apps.cluster.example.com/k8s/ns/mas-inst1-pipelines/tekton.dev~v1beta1~PipelineRun/mas-restore-20260117-191701-YYMMDD-HHMM + https://console-openshift-console.apps.cluster.example.com/k8s/ns/mas-inst1-pipelines/tekton.dev~v1beta1~PipelineRun/mas-restore-2020260117-191701-YYMMDD-HHMM ``` Use this URL to: @@ -656,7 +656,7 @@ Restore Scenarios - Non-Interactive Mode ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --no-confirm ``` @@ -670,7 +670,7 @@ mas restore \ ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --download-backup \ --aws-access-key-id AKIAIOSFODNN7EXAMPLE \ #pragma: allowlist secret --aws-secret-access-key wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY \ #pragma: allowlist secret @@ -689,7 +689,7 @@ mas restore \ ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --mas-domain-restore new-cluster.example.com \ --no-confirm ``` @@ -704,7 +704,7 @@ mas restore \ ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --exclude-sls \ --exclude-slscfg-from-backup \ --sls-cfg-file /path/to/custom-sls-config.yaml \ @@ -721,7 +721,7 @@ mas restore \ ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --include-sls \ --include-slscfg-from-backup \ --sls-url-restore https://new-sls.example.com \ @@ -738,7 +738,7 @@ mas restore \ ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --include-dro \ --ibm-entitlement-key YOUR_ENTITLEMENT_KEY \ #pragma: allowlist secret --contact-email admin@example.com \ @@ -758,7 +758,7 @@ mas restore \ ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --exclude-grafana \ --no-confirm ``` @@ -775,7 +775,7 @@ mas restore \ ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --backup-storage-size 100Gi \ --mas-domain-restore new-cluster.example.com \ --include-sls \ @@ -808,7 +808,7 @@ mas restore \ ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --no-clean-backup \ --no-confirm ``` @@ -826,7 +826,7 @@ mas restore \ ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --skip-pre-check \ --no-confirm ``` diff --git a/python/src/mas/cli/restore/app.py b/python/src/mas/cli/restore/app.py index e123da8bf7b..2c247b36156 100644 --- a/python/src/mas/cli/restore/app.py +++ b/python/src/mas/cli/restore/app.py @@ -350,7 +350,7 @@ def promptForBackupStorageSize(self) -> None: def promptForBackupVersion(self) -> None: self.printH1("Backup Version Configuration") # Prompt user to enter custom backup version - restore_version = self.promptForString("Set the backup version to use for this restore operation. (e.g. 20260117-191701)") + restore_version = self.promptForString("Set the backup version to use for this restore operation. (e.g. 2020260117-191701)") self.setParam("restore_version", restore_version) def setDefaultParams(self) -> None: From 9484567d9077daafa1981fc6a7eb5ff5659d33ed Mon Sep 17 00:00:00 2001 From: whitfiea Date: Fri, 6 Feb 2026 09:54:47 +0000 Subject: [PATCH 09/12] update db2 backup order --- tekton/src/pipelines/mas-backup.yml.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tekton/src/pipelines/mas-backup.yml.j2 b/tekton/src/pipelines/mas-backup.yml.j2 index 28773fc1319..df29400ee12 100644 --- a/tekton/src/pipelines/mas-backup.yml.j2 +++ b/tekton/src/pipelines/mas-backup.yml.j2 @@ -262,7 +262,7 @@ spec: - name: backups workspace: shared-backups runAfter: - - suite-backup + - pre-backup-check # 9. Backup Manage Application - Optional # ------------------------------------------------------------------------- From 7d51dedf4dc220f79fd5db82f107b396021c3374 Mon Sep 17 00:00:00 2001 From: whitfiea Date: Fri, 6 Feb 2026 09:57:42 +0000 Subject: [PATCH 10/12] change db2 backup type default --- python/src/mas/cli/backup/app.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/src/mas/cli/backup/app.py b/python/src/mas/cli/backup/app.py index a0f3cb8a2ac..7ccc0a55abf 100644 --- a/python/src/mas/cli/backup/app.py +++ b/python/src/mas/cli/backup/app.py @@ -455,12 +455,12 @@ def promptForDb2BackupConfiguration(self) -> None: "Db2 backup can be performed online (database remains available) or offline (database unavailable during backup).", "Note: If your Db2 instance uses circular logging (default), you must use offline backup.", "Backup Types:", - " 1. online", - " 2. offline", + " 1. offline", + " 2. online", ]) self.promptForListSelect( message="Select backup type", - options=["online", "offline"], + options=["offline", "online"], param="backup_type", default=1 ) From 7be0b214b44abdb1c57265389e3f11de69eca437 Mon Sep 17 00:00:00 2001 From: whitfiea Date: Fri, 6 Feb 2026 13:09:01 +0000 Subject: [PATCH 11/12] changes to var names --- docs/commands/backup.md | 59 ++++++++++++++++++++++++-- docs/guides/backup-restore.md | 3 ++ python/src/mas/cli/backup/app.py | 47 +++++++++++--------- python/src/mas/cli/backup/argParser.py | 46 ++++++++++++++++++++ tekton/src/params/backup.yml.j2 | 32 +++++--------- tekton/src/pipelines/mas-backup.yml.j2 | 12 +++--- 6 files changed, 148 insertions(+), 51 deletions(-) diff --git a/docs/commands/backup.md b/docs/commands/backup.md index abeb626d75e..21cba28762e 100644 --- a/docs/commands/backup.md +++ b/docs/commands/backup.md @@ -9,8 +9,11 @@ Usage information can be obtained using `mas backup --help` usage: mas backup [-i MAS_INSTANCE_ID] [--backup-version BACKUP_VERSION] [--backup-storage-size BACKUP_STORAGE_SIZE] [--clean-backup] [--no-clean-backup] [--upload-backup] [--aws-access-key-id AWS_ACCESS_KEY_ID] [--aws-secret-access-key AWS_SECRET_ACCESS_KEY] [--s3-bucket-name S3_BUCKET_NAME] [--s3-region S3_REGION] - [--artifactory-url ARTIFACTORY_URL] [--artifactory-repository ARTIFACTORY_REPOSITORY] [--include-sls] - [--exclude-sls] [--mongodb-namespace MONGODB_NAMESPACE] [--mongodb-instance-name MONGODB_INSTANCE_NAME] + [--artifactory-url ARTIFACTORY_URL] [--artifactory-repository ARTIFACTORY_REPOSITORY] + [--backup-manage-app] [--manage-workspace-id MANAGE_WORKSPACE_ID] [--backup-manage-db] + [--manage-db2-namespace MANAGE_DB2_NAMESPACE] [--manage-db2-instance-name MANAGE_DB2_INSTANCE_NAME] + [--manage-db2-backup-type {offline,online}] [--include-sls] [--exclude-sls] + [--mongodb-namespace MONGODB_NAMESPACE] [--mongodb-instance-name MONGODB_INSTANCE_NAME] [--mongodb-provider {community}] [--sls-namespace SLS_NAMESPACE] [--cert-manager-provider {redhat,ibm}] [--artifactory-username ARTIFACTORY_USERNAME] [--artifactory-token ARTIFACTORY_TOKEN] [--dev-mode] [--no-confirm] [--skip-pre-check] [-h] @@ -48,6 +51,18 @@ Upload Configuration: --artifactory-repository ARTIFACTORY_REPOSITORY Artifactory repository for backup upload (dev-mode only) +Manage Application Backup: + --backup-manage-app Backup the Manage application + --manage-workspace-id MANAGE_WORKSPACE_ID + Manage workspace ID + --backup-manage-db Backup the Manage application database (Db2) + --manage-db2-namespace MANAGE_DB2_NAMESPACE + Manage Db2 namespace (default: db2u) + --manage-db2-instance-name MANAGE_DB2_INSTANCE_NAME + Manage Db2 instance name + --manage-db2-backup-type {offline,online} + Manage Db2 backup type: offline (database unavailable) or online (database remains available) + Components: --include-sls Include SLS in backup (default: true) --exclude-sls Exclude SLS from backup (use if SLS is external) @@ -189,6 +204,32 @@ mas backup \ --no-confirm ``` +### Backup with Manage Application +Backup MAS instance including the Manage application and its database: + +```bash +mas backup \ + --instance-id inst1 \ + --backup-manage-app \ + --manage-workspace-id masdev \ + --backup-manage-db \ + --manage-db2-namespace db2u \ + --manage-db2-instance-name mas-inst1-masdev-manage \ + --manage-db2-backup-type offline \ + --no-confirm +``` + +### Backup with Manage Application Only (No Database) +Backup the Manage application without backing up its database: + +```bash +mas backup \ + --instance-id inst1 \ + --backup-manage-app \ + --manage-workspace-id masdev \ + --no-confirm +``` + Notes ------------------------------------------------------------------------------- @@ -229,6 +270,17 @@ Two upload destinations are supported: - **S3**: Standard AWS S3 bucket upload (available in all modes) - **Artifactory**: Artifactory repository upload (requires `--dev-mode`) +### Manage Application Backup +The backup command can optionally include the Manage application and its Db2 database: + +- **Manage Application**: Backs up the Manage namespace resources and persistent volume data +- **Manage Database**: Backs up the Db2 database associated with the Manage workspace + - **Offline backup**: Database is unavailable during backup (required for circular logging) + - **Online backup**: Database remains available during backup (requires archive logging) + +!!! note + If your Db2 instance uses circular logging (default), you must use offline backup type. + ### Interactive Mode When running without `--instance-id`, the command enters interactive mode and will prompt for: @@ -237,7 +289,8 @@ When running without `--instance-id`, the command enters interactive mode and wi 3. Backup storage size 4. Backup version (or auto-generate) 5. Workspace cleanup preference -6. Upload configuration (optional) +6. Manage application backup configuration (optional) +7. Upload configuration (optional) #### Example Interactive Mode Output diff --git a/docs/guides/backup-restore.md b/docs/guides/backup-restore.md index da447aa6997..a6d59e4f007 100644 --- a/docs/guides/backup-restore.md +++ b/docs/guides/backup-restore.md @@ -35,6 +35,7 @@ The `mas backup` command launches a Tekton pipeline that executes the following - [`ibm.mas_devops.mongodb`](https://ibm-mas.github.io/ansible-devops/roles/mongodb/) - Backs up MongoDB Community Edition instance and database - [`ibm.mas_devops.sls`](https://ibm-mas.github.io/ansible-devops/roles/sls/) - Backs up Suite License Service data - [`ibm.mas_devops.suite_backup`](https://ibm-mas.github.io/ansible-devops/roles/suite_backup/) - Backs up MAS Core configuration +- [`ibm.mas_devops.suite_app_backup`](https://ibm-mas.github.io/ansible-devops/roles/suite_app_backup/) - Backs up MAS application resources and persistent volume data For detailed information about the underlying Ansible automation, see the [Backup and Restore Playbook Documentation](https://ibm-mas.github.io/ansible-devops/playbooks/backup-restore/). @@ -955,6 +956,8 @@ Additional Resources - [SLS Role](https://ibm-mas.github.io/ansible-devops/roles/sls/) - Suite License Service backup/restore - [Suite Backup Role](https://ibm-mas.github.io/ansible-devops/roles/suite_backup/) - MAS Core backup - [Suite Restore Role](https://ibm-mas.github.io/ansible-devops/roles/suite_restore/) - MAS Core restore +- [Suite App Backup Role](https://ibm-mas.github.io/ansible-devops/roles/suite_app_backup/) - MAS application backup (generic) +- [Db2 Role](https://ibm-mas.github.io/ansible-devops/roles/db2/) - Db2 database backup/restore - [Grafana Role](https://ibm-mas.github.io/ansible-devops/roles/grafana/) - Grafana installation - [DRO Role](https://ibm-mas.github.io/ansible-devops/roles/dro/) - Data Reporter Operator installation diff --git a/python/src/mas/cli/backup/app.py b/python/src/mas/cli/backup/app.py index 7ccc0a55abf..6e967cff593 100644 --- a/python/src/mas/cli/backup/app.py +++ b/python/src/mas/cli/backup/app.py @@ -71,10 +71,13 @@ def backup(self, argv): "artifactory_url", "artifactory_repository", # Manage App Backup - "mas_app_id", - "mas_workspace_id", + "manage_workspace_id", "backup_manage_app", - "backup_manage_db" + "backup_manage_db", + "manage_db2_namespace", + "manage_db2_instance_name", + "manage_db2_backup_type", + "manage_db2_backup_vendor" ] 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 @@ -166,12 +169,12 @@ def backup(self, argv): if self.getParam("backup_manage_app") == "true": self.printH2("Manage Application Backup") self.printSummary("Backup Manage App", "Yes") - self.printSummary("Workspace ID", self.getParam("mas_workspace_id")) + self.printSummary("Workspace ID", self.getParam("manage_workspace_id")) self.printSummary("Backup Manage incluster Db2 Database", "Yes" if self.getParam("backup_manage_db") == "true" else "No") if self.getParam("backup_manage_db") == "true": - self.printSummary("Db2 Namespace", self.getParam("db2_namespace")) - self.printSummary("Db2 Instance Name", self.getParam("db2_instance_name")) - self.printSummary("Db2 Backup Type", self.getParam("backup_type")) + self.printSummary("Db2 Namespace", self.getParam("manage_db2_namespace")) + self.printSummary("Db2 Instance Name", self.getParam("manage_db2_instance_name")) + self.printSummary("Db2 Backup Type", self.getParam("manage_db2_backup_type")) continueWithBackup = True if not self.noConfirm: @@ -397,7 +400,6 @@ def promptForManageAppBackup(self) -> None: if backupManageApp: self.setParam("backup_manage_app", "true") - self.setParam("mas_app_id", "manage") # Get workspace ID - try to auto-detect first try: @@ -407,16 +409,16 @@ def promptForManageAppBackup(self) -> None: self.printDescription([f"Detected Manage workspace: {workspaceId}"]) useDetected = self.yesOrNo("Use this workspace") if useDetected: - self.setParam("mas_workspace_id", workspaceId) + self.setParam("manage_workspace_id", workspaceId) else: workspaceId = self.promptForString("Enter Manage workspace ID") - self.setParam("mas_workspace_id", workspaceId) + self.setParam("manage_workspace_id", workspaceId) else: workspaceId = self.promptForString("Enter Manage workspace ID") - self.setParam("mas_workspace_id", workspaceId) + self.setParam("manage_workspace_id", workspaceId) except Exception: workspaceId = self.promptForString("Enter Manage workspace ID") - self.setParam("mas_workspace_id", workspaceId) + self.setParam("manage_workspace_id", workspaceId) # Ask about DB2 backup self.printH2("Manage Database Backup") @@ -428,27 +430,30 @@ def promptForManageAppBackup(self) -> None: if backupDb2: self.setParam("backup_manage_db", "true") - self.promptForDb2BackupConfiguration() + self.promptForDb2BackupConfiguration("manage") else: self.setParam("backup_manage_db", "false") else: self.setParam("backup_manage_app", "false") self.setParam("backup_manage_db", "false") - def promptForDb2BackupConfiguration(self) -> None: - """Prompt user for Db2 backup configuration - reusable for any app that uses Db2""" + def promptForDb2BackupConfiguration(self, appId: str) -> None: + """Prompt user for Db2 backup configuration - reusable for any app that uses Db2 + + Args: + appId: The application ID (e.g., 'manage', 'facilities') used to prefix parameter names + """ self.printH2("Db2 Configuration") # DB2 namespace db2Namespace = self.promptForString("Enter Db2 namespace", default="db2u") - self.setParam("db2_namespace", db2Namespace) + self.setParam(f"{appId}_db2_namespace", db2Namespace) # DB2 instance name instanceId = self.getParam("mas_instance_id") - workspaceID = self.getParam("mas_workspace_id") - appId = self.getParam("mas_app_id") + workspaceID = self.getParam(f"{appId}_workspace_id") db2InstanceName = self.promptForString("Enter Db2 instance name", default=f"mas-{instanceId}-{workspaceID}-{appId}") - self.setParam("db2_instance_name", db2InstanceName) + self.setParam(f"{appId}_db2_instance_name", db2InstanceName) # Backup type self.printDescription([ @@ -461,9 +466,9 @@ def promptForDb2BackupConfiguration(self) -> None: self.promptForListSelect( message="Select backup type", options=["offline", "online"], - param="backup_type", + param=f"{appId}_db2_backup_type", default=1 ) # Always set to disk for pipeline as s3 upload is handled for the whole pipeline - self.setParam("backup_vendor", "disk") + self.setParam(f"{appId}_db2_backup_vendor", "disk") diff --git a/python/src/mas/cli/backup/argParser.py b/python/src/mas/cli/backup/argParser.py index 374c4fa222d..8f6a9c9ddc5 100644 --- a/python/src/mas/cli/backup/argParser.py +++ b/python/src/mas/cli/backup/argParser.py @@ -111,6 +111,52 @@ help="Artifactory repository for backup upload" ) +manageAppArgGroup = backupArgParser.add_argument_group( + 'Manage Application Backup', + 'Configure backup of the Manage application and its database.' +) +manageAppArgGroup.add_argument( + '--backup-manage-app', + dest='backup_manage_app', + required=False, + action="store_const", + const="true", + help="Backup the Manage application" +) +manageAppArgGroup.add_argument( + '--manage-workspace-id', + dest='manage_workspace_id', + required=False, + help="Manage workspace ID" +) +manageAppArgGroup.add_argument( + '--backup-manage-db', + dest='backup_manage_db', + required=False, + action="store_const", + const="true", + help="Backup the Manage application database (Db2)" +) +manageAppArgGroup.add_argument( + '--manage-db2-namespace', + dest='manage_db2_namespace', + required=False, + help="Manage Db2 namespace (default: db2u)" +) +manageAppArgGroup.add_argument( + '--manage-db2-instance-name', + dest='manage_db2_instance_name', + required=False, + help="Manage Db2 instance name" +) +manageAppArgGroup.add_argument( + '--manage-db2-backup-type', + dest='manage_db2_backup_type', + required=False, + choices=["offline", "online"], + help="Manage Db2 backup type: offline (database unavailable) or online (database remains available)" +) + componentsArgGroup = backupArgParser.add_argument_group( 'Components', 'Configure which components to include in the backup.' diff --git a/tekton/src/params/backup.yml.j2 b/tekton/src/params/backup.yml.j2 index 4d9335d7cc6..f52d3150b3c 100644 --- a/tekton/src/params/backup.yml.j2 +++ b/tekton/src/params/backup.yml.j2 @@ -233,41 +233,31 @@ description: Whether to backup the Manage database (Db2) (true/false) default: "false" -- name: mas_app_id +- name: manage_workspace_id type: string - description: MAS application ID (e.g., manage) + description: Manage workspace ID for application backup default: "" -- name: mas_workspace_id - type: string - description: MAS workspace ID for application backup - default: "" - -# Db2 Backup Configuration +# Manage Db2 Backup Configuration # ----------------------------------------------------------------------------- -- name: db2_namespace +- name: manage_db2_namespace type: string - description: Db2 namespace for backup + description: Manage Db2 namespace for backup default: "" -- name: db2_instance_name +- name: manage_db2_instance_name type: string - description: Db2 instance name for backup + description: Manage Db2 instance name for backup default: "" -- name: db2_action - type: string - description: Action to perform for Db2 (backup) - default: "backup" - -- name: backup_type +- name: manage_db2_backup_type type: string - description: Type of Db2 backup (online or offline) + description: Type of Manage Db2 backup (online or offline) default: "online" -- name: backup_vendor +- name: manage_db2_backup_vendor type: string - description: Storage backend for Db2 backup files (disk or s3) + description: Storage backend for Manage Db2 backup files (disk or s3) default: "disk" - name: backup_s3_endpoint diff --git a/tekton/src/pipelines/mas-backup.yml.j2 b/tekton/src/pipelines/mas-backup.yml.j2 index df29400ee12..bb095cee566 100644 --- a/tekton/src/pipelines/mas-backup.yml.j2 +++ b/tekton/src/pipelines/mas-backup.yml.j2 @@ -231,9 +231,9 @@ spec: value: $(params.mas_instance_id) - name: db2_namespace - value: $(params.db2_namespace) + value: $(params.manage_db2_namespace) - name: db2_instance_name - value: $(params.db2_instance_name) + value: $(params.manage_db2_instance_name) - name: db2_action value: backup @@ -241,9 +241,9 @@ spec: - name: db2_backup_version value: $(params.backup_version) - name: backup_type - value: $(params.backup_type) + value: $(params.manage_db2_backup_type) - name: backup_vendor - value: $(params.backup_vendor) + value: $(params.manage_db2_backup_vendor) - name: backup_s3_endpoint value: $(params.backup_s3_endpoint) - name: backup_s3_bucket @@ -278,9 +278,9 @@ spec: - name: mas_instance_id value: $(params.mas_instance_id) - name: mas_workspace_id - value: $(params.mas_workspace_id) + value: $(params.manage_workspace_id) - name: mas_app_id - value: $(params.mas_app_id) + value: manage - name: mas_backup_dir value: /workspace/backups From b8c43b57819ea5ecce4694411e139121a58ad2f4 Mon Sep 17 00:00:00 2001 From: whitfiea Date: Fri, 6 Feb 2026 13:56:50 +0000 Subject: [PATCH 12/12] update docs --- docs/guides/backup-restore.md | 146 +++++++++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 4 deletions(-) diff --git a/docs/guides/backup-restore.md b/docs/guides/backup-restore.md index a6d59e4f007..b547603fea9 100644 --- a/docs/guides/backup-restore.md +++ b/docs/guides/backup-restore.md @@ -23,6 +23,8 @@ The MAS backup process uses Tekton pipelines to orchestrate the backup of multip - **MongoDB** - MAS configuration database (Community Edition only) - **Suite License Service (SLS)** - License server data (optional) - **MAS Suite Configuration** - Core MAS instance configuration and custom resources +- **MAS Applications** - Application-specific resources and persistent volume data (optional) +- **Db2 Database** - Db2 instance resources and database backups (optional) The backup creates a compressed archive that can be stored locally or uploaded to cloud storage (S3 or Artifactory). @@ -36,6 +38,7 @@ The `mas backup` command launches a Tekton pipeline that executes the following - [`ibm.mas_devops.sls`](https://ibm-mas.github.io/ansible-devops/roles/sls/) - Backs up Suite License Service data - [`ibm.mas_devops.suite_backup`](https://ibm-mas.github.io/ansible-devops/roles/suite_backup/) - Backs up MAS Core configuration - [`ibm.mas_devops.suite_app_backup`](https://ibm-mas.github.io/ansible-devops/roles/suite_app_backup/) - Backs up MAS application resources and persistent volume data +- [`ibm.mas_devops.db2`](https://ibm-mas.github.io/ansible-devops/roles/db2/) - Backs up DB2 resources and persistent volume data For detailed information about the underlying Ansible automation, see the [Backup and Restore Playbook Documentation](https://ibm-mas.github.io/ansible-devops/playbooks/backup-restore/). @@ -116,6 +119,59 @@ Specify the certificate manager provider used in your environment: The backup captures certificate configurations but not the actual certificates, which are regenerated during restore. +### MAS Application Backup + +The backup process supports backing up MAS application resources and persistent volume data. Currently supported: + +- **Manage Application** - Backs up Manage namespace resources and persistent volume data + +When backing up a Manage application, the following resources are included: + +**Namespace Resources**: +- `ManageApp` custom resource +- `ManageWorkspace` custom resource +- Encryption secrets (dynamically determined from ManageWorkspace CR) +- Certificates with `mas.ibm.com/instanceId` label +- Subscription and OperatorGroup +- IBM entitlement secret +- All referenced secrets (auto-discovered) + +**Persistent Volume Data** (if configured in ManageWorkspace CR): +- All persistent volumes defined in `spec.settings.deployment.persistentVolumes` +- Data backed up as compressed tar.gz archives +- Each PVC's mount path archived separately +- Common PVCs include JMS server data, custom fonts, and attachments + +!!! note + Application backup is optional and configured during the interactive backup process or via command-line parameters (`--backup-manage-app`, `--manage-workspace-id`). + +### Db2 Database Backup + +The backup process supports backing up Db2 databases used by MAS applications. When backing up a Db2 database, the following are included: + +**Db2 Instance Resources**: +- `Db2uCluster` custom resource +- Secrets (instance password, certificates, LDAP credentials) +- ConfigMaps +- Services and routes +- Operator subscription + +**Database Data**: +- Complete database backup (full backup) +- Stored in the backup archive alongside other components +- Supports both online and offline backup modes + +**Backup Types**: + +- **Online Backup** - Database remains accessible during backup; requires archive logging enabled +- **Offline Backup** - Database unavailable during backup; works with circular logging (default configuration) + +!!! warning + If your Db2 instance uses circular logging (the default configuration), you **must** use offline backup type. Online backups require archive logging to be enabled via `LOGARCHMETH1` and `LOGARCHMETH2` configuration. + +!!! note + Db2 backup is optional and configured during the interactive backup process or via command-line parameters (`--backup-manage-db`, `--manage-db2-namespace`, `--manage-db2-instance-name`, `--manage-db2-backup-type`). + Backup Modes ------------------------------------------------------------------------------- @@ -232,6 +288,51 @@ mas backup \ !!! tip Store AWS credentials securely using environment variables or secrets management systems rather than hardcoding them in scripts. +### Scenario 5: Backup with Manage Application and Db2 Database + +**Environment:** +- Standard MAS deployment with Manage application +- Manage workspace with persistent volumes configured +- In-cluster Db2 database for Manage +- Need to backup application resources, PV data, and database + +**Backup Command:** +```bash +mas backup \ + --instance-id inst1 \ + --backup-storage-size 100Gi \ + --backup-manage-app \ + --manage-workspace-id masdev \ + --backup-manage-db \ + --manage-db2-namespace db2u \ + --manage-db2-instance-name mas-inst1-masdev-manage \ + --manage-db2-backup-type offline \ + --no-confirm +``` + +!!! tip + When backing up Manage with Db2, ensure sufficient backup storage (100Gi+ recommended) to accommodate application PV data and database backups. Use offline backup type if your Db2 instance uses the default circular logging configuration. + +### Scenario 6: Backup with Manage Application Only (External Db2) + +**Environment:** +- MAS deployment with Manage application +- External Db2 database (managed separately) +- Only need to backup application resources and PV data + +**Backup Command:** +```bash +mas backup \ + --instance-id inst1 \ + --backup-storage-size 50Gi \ + --backup-manage-app \ + --manage-workspace-id masdev \ + --no-confirm +``` + +!!! note + When using an external Db2 database, omit the `--backup-manage-db` flag. The database should be backed up separately using your organization's database backup procedures. + ### Scenario 7: Backup for Troubleshooting (No Cleanup) **Environment:** @@ -288,9 +389,13 @@ The backup storage size depends on several factors: | SLS Data | < 1 MB | License server database and configuration | | IBM Catalogs | < 1 MB | Operator catalog definitions | | Certificate Manager | < 1 MB | Certificate configurations | +| Manage App Resources | < 10 MB | Manage namespace Kubernetes resources | +| Manage PV Data | 1-100 GB | JMS server, fonts, attachments (if configured) | +| Db2 Instance Resources | < 10 MB | Db2 Kubernetes resources and metadata | +| Db2 Database Backup | Varies | 0.5-2x database size when compressed; depends on data volume | !!! tip - Monitor your first backup to determine actual storage requirements, then adjust the `--backup-storage-size` parameter for future backups. + Monitor your first backup to determine actual storage requirements, then adjust the `--backup-storage-size` parameter for future backups. When backing up Manage with Db2, plan for significantly larger storage requirements (100GB+ recommended). ### Storage Class Considerations @@ -321,9 +426,15 @@ When you run `mas backup`, the following occurs: - MongoDB backup - SLS backup (if included) 7. **Suite Backup** - Backs up MAS core configuration -8. **Archive Creation** - Compresses backup into tar.gz archive -9. **Upload** (optional) - Uploads archive to S3 or Artifactory -10. **Workspace Cleanup** (optional, default: enabled) - Cleans backup and config workspaces to free up storage +8. **Database Backup** (optional) - Backs up Db2 instance and database: + - Db2 instance resources backup + - Db2 database backup (online or offline) +9. **Application Backup** (optional) - Backs up MAS application resources and persistent volumes: + - Manage namespace resources backup + - Manage persistent volume data backup +10. **Archive Creation** - Compresses backup into tar.gz archive +11. **Upload** (optional) - Uploads archive to S3 or Artifactory +12. **Workspace Cleanup** (optional, default: enabled) - Cleans backup and config workspaces to free up storage ### Monitoring Progress @@ -380,6 +491,9 @@ Best Practices 4. **Off-site Storage** - Upload backups to S3 or Artifactory for disaster recovery 5. **Test Restores** - Periodically test restore procedures in non-production environments 6. **Document Configuration** - Keep records of custom configurations and dependencies +7. **Application Backups** - Include Manage application and Db2 database in regular backup schedule +8. **Coordinate Backups** - When backing up Manage, always include the Db2 database for consistency +9. **Storage Planning** - Allocate sufficient backup storage when including applications and databases (100Gi+ recommended) ### Security Considerations @@ -517,6 +631,30 @@ Troubleshooting - Verify network connectivity to AWS - Ensure IAM permissions allow PutObject operations +**Issue: "Manage application backup failed"** + +- Verify Manage workspace ID is correct +- Ensure ManageWorkspace CR exists in the cluster +- Check that Manage pods are running and healthy +- Verify persistent volumes are properly configured in ManageWorkspace CR +- Ensure sufficient storage space in backup PVC + +**Issue: "Db2 backup failed"** + +- Verify Db2 namespace and instance name are correct +- Ensure Db2 instance is running and accessible +- Check backup type matches Db2 logging configuration (use offline for circular logging) +- Verify sufficient storage space in Db2 backup PVC +- Review Db2 pod logs for database-specific errors + +**Issue: "Manage persistent volume backup is slow"** + +- PV backup duration depends on data volume +- Large JMS server or attachment PVCs can take significant time +- Monitor backup progress in Tekton pipeline logs +- Consider scheduling backups during maintenance windows +- Ensure network bandwidth is sufficient for data transfer + Restore Overview -------------------------------------------------------------------------------