10248b284a
Universal: PR Check / Branch Policy (pull_request) Failing after 2s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 5s
Generic: Project CI / Lint & Validate (pull_request) Successful in 12s
Universal: PR Check / Secret Scan (pull_request) Successful in 6s
Universal: PR Check / Validate PR (pull_request) Failing after 4s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 2s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 2s
Joomla: Metadata Validation / Validate Joomla Metadata (pull_request) Successful in 9s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 27s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 39s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 30s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Successful in 4m0s
Generic: Project CI / Tests (pull_request) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Has been cancelled
Joomla: Extension CI / PHPStan Analysis (pull_request) Has been cancelled
Joomla: Extension CI / Build RC Pre-Release (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
Generic: Repo Health / Scripts governance (pull_request) Has been cancelled
Generic: Repo Health / Repository health (pull_request) Has been cancelled
Generic: Repo Health / Report: Scripts Governance (pull_request) Has been cancelled
Generic: Repo Health / Report: Repository Health (pull_request) Has been cancelled
Two related backup-management fixes.
Retention (records/days to keep):
- The retention fieldset was defined in profile.xml but never rendered
in the profile editor, so retention_days/retention_count were invisible.
Render the retention fieldset on the Archive tab.
- retention_days/retention_count were read by nothing, so they pruned no
backups. Add RetentionManager::prune(), called from completeRecord() in
both BackupEngine and SteppedBackupEngine after a backup finishes.
Policy: delete a completed/warning backup when EITHER it is older than
retention_days OR it falls outside the newest retention_count copies
(0 = unlimited for that rule). Deleting a record also removes its
archive and log file.
- Correct misleading language/schema text ("use global default" — no such
global backup-retention setting exists) to "0 = unlimited".
Purge Old Backups button:
- The modal only opened via a fragile selector match on the toolbar
button's inline onclick, which Joomla 6's Atum toolbar does not render,
so the button did nothing. Wrap Joomla.submitbutton to open the modal
for the backups.purgeModal task, keeping the selector as a fallback.
139 lines
8.6 KiB
SQL
139 lines
8.6 KiB
SQL
CREATE TABLE IF NOT EXISTS `#__mokosuitebackup_profiles` (
|
|
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
`title` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`description` TEXT NOT NULL,
|
|
`backup_type` VARCHAR(20) NOT NULL DEFAULT 'full' COMMENT 'full, database, files',
|
|
`archive_format` VARCHAR(10) NOT NULL DEFAULT 'zip',
|
|
`compression_level` TINYINT(1) UNSIGNED NOT NULL DEFAULT 5 COMMENT '0=none, 9=max',
|
|
`split_size` INT(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '0=no split, otherwise MB per part',
|
|
`backup_dir` VARCHAR(512) NOT NULL DEFAULT '[DEFAULT_DIR]',
|
|
`archive_name_format` VARCHAR(512) NOT NULL DEFAULT '[HOST]_[DATETIME]_profile[PROFILE_ID]' COMMENT 'Filename format with placeholders',
|
|
`exclude_dirs` TEXT NOT NULL COMMENT 'Newline-separated directory paths to exclude',
|
|
`exclude_files` TEXT NOT NULL COMMENT 'Newline-separated filename patterns to exclude',
|
|
`exclude_tables` TEXT NOT NULL COMMENT 'Newline-separated table names to exclude',
|
|
`remote_storage` VARCHAR(20) NOT NULL DEFAULT 'none' COMMENT 'none, ftp, google_drive, s3',
|
|
`ftp_host` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`ftp_port` INT(5) UNSIGNED NOT NULL DEFAULT 21,
|
|
`ftp_username` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`ftp_password` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`ftp_path` VARCHAR(512) NOT NULL DEFAULT '/backups',
|
|
`ftp_passive` TINYINT(1) NOT NULL DEFAULT 1,
|
|
`ftp_ssl` TINYINT(1) NOT NULL DEFAULT 0,
|
|
`sftp_host` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`sftp_port` INT(5) UNSIGNED NOT NULL DEFAULT 22,
|
|
`sftp_username` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`sftp_auth_type` VARCHAR(20) NOT NULL DEFAULT 'key',
|
|
`sftp_password` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`sftp_key_data` MEDIUMTEXT,
|
|
`sftp_passphrase` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`sftp_path` VARCHAR(512) NOT NULL DEFAULT '/backups',
|
|
`gdrive_client_id` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`gdrive_client_secret` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`gdrive_refresh_token` VARCHAR(512) NOT NULL DEFAULT '',
|
|
`gdrive_folder_id` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`s3_endpoint` VARCHAR(512) NOT NULL DEFAULT '' COMMENT 'S3 endpoint URL (blank = AWS default)',
|
|
`s3_region` VARCHAR(50) NOT NULL DEFAULT 'us-east-1',
|
|
`s3_access_key` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`s3_secret_key` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`s3_bucket` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`s3_path` VARCHAR(512) NOT NULL DEFAULT '/backups',
|
|
`remote_keep_local` TINYINT(1) NOT NULL DEFAULT 1 COMMENT 'Keep local copy after upload',
|
|
`encryption_password` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'AES-256 archive encryption password (blank = no encryption)',
|
|
`include_mokorestore` VARCHAR(20) NOT NULL DEFAULT '0' COMMENT 'MokoRestore mode: 0=none, 1=wrapped, standalone',
|
|
`restore_script_name` VARCHAR(100) NOT NULL DEFAULT 'restore.php' COMMENT 'Custom restore script filename',
|
|
`sanitize_passwords` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'Replace user password hashes with invalid value',
|
|
`preserve_super_admin` TINYINT(1) NOT NULL DEFAULT 1 COMMENT 'Keep super admin password when sanitizing',
|
|
`sanitize_emails` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'Replace user emails with dummy values',
|
|
`sanitize_sessions` TINYINT(1) NOT NULL DEFAULT 1 COMMENT 'Skip session table data',
|
|
`notify_email` VARCHAR(512) NOT NULL DEFAULT '' COMMENT 'Comma-separated notification emails',
|
|
`notify_user_groups` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'Comma-separated Joomla user group IDs',
|
|
`notify_on_success` TINYINT(1) NOT NULL DEFAULT 0,
|
|
`notify_on_failure` TINYINT(1) NOT NULL DEFAULT 1,
|
|
`retention_days` INT(11) NOT NULL DEFAULT 0 COMMENT 'Delete backups older than N days; 0 = unlimited',
|
|
`retention_count` INT(11) NOT NULL DEFAULT 0 COMMENT 'Keep newest N backups; 0 = unlimited',
|
|
`ntfy_topic` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'ntfy topic name',
|
|
`ntfy_server` VARCHAR(512) NOT NULL DEFAULT 'https://ntfy.sh' COMMENT 'ntfy server URL',
|
|
`ntfy_token` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'ntfy access token (optional)',
|
|
`published` TINYINT(1) NOT NULL DEFAULT 1,
|
|
`created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
|
|
`modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
|
|
PRIMARY KEY (`id`),
|
|
KEY `idx_published` (`published`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS `#__mokosuitebackup_records` (
|
|
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
`profile_id` INT(11) UNSIGNED NOT NULL DEFAULT 1,
|
|
`description` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`status` VARCHAR(20) NOT NULL DEFAULT 'pending' COMMENT 'pending, running, complete, warning, fail',
|
|
`origin` VARCHAR(20) NOT NULL DEFAULT 'backend' COMMENT 'backend, cli, api, scheduled',
|
|
`backup_type` VARCHAR(20) NOT NULL DEFAULT 'full' COMMENT 'full, database, files',
|
|
`archivename` VARCHAR(512) NOT NULL DEFAULT '',
|
|
`absolute_path` VARCHAR(1024) NOT NULL DEFAULT '',
|
|
`total_size` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
|
|
`db_size` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
|
|
`files_count` INT(11) UNSIGNED NOT NULL DEFAULT 0,
|
|
`tables_count` INT(11) UNSIGNED NOT NULL DEFAULT 0,
|
|
`multipart` INT(11) UNSIGNED NOT NULL DEFAULT 0,
|
|
`tag` VARCHAR(50) NOT NULL DEFAULT '',
|
|
`backupstart` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
|
|
`backupend` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
|
|
`filesexist` TINYINT(1) NOT NULL DEFAULT 1,
|
|
`remote_filename` VARCHAR(512) NOT NULL DEFAULT '',
|
|
`checksum` VARCHAR(64) NOT NULL DEFAULT '' COMMENT 'SHA-256 hash of archive',
|
|
`base_record_id` INT(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Base full backup ID for differential',
|
|
`manifest` LONGTEXT DEFAULT NULL COMMENT 'JSON file manifest for differential comparison',
|
|
`log` MEDIUMTEXT DEFAULT NULL COMMENT 'Step-by-step backup log',
|
|
PRIMARY KEY (`id`),
|
|
KEY `idx_profile` (`profile_id`),
|
|
KEY `idx_status` (`status`),
|
|
KEY `idx_backupstart` (`backupstart`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS `#__mokosuitebackup_snapshots` (
|
|
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
`description` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`content_types` VARCHAR(255) NOT NULL DEFAULT '[]' COMMENT 'JSON array: ["articles","categories","modules"]',
|
|
`status` VARCHAR(20) NOT NULL DEFAULT 'complete' COMMENT 'complete, fail',
|
|
`articles_count` INT(11) UNSIGNED NOT NULL DEFAULT 0,
|
|
`categories_count` INT(11) UNSIGNED NOT NULL DEFAULT 0,
|
|
`modules_count` INT(11) UNSIGNED NOT NULL DEFAULT 0,
|
|
`data_file` VARCHAR(512) NOT NULL DEFAULT '' COMMENT 'Absolute path to JSON snapshot file',
|
|
`data_size` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Size of JSON file in bytes',
|
|
`log` MEDIUMTEXT DEFAULT NULL COMMENT 'Snapshot operation log',
|
|
`created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
|
|
`created_by` INT(11) UNSIGNED NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (`id`),
|
|
KEY `idx_created` (`created`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS `#__mokosuitebackup_remotes` (
|
|
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
`profile_id` INT(11) UNSIGNED NOT NULL,
|
|
`title` VARCHAR(255) NOT NULL DEFAULT '',
|
|
`type` VARCHAR(20) NOT NULL DEFAULT 'sftp' COMMENT 'sftp, s3, google_drive',
|
|
`enabled` TINYINT(1) NOT NULL DEFAULT 1,
|
|
`params` MEDIUMTEXT COMMENT 'JSON: type-specific settings',
|
|
`ordering` INT(11) NOT NULL DEFAULT 0,
|
|
`created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
|
|
`modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
|
|
PRIMARY KEY (`id`),
|
|
KEY `idx_profile` (`profile_id`),
|
|
KEY `idx_enabled` (`profile_id`, `enabled`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- Insert default backup profile (IGNORE prevents duplicate key error on update)
|
|
INSERT IGNORE INTO `#__mokosuitebackup_profiles` (
|
|
`id`, `title`, `description`, `backup_type`,
|
|
`archive_format`, `compression_level`, `split_size`, `backup_dir`,
|
|
`exclude_dirs`, `exclude_files`, `exclude_tables`,
|
|
`published`, `created`, `modified`
|
|
) VALUES (
|
|
1, 'Default Backup Profile', 'Full site backup with default settings', 'full',
|
|
'zip', 5, 0, '[DEFAULT_DIR]',
|
|
'administrator/components/com_mokosuitebackup/backups\ntmp\ncache\nlogs\nadministrator/logs',
|
|
'.gitignore\n.htaccess.bak',
|
|
'#__session',
|
|
1, NOW(), NOW()
|
|
);
|