dae30161ae
Universal: PR Check / Branch Policy (pull_request) Failing after 2s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 8s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 5s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 1s
Universal: PR Check / Validate PR (pull_request) Failing after 7s
Universal: PR Check / Secret Scan (pull_request) Successful in 8s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 2s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Failing after 5s
Joomla: Metadata Validation / Validate Joomla Metadata (pull_request) Successful in 41s
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 22s
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 Issues (pull_request) Has been cancelled
New #__mokosuitebackup_remotes table stores remote destinations with JSON params per type (SFTP/S3/GDrive/FTP). Each profile can have multiple enabled destinations — the engine uploads to all of them. Database: - New table with profile_id FK, type, enabled, params JSON, ordering - Migration auto-converts existing profile remote columns to new table - RemoteTable, RemoteModel, RemotesModel classes Engine: - BackupEngine: loadRemoteDestinations() + createUploaderFromParams() iterates all enabled remotes, falls back to legacy columns - SteppedBackupEngine: one upload step per remote destination, persisted via session.remoteDestinations + remoteIndex - Local copy only deleted when ALL uploads succeed UI: - Profile edit: "Remote Destinations" linked table with AJAX CRUD - Add/edit modal with type selector showing dynamic fields - Toggle enabled/disabled, delete with confirmation - Legacy fields hidden when remotes configured, shown as fallback - Secrets masked in responses, merged from DB on save Closes #97
98 lines
3.1 KiB
SQL
98 lines
3.1 KiB
SQL
-- MokoSuiteBackup 01.41.00 — Multi-remote storage destinations (#97)
|
|
|
|
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;
|
|
|
|
-- Migrate existing SFTP remote configs into new table
|
|
INSERT INTO `#__mokosuitebackup_remotes` (`profile_id`, `title`, `type`, `enabled`, `params`, `ordering`, `created`)
|
|
SELECT
|
|
`id`,
|
|
CONCAT(`title`, ' - SFTP'),
|
|
'sftp',
|
|
1,
|
|
JSON_OBJECT(
|
|
'host', `sftp_host`,
|
|
'port', `sftp_port`,
|
|
'username', `sftp_username`,
|
|
'auth_type', `sftp_auth_type`,
|
|
'password', `sftp_password`,
|
|
'key_data', COALESCE(`sftp_key_data`, ''),
|
|
'passphrase', `sftp_passphrase`,
|
|
'path', `sftp_path`
|
|
),
|
|
1,
|
|
NOW()
|
|
FROM `#__mokosuitebackup_profiles`
|
|
WHERE `remote_storage` = 'sftp' AND `sftp_host` != '';
|
|
|
|
-- Migrate existing S3 remote configs into new table
|
|
INSERT INTO `#__mokosuitebackup_remotes` (`profile_id`, `title`, `type`, `enabled`, `params`, `ordering`, `created`)
|
|
SELECT
|
|
`id`,
|
|
CONCAT(`title`, ' - S3'),
|
|
's3',
|
|
1,
|
|
JSON_OBJECT(
|
|
'endpoint', `s3_endpoint`,
|
|
'region', `s3_region`,
|
|
'access_key', `s3_access_key`,
|
|
'secret_key', `s3_secret_key`,
|
|
'bucket', `s3_bucket`,
|
|
'path', `s3_path`
|
|
),
|
|
1,
|
|
NOW()
|
|
FROM `#__mokosuitebackup_profiles`
|
|
WHERE `remote_storage` = 's3' AND `s3_bucket` != '';
|
|
|
|
-- Migrate existing Google Drive remote configs into new table
|
|
INSERT INTO `#__mokosuitebackup_remotes` (`profile_id`, `title`, `type`, `enabled`, `params`, `ordering`, `created`)
|
|
SELECT
|
|
`id`,
|
|
CONCAT(`title`, ' - Google Drive'),
|
|
'google_drive',
|
|
1,
|
|
JSON_OBJECT(
|
|
'client_id', `gdrive_client_id`,
|
|
'client_secret', `gdrive_client_secret`,
|
|
'refresh_token', `gdrive_refresh_token`,
|
|
'folder_id', `gdrive_folder_id`
|
|
),
|
|
1,
|
|
NOW()
|
|
FROM `#__mokosuitebackup_profiles`
|
|
WHERE `remote_storage` = 'google_drive' AND `gdrive_client_id` != '';
|
|
|
|
-- Migrate existing FTP remote configs into new table
|
|
INSERT INTO `#__mokosuitebackup_remotes` (`profile_id`, `title`, `type`, `enabled`, `params`, `ordering`, `created`)
|
|
SELECT
|
|
`id`,
|
|
CONCAT(`title`, ' - FTP'),
|
|
'ftp',
|
|
1,
|
|
JSON_OBJECT(
|
|
'host', `ftp_host`,
|
|
'port', `ftp_port`,
|
|
'username', `ftp_username`,
|
|
'password', `ftp_password`,
|
|
'path', `ftp_path`,
|
|
'passive', `ftp_passive`,
|
|
'ssl', `ftp_ssl`
|
|
),
|
|
1,
|
|
NOW()
|
|
FROM `#__mokosuitebackup_profiles`
|
|
WHERE `remote_storage` = 'ftp' AND `ftp_host` != '';
|