feat(nixserver): version display and one-click panel upgrade
Add version badge to sidebar footer showing installed vs latest version, fetched from /api/nixserver/system/version. Badge shows green when up to date or amber with target version when an update is available. Upgrade button triggers POST /api/nixserver/system/upgrade which spawns scripts/update.sh detached (git pull + npm install + prisma migrate + build + restart). Response is returned before the service restarts so the client receives confirmation. Panel comes back online in ~60 s.
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nixpanel/server",
|
||||
"version": "0.4.2",
|
||||
"version": "0.4.3",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ export async function buildApp() {
|
||||
|
||||
fastify.get('/api/health', async () => ({
|
||||
status: 'ok',
|
||||
version: '0.4.2',
|
||||
version: '0.4.3',
|
||||
timestamp: new Date().toISOString(),
|
||||
}))
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import type { FastifyInstance } from 'fastify'
|
||||
import { spawn } from 'child_process'
|
||||
import prisma from '../../db/client.js'
|
||||
import { requireAdmin } from '../../middleware/auth.js'
|
||||
import { getSystemStats } from '../../core/system.js'
|
||||
import { exec } from '../../core/exec.js'
|
||||
import { readFile } from 'fs/promises'
|
||||
|
||||
const INSTALL_DIR = process.env.INSTALL_DIR ?? '/opt/nixpanel'
|
||||
|
||||
export default async function systemRoutes(fastify: FastifyInstance) {
|
||||
// GET /api/nixserver/system/stats
|
||||
fastify.get('/stats', { preHandler: [requireAdmin] }, async (request, reply) => {
|
||||
@@ -121,4 +124,56 @@ export default async function systemRoutes(fastify: FastifyInstance) {
|
||||
|
||||
return reply.send({ success: true, data: { message: 'Settings updated' } })
|
||||
})
|
||||
|
||||
// GET /api/nixserver/system/version
|
||||
// Returns the installed version and checks GitHub for the latest available version.
|
||||
fastify.get('/version', { preHandler: [requireAdmin] }, async (_request, reply) => {
|
||||
// Read installed version from package.json
|
||||
let currentVersion = '0.0.0'
|
||||
try {
|
||||
const pkg = JSON.parse(await readFile(`${INSTALL_DIR}/package.json`, 'utf8'))
|
||||
currentVersion = pkg.version ?? '0.0.0'
|
||||
} catch { /* running in dev or non-standard path */ }
|
||||
|
||||
// Check GitHub for latest version (5 s timeout, non-fatal)
|
||||
let latestVersion: string | null = null
|
||||
try {
|
||||
const resp = await fetch(
|
||||
'https://raw.githubusercontent.com/NixReaper/nixpanel-server/main/package.json',
|
||||
{ signal: AbortSignal.timeout(5_000) }
|
||||
)
|
||||
if (resp.ok) {
|
||||
const json = await resp.json() as { version?: string }
|
||||
latestVersion = json.version ?? null
|
||||
}
|
||||
} catch { /* offline or rate-limited */ }
|
||||
|
||||
return reply.send({
|
||||
success: true,
|
||||
data: {
|
||||
currentVersion,
|
||||
latestVersion,
|
||||
updateAvailable: latestVersion !== null && latestVersion !== currentVersion,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
// POST /api/nixserver/system/upgrade
|
||||
// Fires the update script in the background and returns immediately.
|
||||
// The service will restart ~60 s later once the build finishes.
|
||||
fastify.post('/upgrade', { preHandler: [requireAdmin] }, async (_request, reply) => {
|
||||
reply.send({
|
||||
success: true,
|
||||
data: { message: 'Upgrade started. The panel will be back online in about 60 seconds.' },
|
||||
})
|
||||
|
||||
// Delay slightly to ensure the HTTP response is flushed before the service restarts
|
||||
setTimeout(() => {
|
||||
const child = spawn('bash', [`${INSTALL_DIR}/scripts/update.sh`], {
|
||||
detached: true,
|
||||
stdio: 'ignore',
|
||||
})
|
||||
child.unref()
|
||||
}, 800)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user