Files
cloudron-box/migrations/20250724141339-backups-add-siteId.js
2025-10-01 10:27:20 +02:00

56 lines
3.1 KiB
JavaScript

'use strict';
const crypto = require('node:crypto'),
path = require('node:path'),
paths = require('../src/paths.js');
exports.up = async function(db) {
const backups = await db.runSql('SELECT format, COUNT(*) AS count FROM backups GROUP BY format WITH ROLLUP', []); // https://dev.mysql.com/doc/refman/8.4/en/group-by-modifiers.html
let tgzCount = 0, rsyncCount = 0, totalCount = 0;
for (const r of backups) {
if (r.format === 'tgz') tgzCount = r.count;
else if (r.format === 'rsync') rsyncCount = r.count;
else if (r.format === null) totalCount = r.count;
}
let theOneFormat = null;
if (tgzCount === totalCount) theOneFormat = 'tgz';
else if (rsyncCount === totalCount) theOneFormat = 'rsync';
console.log(`Backup counts. rsync: ${rsyncCount} tgz: ${tgzCount} total: ${totalCount} . theOneFormat: ${theOneFormat}`);
const backupSites = await db.runSql('SELECT * FROM backupSites');
const currentBackupSite = backupSites[0];
let cloneBackupSite = null;
if (totalCount && currentBackupSite.format !== theOneFormat) {
const cloneId = crypto.randomUUID();
cloneBackupSite = Object.assign({}, backupSites[0], { id: cloneId });
cloneBackupSite.format = currentBackupSite.format === 'rsync' ? 'tgz' : 'rsync';
cloneBackupSite.priority = false;
cloneBackupSite.name = 'Copy of Default';
cloneBackupSite.schedule = 'never';
cloneBackupSite._managedMountPath = path.join(paths.MANAGED_BACKUP_MOUNT_DIR, cloneId); // this won't work until the user remounts
console.log(`Existing format is ${currentBackupSite.format} . Adding clone backup site for ${cloneBackupSite.format}`);
await db.runSql('INSERT INTO backupSites (id, name, configJson, limitsJson, retentionJson, schedule, encryptionJson, format, priority) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)',
[ cloneBackupSite.id, cloneBackupSite.name, cloneBackupSite.configJson, cloneBackupSite.limitsJson, cloneBackupSite.retentionJson, cloneBackupSite.schedule,
cloneBackupSite.encryptionJson, cloneBackupSite.format, cloneBackupSite.priority ]);
}
await db.runSql('ALTER TABLE backups ADD siteId VARCHAR(128)');
if (totalCount) {
if (currentBackupSite.format === 'tgz') {
const ext = currentBackupSite.encryptionJson ? '.tar.gz.enc' : '.tar.gz';
console.log(`Adjusting remotePath of existing tgz backups with ${ext}`);
await db.runSql('UPDATE backups SET remotePath=CONCAT(remotePath, ?) WHERE format=?', [ ext, 'tgz' ]);
}
await db.runSql('UPDATE backups SET siteId=? WHERE format=?', [ currentBackupSite.id, currentBackupSite.format ]);
if (cloneBackupSite) await db.runSql('UPDATE backups SET siteId=? WHERE format=?', [ cloneBackupSite.id, cloneBackupSite.format ]);
}
await db.runSql('ALTER TABLE backups MODIFY siteId VARCHAR(128) NOT NULL');
await db.runSql('ALTER TABLE backups ADD FOREIGN KEY(siteId) REFERENCES backupSites(id)');
await db.runSql('ALTER TABLE backups DROP COLUMN format');
};
exports.down = async function(/*db*/) {
};