Merge: resolve conflict in routes/backups.js, keep storage-info + maxStorageBytes

This commit is contained in:
Krystie
2026-05-28 15:00:41 -07:00
parent ea9bdf9598
commit ad9400490d
6 changed files with 387 additions and 14 deletions
+21 -4
View File
@@ -226,17 +226,34 @@ class ConfigManager {
* @returns {Promise<Object>} Disk space info
*/
async getDiskSpace(testPath) {
// Note: This is a simplified version. In production, you'd use a library like 'check-disk-space'
try {
const stats = await fs.stat(testPath);
const fsPromises = require('fs').promises;
const pathModule = require('path');
// Ensure directory exists
await fsPromises.mkdir(testPath, { recursive: true });
// Use statfs for true disk space (works on all filesystems: ext4, Btrfs, XFS, ZFS, APFS, NTFS)
const stats = await fsPromises.statfs(testPath);
const totalBytes = stats.blocks * stats.bsize;
const freeBytes = stats.bfree * stats.bsize;
const availableBytes = stats.bavail * stats.bsize; // Available to non-root users
const usedBytes = totalBytes - freeBytes;
return {
available: true,
path: testPath
path: testPath,
total: totalBytes,
used: usedBytes,
free: freeBytes,
availableBytes: availableBytes,
usagePercent: parseFloat(((usedBytes / totalBytes) * 100).toFixed(2))
};
} catch (error) {
return {
available: false,
path: testPath,
error: error.message
};
}
@@ -62,6 +62,11 @@ const state = {
installPath: '',
health: null
},
// Backup configuration
backup: {
maxStorageGB: 10,
backupDir: ''
},
// Uninstall mode
uninstallMode: false,
uninstall: {
@@ -373,6 +378,24 @@ function updateBranding(field, value) {
if (field === 'primaryColor') render();
}
// Backup functions
function updateBackup(field, value) {
state.backup[field] = value;
render();
}
async function selectBackupDir() {
try {
const result = await window.electronAPI.selectFolder();
if (result.success && result.path) {
state.backup.backupDir = result.path;
render();
}
} catch (err) {
console.error('Backup dir selection failed:', err);
}
}
async function selectLogo() {
try {
const result = await window.electronAPI.selectFile({
@@ -420,6 +443,10 @@ async function startInstallation() {
password: state.dns.password,
token: state.dns.token
} : null,
backup: {
maxStorageGB: state.backup.maxStorageGB,
backupDir: state.backup.backupDir || null
},
autoStart: true
});
} catch (err) {
@@ -963,6 +990,31 @@ function renderDashboardSetup() {
<p class="hint">Port for the DashCaddy API server (default: 3001)</p>
</div>
` : ''}
<div class="folder-input">
<label>Backup Storage Limit (GB)</label>
<div class="input-row">
<input type="number"
value="${state.backup.maxStorageGB}"
min="1" max="10240"
oninput="updateBackup('maxStorageGB', parseInt(this.value) || 10)">
</div>
<p class="hint">Maximum storage for backups in GB (default: 10, max: 10TB)</p>
</div>
${state.tier !== 'basic' ? `
<div class="folder-input">
<label>Backup Directory</label>
<div class="input-row">
<input type="text"
value="${escapeHtml(state.backup.backupDir)}"
readonly
placeholder="Default: $INSTALL_DIR/backups">
<button class="btn-browse" onclick="selectBackupDir()">Browse...</button>
</div>
<p class="hint">Where backup files are stored on the host</p>
</div>
` : ''}
</div>
</div>
`;