Compare commits
11 Commits
feat/lxc_b
...
node24_sec
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72c0246d8c | ||
|
|
bc31896586 | ||
|
|
213a606fc0 | ||
|
|
3579f2258e | ||
|
|
5b861ade05 | ||
|
|
553eae6ce7 | ||
|
|
c2ca88f033 | ||
|
|
67d44a6a5f | ||
|
|
fe6cca5c63 | ||
|
|
014e5b69e9 | ||
|
|
f37b2cb26f |
@@ -43,6 +43,10 @@ const config = {
|
|||||||
'http://192.168.*',
|
'http://192.168.*',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
turbopack: {
|
||||||
|
// Disable Turbopack and use Webpack instead for compatibility
|
||||||
|
// This is necessary for server-side code that uses child_process
|
||||||
|
},
|
||||||
webpack: (config, { dev, isServer }) => {
|
webpack: (config, { dev, isServer }) => {
|
||||||
if (dev && !isServer) {
|
if (dev && !isServer) {
|
||||||
config.watchOptions = {
|
config.watchOptions = {
|
||||||
@@ -50,12 +54,15 @@ const config = {
|
|||||||
aggregateTimeout: 300,
|
aggregateTimeout: 300,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
// Handle server-side modules
|
||||||
|
if (isServer) {
|
||||||
|
config.externals = config.externals || [];
|
||||||
|
if (!config.externals.includes('child_process')) {
|
||||||
|
config.externals.push('child_process');
|
||||||
|
}
|
||||||
|
}
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
// Ignore ESLint errors during build (they can be fixed separately)
|
|
||||||
eslint: {
|
|
||||||
ignoreDuringBuilds: true,
|
|
||||||
},
|
|
||||||
// Ignore TypeScript errors during build (they can be fixed separately)
|
// Ignore TypeScript errors during build (they can be fixed separately)
|
||||||
typescript: {
|
typescript: {
|
||||||
ignoreBuildErrors: true,
|
ignoreBuildErrors: true,
|
||||||
|
|||||||
2760
package-lock.json
generated
2760
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
31
package.json
31
package.json
@@ -4,11 +4,11 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "next build",
|
"build": "next build --webpack",
|
||||||
"check": "next lint && tsc --noEmit",
|
"check": "next lint && tsc --noEmit",
|
||||||
"dev": "next dev",
|
"dev": "next dev --webpack",
|
||||||
"dev:server": "node server.js",
|
"dev:server": "node server.js",
|
||||||
"dev:next": "next dev",
|
"dev:next": "next dev --webpack",
|
||||||
"format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,mdx}\" --cache",
|
"format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,mdx}\" --cache",
|
||||||
"format:write": "prettier --write \"**/*.{ts,tsx,js,jsx,mdx}\" --cache",
|
"format:write": "prettier --write \"**/*.{ts,tsx,js,jsx,mdx}\" --cache",
|
||||||
"lint": "next lint",
|
"lint": "next lint",
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
"typecheck": "tsc --noEmit"
|
"typecheck": "tsc --noEmit"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/client": "^6.18.0",
|
"@prisma/client": "^6.19.0",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||||
"@radix-ui/react-slot": "^1.2.3",
|
"@radix-ui/react-slot": "^1.2.3",
|
||||||
"@t3-oss/env-nextjs": "^0.13.8",
|
"@t3-oss/env-nextjs": "^0.13.8",
|
||||||
@@ -43,14 +43,14 @@
|
|||||||
"cron-validator": "^1.2.0",
|
"cron-validator": "^1.2.0",
|
||||||
"dotenv": "^17.2.3",
|
"dotenv": "^17.2.3",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"lucide-react": "^0.553.0",
|
"lucide-react": "^0.554.0",
|
||||||
"next": "^15.1.6",
|
"next": "^16.0.4",
|
||||||
"node-cron": "^3.0.3",
|
"node-cron": "^4.2.1",
|
||||||
"node-pty": "^1.0.0",
|
"node-pty": "^1.0.0",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"react-markdown": "^10.1.0",
|
"react-markdown": "^10.1.0",
|
||||||
"react-syntax-highlighter": "^15.6.6",
|
"react-syntax-highlighter": "^16.1.0",
|
||||||
"refractor": "^5.0.0",
|
"refractor": "^5.0.0",
|
||||||
"remark-gfm": "^4.0.1",
|
"remark-gfm": "^4.0.1",
|
||||||
"server-only": "^0.0.1",
|
"server-only": "^0.0.1",
|
||||||
@@ -69,15 +69,15 @@
|
|||||||
"@types/bcryptjs": "^3.0.0",
|
"@types/bcryptjs": "^3.0.0",
|
||||||
"@types/better-sqlite3": "^7.6.8",
|
"@types/better-sqlite3": "^7.6.8",
|
||||||
"@types/jsonwebtoken": "^9.0.10",
|
"@types/jsonwebtoken": "^9.0.10",
|
||||||
"@types/node": "^24.9.1",
|
"@types/node": "^24.10.1",
|
||||||
"@types/node-cron": "^3.0.11",
|
"@types/node-cron": "^3.0.11",
|
||||||
"@types/react": "^19.2.4",
|
"@types/react": "^19.2.4",
|
||||||
"@types/react-dom": "^19.2.2",
|
"@types/react-dom": "^19.2.2",
|
||||||
"@vitejs/plugin-react": "^5.1.0",
|
"@vitejs/plugin-react": "^5.1.0",
|
||||||
"@vitest/coverage-v8": "^3.2.4",
|
"@vitest/coverage-v8": "^4.0.13",
|
||||||
"@vitest/ui": "^3.2.4",
|
"@vitest/ui": "^4.0.13",
|
||||||
"eslint": "^9.38.0",
|
"eslint": "^9.39.1",
|
||||||
"eslint-config-next": "^15.1.6",
|
"eslint-config-next": "^16.0.4",
|
||||||
"jsdom": "^27.2.0",
|
"jsdom": "^27.2.0",
|
||||||
"postcss": "^8.5.3",
|
"postcss": "^8.5.3",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
@@ -86,12 +86,15 @@
|
|||||||
"tailwindcss": "^4.1.17",
|
"tailwindcss": "^4.1.17",
|
||||||
"typescript": "^5.8.2",
|
"typescript": "^5.8.2",
|
||||||
"typescript-eslint": "^8.46.2",
|
"typescript-eslint": "^8.46.2",
|
||||||
"vitest": "^3.2.4"
|
"vitest": "^4.0.13"
|
||||||
},
|
},
|
||||||
"ct3aMetadata": {
|
"ct3aMetadata": {
|
||||||
"initVersion": "7.39.3"
|
"initVersion": "7.39.3"
|
||||||
},
|
},
|
||||||
"packageManager": "npm@10.9.3",
|
"packageManager": "npm@10.9.3",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=24.0.0"
|
||||||
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"prismjs": "^1.30.0"
|
"prismjs": "^1.30.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ root_check() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported.
|
# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported.
|
||||||
# Supported: Proxmox VE 8.0.x – 8.9.x and 9.0 (NOT 9.1+)
|
# Supported: Proxmox VE 8.0.x – 8.9.x, 9.0 and 9.1
|
||||||
pve_check() {
|
pve_check() {
|
||||||
local PVE_VER
|
local PVE_VER
|
||||||
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
|
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
|
||||||
@@ -76,12 +76,12 @@ pve_check() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for Proxmox VE 9.x: allow ONLY 9.0
|
# Check for Proxmox VE 9.x: allow 9.0 and 9.1
|
||||||
if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then
|
if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then
|
||||||
local MINOR="${BASH_REMATCH[1]}"
|
local MINOR="${BASH_REMATCH[1]}"
|
||||||
if ((MINOR != 0)); then
|
if ((MINOR < 0 || MINOR > 1)); then
|
||||||
msg_error "This version of Proxmox VE is not yet supported."
|
msg_error "This version of Proxmox VE is not supported."
|
||||||
msg_error "Supported: Proxmox VE version 9.0"
|
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
return 0
|
return 0
|
||||||
@@ -89,7 +89,7 @@ pve_check() {
|
|||||||
|
|
||||||
# All other unsupported versions
|
# All other unsupported versions
|
||||||
msg_error "This version of Proxmox VE is not supported."
|
msg_error "This version of Proxmox VE is not supported."
|
||||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0"
|
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0 – 9.1"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1323,9 +1323,9 @@ EOF'
|
|||||||
msg_ok "Customized LXC Container"
|
msg_ok "Customized LXC Container"
|
||||||
|
|
||||||
if [ "$var_os" == "alpine" ]; then
|
if [ "$var_os" == "alpine" ]; then
|
||||||
FUNCTIONS_FILE_PATH="$(cat "$CORE_DIR/core.func" && echo && cat "$CORE_DIR/tools.func" && echo && cat "$CORE_DIR/alpine-install.func")"
|
FUNCTIONS_FILE_PATH="$(cat "$CORE_DIR/core.func" && echo && cat "$CORE_DIR/tools.func" && echo && cat "$CORE_DIR/api.func" && echo && cat "$CORE_DIR/alpine-install.func")"
|
||||||
else
|
else
|
||||||
FUNCTIONS_FILE_PATH="$(cat "$CORE_DIR/core.func" && echo && cat "$CORE_DIR/tools.func" && echo && cat "$CORE_DIR/install.func")"
|
FUNCTIONS_FILE_PATH="$(cat "$CORE_DIR/core.func" && echo && cat "$CORE_DIR/tools.func" && echo && cat "$CORE_DIR/api.func" && echo && cat "$CORE_DIR/install.func")"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
FUNCTIONS_FILE="/tmp/functions.sh"
|
FUNCTIONS_FILE="/tmp/functions.sh"
|
||||||
|
|||||||
@@ -392,8 +392,6 @@ cleanup_lxc() {
|
|||||||
|
|
||||||
# Python pip
|
# Python pip
|
||||||
if command -v pip &>/dev/null; then $STD pip cache purge || true; fi
|
if command -v pip &>/dev/null; then $STD pip cache purge || true; fi
|
||||||
# Python uv
|
|
||||||
if command -v uv &>/dev/null; then $STD uv cache clear || true; fi
|
|
||||||
# Node.js npm
|
# Node.js npm
|
||||||
if command -v npm &>/dev/null; then $STD npm cache clean --force || true; fi
|
if command -v npm &>/dev/null; then $STD npm cache clean --force || true; fi
|
||||||
# Node.js yarn
|
# Node.js yarn
|
||||||
@@ -410,7 +408,6 @@ cleanup_lxc() {
|
|||||||
if command -v composer &>/dev/null; then $STD composer clear-cache || true; fi
|
if command -v composer &>/dev/null; then $STD composer clear-cache || true; fi
|
||||||
|
|
||||||
if command -v journalctl &>/dev/null; then
|
if command -v journalctl &>/dev/null; then
|
||||||
$STD journalctl --rotate || true
|
|
||||||
$STD journalctl --vacuum-time=10m || true
|
$STD journalctl --vacuum-time=10m || true
|
||||||
fi
|
fi
|
||||||
msg_ok "Cleaned"
|
msg_ok "Cleaned"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Button } from './ui/button';
|
import { Button } from './ui/button';
|
||||||
import { HelpCircle, Server, Settings, RefreshCw, Clock, Package, HardDrive, FolderOpen, Search, Download, Lock, GitBranch } from 'lucide-react';
|
import { HelpCircle, Server, Settings, RefreshCw, Clock, Package, HardDrive, FolderOpen, Search, Download, Lock, GitBranch, Archive } from 'lucide-react';
|
||||||
import { useRegisterModal } from './modal/ModalStackProvider';
|
import { useRegisterModal } from './modal/ModalStackProvider';
|
||||||
|
|
||||||
interface HelpModalProps {
|
interface HelpModalProps {
|
||||||
@@ -11,7 +11,7 @@ interface HelpModalProps {
|
|||||||
initialSection?: string;
|
initialSection?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type HelpSection = 'server-settings' | 'general-settings' | 'auth-settings' | 'sync-button' | 'auto-sync' | 'available-scripts' | 'downloaded-scripts' | 'installed-scripts' | 'lxc-settings' | 'update-system' | 'repositories';
|
type HelpSection = 'server-settings' | 'general-settings' | 'auth-settings' | 'sync-button' | 'auto-sync' | 'available-scripts' | 'downloaded-scripts' | 'installed-scripts' | 'lxc-settings' | 'update-system' | 'repositories' | 'backups';
|
||||||
|
|
||||||
export function HelpModal({ isOpen, onClose, initialSection = 'server-settings' }: HelpModalProps) {
|
export function HelpModal({ isOpen, onClose, initialSection = 'server-settings' }: HelpModalProps) {
|
||||||
useRegisterModal(isOpen, { id: 'help-modal', allowEscape: true, onClose });
|
useRegisterModal(isOpen, { id: 'help-modal', allowEscape: true, onClose });
|
||||||
@@ -30,6 +30,7 @@ export function HelpModal({ isOpen, onClose, initialSection = 'server-settings'
|
|||||||
{ id: 'downloaded-scripts' as HelpSection, label: 'Downloaded Scripts', icon: HardDrive },
|
{ id: 'downloaded-scripts' as HelpSection, label: 'Downloaded Scripts', icon: HardDrive },
|
||||||
{ id: 'installed-scripts' as HelpSection, label: 'Installed Scripts', icon: FolderOpen },
|
{ id: 'installed-scripts' as HelpSection, label: 'Installed Scripts', icon: FolderOpen },
|
||||||
{ id: 'lxc-settings' as HelpSection, label: 'LXC Settings', icon: Settings },
|
{ id: 'lxc-settings' as HelpSection, label: 'LXC Settings', icon: Settings },
|
||||||
|
{ id: 'backups' as HelpSection, label: 'LXC Backups', icon: Archive },
|
||||||
{ id: 'update-system' as HelpSection, label: 'Update System', icon: Download },
|
{ id: 'update-system' as HelpSection, label: 'Update System', icon: Download },
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -925,6 +926,144 @@ export function HelpModal({ isOpen, onClose, initialSection = 'server-settings'
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
case 'backups':
|
||||||
|
return (
|
||||||
|
<div className="space-y-6">
|
||||||
|
<div>
|
||||||
|
<h3 className="text-xl font-semibold text-foreground mb-4">LXC Backups</h3>
|
||||||
|
<p className="text-muted-foreground mb-6">
|
||||||
|
Create backups of your LXC containers before updates or on-demand. Backups are created using Proxmox VE's built-in backup system and can be stored on any backup-capable storage.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="p-4 border border-border rounded-lg bg-primary/10 border-primary/20">
|
||||||
|
<h4 className="font-medium text-foreground mb-2">Overview</h4>
|
||||||
|
<p className="text-sm text-muted-foreground mb-3">
|
||||||
|
The backup feature allows you to create snapshots of your LXC containers before performing updates or at any time. Backups are created using the <code className="bg-muted px-1 rounded">vzdump</code> command via SSH and stored on your configured Proxmox storage.
|
||||||
|
</p>
|
||||||
|
<ul className="text-sm text-muted-foreground space-y-1">
|
||||||
|
<li>• <strong>Pre-Update Backups:</strong> Automatically create backups before updating containers</li>
|
||||||
|
<li>• <strong>Standalone Backups:</strong> Create backups on-demand from the Actions menu</li>
|
||||||
|
<li>• <strong>Storage Selection:</strong> Choose from available backup-capable storages</li>
|
||||||
|
<li>• <strong>Real-Time Progress:</strong> View backup progress in the terminal output</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="p-4 border border-border rounded-lg">
|
||||||
|
<h4 className="font-medium text-foreground mb-2">Backup Before Update</h4>
|
||||||
|
<p className="text-sm text-muted-foreground mb-3">
|
||||||
|
When updating an LXC container, you can choose to create a backup first:
|
||||||
|
</p>
|
||||||
|
<ol className="text-sm text-muted-foreground space-y-2 list-decimal list-inside">
|
||||||
|
<li>Click the "Update" button for an installed script</li>
|
||||||
|
<li>Confirm that you want to update the container</li>
|
||||||
|
<li>Choose whether to create a backup before updating</li>
|
||||||
|
<li>If yes, select a backup-capable storage from the list</li>
|
||||||
|
<li>The backup will be created, then the update will proceed automatically</li>
|
||||||
|
</ol>
|
||||||
|
<div className="mt-3 p-3 bg-info/10 rounded-md">
|
||||||
|
<h5 className="font-medium text-info-foreground mb-2">Backup Failure Handling</h5>
|
||||||
|
<p className="text-xs text-info/80">
|
||||||
|
If a backup fails, you'll be warned but can still choose to proceed with the update. This ensures updates aren't blocked by backup issues.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="p-4 border border-border rounded-lg">
|
||||||
|
<h4 className="font-medium text-foreground mb-2">Standalone Backup</h4>
|
||||||
|
<p className="text-sm text-muted-foreground mb-3">
|
||||||
|
Create a backup at any time without updating:
|
||||||
|
</p>
|
||||||
|
<ol className="text-sm text-muted-foreground space-y-2 list-decimal list-inside">
|
||||||
|
<li>Open the Actions dropdown menu for an installed script</li>
|
||||||
|
<li>Click "Backup"</li>
|
||||||
|
<li>Select a backup-capable storage from the list</li>
|
||||||
|
<li>Watch the backup progress in the terminal output</li>
|
||||||
|
</ol>
|
||||||
|
<p className="text-xs text-muted-foreground mt-2">
|
||||||
|
<strong>Note:</strong> Standalone backups are only available for SSH-enabled scripts with valid container IDs.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="p-4 border border-border rounded-lg">
|
||||||
|
<h4 className="font-medium text-foreground mb-2">Storage Selection</h4>
|
||||||
|
<p className="text-sm text-muted-foreground mb-3">
|
||||||
|
The system automatically discovers backup-capable storages from your Proxmox servers:
|
||||||
|
</p>
|
||||||
|
<ul className="text-sm text-muted-foreground space-y-2">
|
||||||
|
<li>• <strong>Automatic Discovery:</strong> Storages are fetched from <code className="bg-muted px-1 rounded">/etc/pve/storage.cfg</code> on each server</li>
|
||||||
|
<li>• <strong>Backup-Capable Only:</strong> Only storages with "backup" in their content are shown</li>
|
||||||
|
<li>• <strong>Cached Results:</strong> Storage lists are cached for 1 hour to improve performance</li>
|
||||||
|
<li>• <strong>Manual Refresh:</strong> Use the "Fetch Storages" button to refresh the list if needed</li>
|
||||||
|
</ul>
|
||||||
|
<div className="mt-3 p-3 bg-muted/30 rounded-md">
|
||||||
|
<h5 className="font-medium text-foreground mb-1">Storage Types</h5>
|
||||||
|
<ul className="text-xs text-muted-foreground space-y-1">
|
||||||
|
<li>• <strong>Local:</strong> Backups stored on the Proxmox host</li>
|
||||||
|
<li>• <strong>Storage:</strong> Network-attached storage (NFS, CIFS, etc.)</li>
|
||||||
|
<li>• <strong>PBS:</strong> Proxmox Backup Server storage</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="p-4 border border-border rounded-lg">
|
||||||
|
<h4 className="font-medium text-foreground mb-2">Viewing Available Storages</h4>
|
||||||
|
<p className="text-sm text-muted-foreground mb-3">
|
||||||
|
You can view all storages for a server, including which ones support backups:
|
||||||
|
</p>
|
||||||
|
<ol className="text-sm text-muted-foreground space-y-2 list-decimal list-inside">
|
||||||
|
<li>Go to the Server Settings section</li>
|
||||||
|
<li>Find the server you want to check</li>
|
||||||
|
<li>Click the "View Storages" button (database icon)</li>
|
||||||
|
<li>See all storages with backup-capable ones highlighted</li>
|
||||||
|
</ol>
|
||||||
|
<p className="text-xs text-muted-foreground mt-2">
|
||||||
|
This helps you identify which storages are available for backups before starting a backup operation.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="p-4 border border-border rounded-lg">
|
||||||
|
<h4 className="font-medium text-foreground mb-2">Backup Process</h4>
|
||||||
|
<p className="text-sm text-muted-foreground mb-3">
|
||||||
|
When a backup is initiated, the following happens:
|
||||||
|
</p>
|
||||||
|
<ul className="text-sm text-muted-foreground space-y-2">
|
||||||
|
<li>• <strong>SSH Connection:</strong> Connects to the Proxmox server via SSH</li>
|
||||||
|
<li>• <strong>Command Execution:</strong> Runs <code className="bg-muted px-1 rounded">vzdump <CTID> --storage <STORAGE> --mode snapshot</code></li>
|
||||||
|
<li>• <strong>Real-Time Output:</strong> Backup progress is streamed to the terminal</li>
|
||||||
|
<li>• <strong>Completion:</strong> Backup completes and shows success/failure status</li>
|
||||||
|
<li>• <strong>Sequential Execution:</strong> If part of update flow, update proceeds after backup completes</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="p-4 border border-border rounded-lg bg-warning/10 border-warning/20">
|
||||||
|
<h4 className="font-medium text-warning-foreground mb-2">⚠️ Important Notes</h4>
|
||||||
|
<ul className="text-sm text-warning/80 space-y-2">
|
||||||
|
<li>• <strong>Storage Requirements:</strong> Ensure you have sufficient storage space for backups</li>
|
||||||
|
<li>• <strong>Backup Duration:</strong> Backup time depends on container size and storage speed</li>
|
||||||
|
<li>• <strong>Snapshot Mode:</strong> Backups use snapshot mode, which requires sufficient disk space</li>
|
||||||
|
<li>• <strong>SSH Access:</strong> Backups require valid SSH credentials configured for the server</li>
|
||||||
|
<li>• <strong>Container State:</strong> Containers can be running or stopped during backup</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="p-4 border border-border rounded-lg">
|
||||||
|
<h4 className="font-medium text-foreground mb-2">Backup Storage Cache</h4>
|
||||||
|
<p className="text-sm text-muted-foreground mb-3">
|
||||||
|
Storage information is cached to improve performance:
|
||||||
|
</p>
|
||||||
|
<ul className="text-sm text-muted-foreground space-y-1">
|
||||||
|
<li>• <strong>Cache Duration:</strong> Storage lists are cached for 1 hour</li>
|
||||||
|
<li>• <strong>Automatic Refresh:</strong> Cache expires and refreshes automatically</li>
|
||||||
|
<li>• <strong>Manual Refresh:</strong> Use "Fetch Storages" button to force refresh</li>
|
||||||
|
<li>• <strong>Per-Server Cache:</strong> Each server has its own cached storage list</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"moduleResolution": "Bundler",
|
"moduleResolution": "Bundler",
|
||||||
"jsx": "preserve",
|
"jsx": "react-jsx",
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
"name": "next"
|
"name": "next"
|
||||||
|
|||||||
Reference in New Issue
Block a user