Compare commits

...

13 Commits

Author SHA1 Message Date
CanbiZ
60f81fabc3 Improve server startup logging and update script fetching
Adds success and error logging to the Next.js app preparation process in server.js, including guidance for missing production builds. In versionRouter, always fetches the latest update.sh from GitHub before running updates, logging the outcome and falling back to the local script if fetching fails.
2026-01-13 18:00:53 +01:00
github-actions[bot]
414c356446 chore: add VERSION v0.5.4 (#441)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-13 16:05:32 +00:00
CanbiZ
c38ded7a39 Update dependencies in package-lock.json
Upgraded multiple dependencies and devDependencies to their latest versions, including @prisma, @tanstack/react-query, next, eslint, typescript-eslint, and others. This ensures compatibility, security, and access to new features and bug fixes.
2026-01-13 17:03:21 +01:00
CanbiZ
0cfed84cd0 update package.json 2026-01-13 16:56:58 +01:00
CanbiZ (MickLesk)
9611bc9bcf Improve Node.js upgrade and service recovery in update.sh (#440)
Enhances the Node.js upgrade process by handling both .list and .sources files, updating the apt cache, and adding error handling for download and install failures. Introduces a function to re-enable and start the systemd service on failure to prevent user lockout, and ensures this is called during rollback and upgrade errors. Also refines Node.js version checks and build environment setup.
2026-01-13 16:53:37 +01:00
dependabot[bot]
6fe2a790fd build(deps): Bump @xterm/xterm from 5.5.0 to 6.0.0 (#431)
Bumps [@xterm/xterm](https://github.com/xtermjs/xterm.js) from 5.5.0 to 6.0.0.
- [Release notes](https://github.com/xtermjs/xterm.js/releases)
- [Commits](https://github.com/xtermjs/xterm.js/compare/5.5.0...6.0.0)

---
updated-dependencies:
- dependency-name: "@xterm/xterm"
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-13 16:47:18 +01:00
Bryan Lieberman
5ea71837e7 Fix nodejs update failure (#435)
* fix: update fails during NodeJS Version check

- Removed redundant NodeJS Update call

* fix: update fails after nodejs version check (#429)

- Removed redundant nodejs update call
2026-01-13 16:47:05 +01:00
dependabot[bot]
bf5ebc72b6 build(deps-dev): Bump @vitest/coverage-v8 from 4.0.15 to 4.0.16 (#434)
Bumps [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) from 4.0.15 to 4.0.16.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.16/packages/coverage-v8)

---
updated-dependencies:
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 4.0.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-13 16:46:25 +01:00
dependabot[bot]
a32c7bcbba build(deps): Bump lucide-react from 0.561.0 to 0.562.0 (#433)
Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 0.561.0 to 0.562.0.
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/0.562.0/packages/lucide-react)

---
updated-dependencies:
- dependency-name: lucide-react
  dependency-version: 0.562.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-13 16:46:14 +01:00
dependabot[bot]
98c6e79db6 build(deps-dev): Bump @testing-library/react from 16.3.0 to 16.3.1 (#432)
Bumps [@testing-library/react](https://github.com/testing-library/react-testing-library) from 16.3.0 to 16.3.1.
- [Release notes](https://github.com/testing-library/react-testing-library/releases)
- [Changelog](https://github.com/testing-library/react-testing-library/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testing-library/react-testing-library/compare/v16.3.0...v16.3.1)

---
updated-dependencies:
- dependency-name: "@testing-library/react"
  dependency-version: 16.3.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-13 16:46:05 +01:00
dependabot[bot]
c962a9cd5a build(deps): Bump @xterm/addon-web-links from 0.11.0 to 0.12.0 (#430)
Bumps [@xterm/addon-web-links](https://github.com/xtermjs/xterm.js) from 0.11.0 to 0.12.0.
- [Release notes](https://github.com/xtermjs/xterm.js/releases)
- [Commits](https://github.com/xtermjs/xterm.js/compare/0.11...0.12)

---
updated-dependencies:
- dependency-name: "@xterm/addon-web-links"
  dependency-version: 0.12.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-13 16:45:53 +01:00
CanbiZ
5d20a6d694 fix: allow update without existing database file
Database verification now allows missing database files for new
installations. The app will create the database automatically
via Prisma migrations on first start.
2026-01-07 20:54:16 +01:00
github-actions[bot]
cb4e8c543a chore: add VERSION v0.5.3 (#428)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-07 19:52:06 +00:00
6 changed files with 653 additions and 625 deletions

View File

@@ -1 +1 @@
0.5.2
0.5.4

841
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -25,33 +25,33 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@prisma/adapter-better-sqlite3": "^7.1.0",
"@prisma/client": "^7.1.0",
"@prisma/adapter-better-sqlite3": "^7.2.0",
"@prisma/client": "^7.2.0",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-slot": "^1.2.4",
"@t3-oss/env-nextjs": "^0.13.10",
"@tailwindcss/typography": "^0.5.19",
"@tanstack/react-query": "^5.90.12",
"@trpc/client": "^11.8.0",
"@tanstack/react-query": "^5.90.16",
"@trpc/client": "^11.8.1",
"@trpc/react-query": "^11.8.1",
"@trpc/server": "^11.8.0",
"@trpc/server": "^11.8.1",
"@types/react-syntax-highlighter": "^15.5.13",
"@types/ws": "^8.18.1",
"@xterm/addon-fit": "^0.10.0",
"@xterm/addon-web-links": "^0.11.0",
"@xterm/xterm": "^5.5.0",
"@xterm/addon-fit": "^0.11.0",
"@xterm/addon-web-links": "^0.12.0",
"@xterm/xterm": "^6.0.0",
"axios": "^1.13.2",
"bcryptjs": "^3.0.3",
"better-sqlite3": "^12.5.0",
"better-sqlite3": "^12.6.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cron-validator": "^1.4.0",
"dotenv": "^17.2.3",
"jsonwebtoken": "^9.0.3",
"lucide-react": "^0.561.0",
"next": "^16.0.10",
"lucide-react": "^0.562.0",
"next": "^16.1.1",
"node-cron": "^4.2.1",
"node-pty": "^1.0.0",
"node-pty": "^1.1.0",
"react": "^19.2.3",
"react-dom": "^19.2.3",
"react-markdown": "^10.1.0",
@@ -62,37 +62,37 @@
"strip-ansi": "^7.1.2",
"superjson": "^2.2.6",
"tailwind-merge": "^3.4.0",
"ws": "^8.18.3",
"zod": "^4.1.13"
"ws": "^8.19.0",
"zod": "^4.3.5"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.1.18",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.0",
"@testing-library/react": "^16.3.1",
"@testing-library/user-event": "^14.6.1",
"@types/bcryptjs": "^3.0.0",
"@types/better-sqlite3": "^7.6.13",
"@types/jsonwebtoken": "^9.0.10",
"@types/node": "^24.10.4",
"@types/node-cron": "^3.0.11",
"@types/react": "^19.2.7",
"@types/react": "^19.2.8",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.2",
"@vitest/coverage-v8": "^4.0.15",
"@vitest/ui": "^4.0.14",
"baseline-browser-mapping": "^2.9.3",
"eslint": "^9.39.1",
"eslint-config-next": "^16.1.0",
"jsdom": "^27.3.0",
"@vitest/coverage-v8": "^4.0.17",
"@vitest/ui": "^4.0.17",
"baseline-browser-mapping": "^2.9.14",
"eslint": "^9.39.2",
"eslint-config-next": "^16.1.1",
"jsdom": "^27.4.0",
"postcss": "^8.5.6",
"prettier": "^3.7.4",
"prettier-plugin-tailwindcss": "^0.7.2",
"prisma": "^7.1.0",
"prisma": "^7.2.0",
"tailwindcss": "^4.1.18",
"tsx": "^4.21.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.48.1",
"vitest": "^4.0.14"
"typescript-eslint": "^8.53.0",
"vitest": "^4.0.17"
},
"ct3aMetadata": {
"initVersion": "7.39.3"

View File

@@ -1610,6 +1610,7 @@ class ScriptExecutionHandler {
// TerminalHandler removed - not used by current application
app.prepare().then(() => {
console.log('> Next.js app prepared successfully');
const httpServer = createServer(async (req, res) => {
try {
// Be sure to pass `true` as the second argument to `url.parse`.
@@ -1715,4 +1716,9 @@ app.prepare().then(() => {
autoSyncModule.setupGracefulShutdown();
}
});
}).catch((err) => {
console.error('> Failed to start server:', err.message);
console.error('> If you see "Could not find a production build", run: npm run build');
console.error('> Full error:', err);
process.exit(1);
});

View File

@@ -238,6 +238,27 @@ export const versionRouter = createTRPCRouter({
// Clear/create the log file
await writeFile(logPath, '', 'utf-8');
// Always fetch the latest update.sh from GitHub before running
// This ensures we always use the newest update script, avoiding
// the "chicken-and-egg" problem where old scripts can't update properly
const updateScriptUrl = 'https://raw.githubusercontent.com/community-scripts/ProxmoxVE-Local/main/update.sh';
try {
const response = await fetch(updateScriptUrl);
if (response.ok) {
const latestScript = await response.text();
await writeFile(updateScriptPath, latestScript, { mode: 0o755 });
// Log that we fetched the latest script
await writeFile(logPath, '[INFO] Fetched latest update.sh from GitHub\n', { flag: 'a' });
} else {
// If fetch fails, log warning but continue with local script
await writeFile(logPath, `[WARNING] Could not fetch latest update.sh (HTTP ${response.status}), using local version\n`, { flag: 'a' });
}
} catch (fetchError) {
// If fetch fails, log warning but continue with local script
const errorMsg = fetchError instanceof Error ? fetchError.message : 'Unknown error';
await writeFile(logPath, `[WARNING] Could not fetch latest update.sh: ${errorMsg}, using local version\n`, { flag: 'a' });
}
// Spawn the update script as a detached process using nohup
// This allows it to run independently and kill the parent Node.js process
// Redirect output to log file

108
update.sh
View File

@@ -4,7 +4,7 @@
# Enhanced update script for ProxmoxVE-Local
# Fetches latest release from GitHub and backs up data directory
set -euo pipefail # Exit on error, undefined vars, pipe failures
set -euo pipefail # Exit on error, undefined vars, pipe failures
# Add error trap for debugging
trap 'echo "Error occurred at line $LINENO, command: $BASH_COMMAND"' ERR
@@ -72,7 +72,7 @@ load_github_token() {
# Initialize log file
init_log() {
# Clear/create log file
> "$LOG_FILE"
>"$LOG_FILE"
log "Starting ProxmoxVE-Local update process..."
log "Log file: $LOG_FILE"
}
@@ -100,19 +100,19 @@ check_dependencies() {
local missing_deps=()
if ! command -v curl &> /dev/null; then
if ! command -v curl &>/dev/null; then
missing_deps+=("curl")
fi
if ! command -v jq &> /dev/null; then
if ! command -v jq &>/dev/null; then
missing_deps+=("jq")
fi
if ! command -v npm &> /dev/null; then
if ! command -v npm &>/dev/null; then
missing_deps+=("npm")
fi
if ! command -v node &> /dev/null; then
if ! command -v node &>/dev/null; then
missing_deps+=("node")
fi
@@ -418,6 +418,12 @@ restore_backup_files() {
verify_database_restored() {
log "Verifying database was restored correctly..."
# Ensure data directory exists (will be auto-created by app if needed)
if [ ! -d "data" ]; then
log "Creating data directory..."
mkdir -p data
fi
# Check for both possible database filenames
local db_file=""
if [ -f "data/database.sqlite" ]; then
@@ -425,14 +431,16 @@ verify_database_restored() {
elif [ -f "data/settings.db" ]; then
db_file="data/settings.db"
else
log_error "Database file not found after restore! (checked database.sqlite and settings.db)"
return 1
# Database doesn't exist yet - this is OK for new installations
# The app will create it automatically via Prisma migrations
log_warning "No existing database file found - will be created automatically on first start"
return 0
fi
local db_size=$(stat -f%z "$db_file" 2>/dev/null || stat -c%s "$db_file" 2>/dev/null)
if [ "$db_size" -eq 0 ]; then
log_warning "Database file is empty - will be recreated by Prisma migrations"
return 0 # Don't fail the update, let Prisma recreate the database
return 0 # Don't fail the update, let Prisma recreate the database
fi
log_success "Database verified (file: $db_file, size: $db_size bytes)"
@@ -461,9 +469,9 @@ ensure_database_url() {
# Add DATABASE_URL to .env file
log "Adding DATABASE_URL to .env file..."
echo "" >> .env
echo "# Database" >> .env
echo "DATABASE_URL=\"file:./data/settings.db\"" >> .env
echo "" >>.env
echo "# Database" >>.env
echo "DATABASE_URL=\"file:./data/settings.db\"" >>.env
log_success "DATABASE_URL added to .env file"
}
@@ -481,11 +489,9 @@ check_service() {
fi
}
# Stop the application before updating
stop_application() {
# Change to the application directory if we're not already there
local app_dir
if [ -f "package.json" ] && [ -f "server.js" ]; then
@@ -577,7 +583,7 @@ update_files() {
# Create a temporary file list to avoid process substitution issues
local file_list="/tmp/file_list_$$.txt"
find "$actual_source_dir" -type f > "$file_list"
find "$actual_source_dir" -type f >"$file_list"
while IFS= read -r file; do
local rel_path="${file#$actual_source_dir/}"
@@ -606,7 +612,7 @@ update_files() {
else
files_excluded=$((files_excluded + 1))
fi
done < "$file_list"
done <"$file_list"
# Clean up temporary file
rm -f "$file_list"
@@ -624,7 +630,6 @@ update_files() {
log_success "Application files updated successfully ($files_copied files)"
}
# Install dependencies and build
install_and_build() {
log "Installing dependencies..."
@@ -647,7 +652,7 @@ install_and_build() {
export NODE_ENV=development
# Run npm install to get ALL dependencies including devDependencies
if ! npm install --include=dev > "$npm_log" 2>&1; then
if ! npm install --include=dev >"$npm_log" 2>&1; then
log_error "Failed to install dependencies"
log_error "npm install output (last 30 lines):"
tail -30 "$npm_log" | while read -r line; do
@@ -669,7 +674,7 @@ install_and_build() {
# Generate Prisma client
log "Generating Prisma client..."
if ! npx prisma generate > "$npm_log" 2>&1; then
if ! npx prisma generate >"$npm_log" 2>&1; then
log_error "Failed to generate Prisma client"
log_error "Prisma generate output:"
cat "$npm_log" | while read -r line; do
@@ -691,7 +696,7 @@ install_and_build() {
# Run Prisma migrations
log "Running Prisma migrations..."
if ! npx prisma migrate deploy > "$npm_log" 2>&1; then
if ! npx prisma migrate deploy >"$npm_log" 2>&1; then
log_warning "Prisma migrations failed or no migrations to run"
log "Prisma migrate output:"
cat "$npm_log" | while read -r line; do
@@ -705,11 +710,14 @@ install_and_build() {
log "Building application..."
# Set NODE_ENV to production for build
export NODE_ENV=production
# Unset TURBOPACK to prevent "Multiple bundler flags" error with --webpack
unset TURBOPACK 2>/dev/null || true
export TURBOPACK=''
# Create temporary file for npm build output
local build_log="/tmp/npm_build_$$.log"
if ! npm run build > "$build_log" 2>&1; then
if ! TURBOPACK='' npm run build >"$build_log" 2>&1; then
log_error "Failed to build application"
log_error "npm run build output:"
cat "$build_log" | while read -r line; do
@@ -763,7 +771,7 @@ start_with_npm() {
log "Starting application with npm start..."
# Start in background
nohup npm start > server.log 2>&1 &
nohup npm start >server.log 2>&1 &
local npm_pid=$!
# Wait a moment and check if it started
@@ -776,6 +784,23 @@ start_with_npm() {
fi
}
# Re-enable the systemd service on failure to prevent users from being locked out
re_enable_service_on_failure() {
if check_service; then
log "Re-enabling systemd service after failure..."
if systemctl enable pvescriptslocal.service 2>/dev/null; then
log_success "Service re-enabled"
if systemctl start pvescriptslocal.service 2>/dev/null; then
log_success "Service started"
else
log_warning "Failed to start service - manual intervention may be required"
fi
else
log_warning "Failed to re-enable service - manual intervention may be required"
fi
fi
}
# Rollback function
rollback() {
log_warning "Rolling back to previous version..."
@@ -847,6 +872,9 @@ rollback() {
log_error "No backup directory found for rollback"
fi
# Re-enable the service so users aren't locked out
re_enable_service_on_failure
log_error "Update failed. Please check the logs and try again."
exit 1
}
@@ -865,14 +893,14 @@ check_node_version() {
log "Detected Node.js version: $current"
if (( major_version < 24 )); then
if ((major_version == 24)); then
log_success "Node.js 24 already installed"
elif ((major_version < 24)); then
log_warning "Node.js < 24 detected → upgrading to Node.js 24 LTS..."
upgrade_node_to_24
elif (( major_version > 24 )); then
else
log_warning "Node.js > 24 detected → script tested only up to Node 24"
log "Continuing anyway…"
else
log_success "Node.js 24 already installed"
fi
}
@@ -880,22 +908,39 @@ check_node_version() {
upgrade_node_to_24() {
log "Preparing Node.js 24 upgrade…"
# Remove old nodesource repo if it exists
# Remove old nodesource repo files if they exist
if [ -f /etc/apt/sources.list.d/nodesource.list ]; then
log "Removing old nodesource.list file..."
rm -f /etc/apt/sources.list.d/nodesource.list
fi
if [ -f /etc/apt/sources.list.d/nodesource.sources ]; then
log "Removing old nodesource.sources file..."
rm -f /etc/apt/sources.list.d/nodesource.sources
fi
# Update apt cache first
log "Updating apt cache..."
apt-get update >>"$LOG_FILE" 2>&1 || true
# Install NodeSource repo for Node.js 24
curl -fsSL https://deb.nodesource.com/setup_24.x -o /tmp/node24_setup.sh
if ! bash /tmp/node24_setup.sh > /tmp/node24_setup.log 2>&1; then
log "Downloading Node.js 24 setup script..."
if ! curl -fsSL https://deb.nodesource.com/setup_24.x -o /tmp/node24_setup.sh; then
log_error "Failed to download Node.js 24 setup script"
re_enable_service_on_failure
exit 1
fi
if ! bash /tmp/node24_setup.sh >/tmp/node24_setup.log 2>&1; then
log_error "Failed to configure Node.js 24 repository"
tail -20 /tmp/node24_setup.log | while read -r line; do log_error "$line"; done
re_enable_service_on_failure
exit 1
fi
log "Installing Node.js 24…"
if ! apt-get install -y nodejs >> "$LOG_FILE" 2>&1; then
if ! apt-get install -y nodejs >>"$LOG_FILE" 2>&1; then
log_error "Failed to install Node.js 24"
re_enable_service_on_failure
exit 1
fi
@@ -970,9 +1015,6 @@ main() {
# Check Node.js version
check_node_version
#Update Node.js to 24
upgrade_node_to_24
# Download and extract release
local source_dir
source_dir=$(download_release "$release_info")