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/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..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). @@ -35,6 +37,8 @@ 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 +- [`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/). @@ -115,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 ------------------------------------------------------------------------------- @@ -231,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:** @@ -287,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 @@ -320,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 @@ -379,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 @@ -516,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 ------------------------------------------------------------------------------- @@ -578,7 +717,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 +753,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 +795,7 @@ Restore Scenarios - Non-Interactive Mode ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --no-confirm ``` @@ -670,7 +809,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 +828,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 +843,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 +860,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 +877,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 +897,7 @@ mas restore \ ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --exclude-grafana \ --no-confirm ``` @@ -775,7 +914,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 +947,7 @@ mas restore \ ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --no-clean-backup \ --no-confirm ``` @@ -826,7 +965,7 @@ mas restore \ ```bash mas restore \ --instance-id inst1 \ - --restore-version 20260117-191701 \ + --restore-version 2020260117-191701 \ --skip-pre-check \ --no-confirm ``` @@ -955,6 +1094,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 188e377966c..6e967cff593 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 @@ -22,7 +21,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 +69,15 @@ def backup(self, argv): "s3_bucket_name", "s3_region", "artifactory_url", - "artifactory_repository" + "artifactory_repository", + # Manage App Backup + "manage_workspace_id", + "backup_manage_app", + "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 @@ -128,6 +135,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 +166,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("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("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: print() @@ -318,7 +338,9 @@ 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", ]) uploadDestination = self.promptForListSelect( "Select upload destination", @@ -365,3 +387,88 @@ 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") + + # 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("manage_workspace_id", workspaceId) + else: + workspaceId = self.promptForString("Enter Manage workspace ID") + self.setParam("manage_workspace_id", workspaceId) + else: + workspaceId = self.promptForString("Enter Manage workspace ID") + self.setParam("manage_workspace_id", workspaceId) + except Exception: + workspaceId = self.promptForString("Enter Manage workspace ID") + self.setParam("manage_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("manage") + else: + self.setParam("backup_manage_db", "false") + else: + self.setParam("backup_manage_app", "false") + self.setParam("backup_manage_db", "false") + + 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(f"{appId}_db2_namespace", db2Namespace) + + # DB2 instance name + instanceId = self.getParam("mas_instance_id") + workspaceID = self.getParam(f"{appId}_workspace_id") + db2InstanceName = self.promptForString("Enter Db2 instance name", default=f"mas-{instanceId}-{workspaceID}-{appId}") + self.setParam(f"{appId}_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. offline", + " 2. online", + ]) + self.promptForListSelect( + message="Select backup type", + options=["offline", "online"], + 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(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/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: 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..f52d3150b3c 100644 --- a/tekton/src/params/backup.yml.j2 +++ b/tekton/src/params/backup.yml.j2 @@ -219,4 +219,63 @@ - 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: manage_workspace_id + type: string + description: Manage workspace ID for application backup + default: "" + +# Manage Db2 Backup Configuration +# ----------------------------------------------------------------------------- +- name: manage_db2_namespace + type: string + description: Manage Db2 namespace for backup + default: "" + +- name: manage_db2_instance_name + type: string + description: Manage Db2 instance name for backup + default: "" + +- name: manage_db2_backup_type + type: string + description: Type of Manage Db2 backup (online or offline) + default: "online" + +- name: manage_db2_backup_vendor + type: string + description: Storage backend for Manage 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..bb095cee566 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 # ------------------------------------------------------------------------- @@ -62,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 @@ -93,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 @@ -122,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 @@ -160,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) @@ -199,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) @@ -224,7 +216,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.manage_db2_namespace) + - name: db2_instance_name + value: $(params.manage_db2_instance_name) + - name: db2_action + value: backup + + # Backup specific parameters + - name: db2_backup_version + value: $(params.backup_version) + - name: backup_type + value: $(params.manage_db2_backup_type) + - name: backup_vendor + value: $(params.manage_db2_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: + - pre-backup-check + + # 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.manage_workspace_id) + - name: mas_app_id + value: manage + + - name: mas_backup_dir + value: /workspace/backups + - name: mas_app_backup_version + value: $(params.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 +340,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/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/dependencies/db2.yml.j2 b/tekton/src/tasks/dependencies/db2.yml.j2 index e4c2fc3783c..d93299af212 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: DB2_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..aeffe678651 --- /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 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