mirror of
https://github.com/UNITRONIX/BetterDesk.git
synced 2026-10-26 14:30:19 +00:00
cead414395
Remove GitHub prebuilt server binary delivery from panel updates. Fetch only required source subtrees for the selected commit and compile the Go server locally while preserving existing deployment and rollback behavior. Refs: panel update local build path Thanks: INSOLVE (Honorary); Marco Jakobs (@jacotec); MyNameisStitch (@MyNameisStitch); Redspin (@playerumpknow)
164 lines
6.1 KiB
JavaScript
Executable File
164 lines
6.1 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
'use strict';
|
|
|
|
const readline = require('readline');
|
|
const updateService = require('../services/updateService');
|
|
|
|
const args = new Set(process.argv.slice(2));
|
|
const yes = args.has('--yes') || args.has('-y') || args.has('--auto');
|
|
const dryRun = args.has('--check') || args.has('--dry-run');
|
|
const createBackup = !args.has('--no-backup');
|
|
|
|
function step(index, total, message) {
|
|
console.log(`[${index}/${total}] ${message}`);
|
|
}
|
|
|
|
function printComponents(components) {
|
|
const entries = Object.entries(components || {}).filter(([, info]) => info.changed);
|
|
if (!entries.length) return;
|
|
console.log('Changed components:');
|
|
for (const [name, info] of entries) {
|
|
const mode = info.autoUpdate ? 'auto' : 'manual';
|
|
console.log(` - ${info.label || name}: ${info.fileCount || 0} file(s), ${mode}`);
|
|
}
|
|
}
|
|
|
|
function ask(question) {
|
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
return new Promise(resolve => {
|
|
rl.question(question, answer => {
|
|
rl.close();
|
|
resolve(answer.trim());
|
|
});
|
|
});
|
|
}
|
|
|
|
function summarizeResult(result) {
|
|
console.log('Update summary:');
|
|
console.log(` Applied: ${result.applied?.length || 0}`);
|
|
console.log(` Removed: ${result.removed?.length || 0}`);
|
|
console.log(` Skipped: ${result.skipped?.length || 0}`);
|
|
console.log(` Backup: ${result.backupPath || 'not created'}`);
|
|
if (result.serverBuild) {
|
|
console.log(` Go server build: ${result.serverBuild.success ? 'ok' : 'failed'} (${result.serverBuild.method})`);
|
|
}
|
|
if (result.serverDeploy) {
|
|
console.log(` Go server deploy: ${result.serverDeploy.success ? 'ok' : 'failed'}`);
|
|
}
|
|
if (result.serverServiceConfig?.changed) {
|
|
console.log(` Service config: ${result.serverServiceConfig.changes.join('; ')}`);
|
|
}
|
|
if (result.toolchainInstall) {
|
|
console.log(` Go toolchain: ${result.toolchainInstall.success ? 'ready' : 'failed'}`);
|
|
}
|
|
if (result.failed?.length) {
|
|
console.log('Failures:');
|
|
for (const failure of result.failed) {
|
|
console.log(` - ${failure.file}: ${failure.error}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
console.log('BetterDesk terminal updater');
|
|
console.log('Using the same update engine as the web console.');
|
|
console.log('');
|
|
|
|
step(1, 6, 'Checking remote update state');
|
|
const check = await updateService.checkForUpdates();
|
|
if (check.baselineEstablished) {
|
|
console.log(`Baseline established at ${check.remoteSHA.slice(0, 7)}. No update applied.`);
|
|
return;
|
|
}
|
|
if (!check.updateAvailable) {
|
|
console.log(`Already up to date (${check.remoteSHA.slice(0, 7)}).`);
|
|
return;
|
|
}
|
|
|
|
console.log(`Local SHA: ${check.localSHA || 'unknown'}`);
|
|
console.log(`Remote SHA: ${check.remoteSHA}`);
|
|
console.log(`Commits behind: ${check.commitsBehind}`);
|
|
printComponents(check.components);
|
|
|
|
step(2, 6, 'Loading changed file list');
|
|
const changedData = await updateService.getChangedFiles(check.remoteSHA);
|
|
console.log(`Changed files: ${changedData.totalFiles}`);
|
|
for (const commit of changedData.commits.slice(0, 5)) {
|
|
console.log(` - ${commit.sha} ${commit.message}`);
|
|
}
|
|
|
|
if (dryRun) {
|
|
console.log('Dry run complete. No files were changed.');
|
|
return;
|
|
}
|
|
|
|
if (!yes) {
|
|
const answer = await ask('Apply this update now? [y/N] ');
|
|
if (!/^y(es)?$/i.test(answer)) {
|
|
console.log('Update cancelled.');
|
|
return;
|
|
}
|
|
}
|
|
|
|
step(3, 6, createBackup ? 'Creating backup and applying files' : 'Applying files without backup');
|
|
const result = await updateService.applyUpdate(check.remoteSHA, changedData, {
|
|
createBackup
|
|
});
|
|
|
|
step(4, 6, 'Summarizing result');
|
|
summarizeResult(result);
|
|
|
|
// Distinguish critical failures (file download/write errors) from
|
|
// non-critical ones (server binary deployment problems — source was still
|
|
// applied). See issue #154: server binary failures caused infinite
|
|
// update loop because SHA was never saved.
|
|
const criticalFailures = (result.failed || []).filter(f =>
|
|
!updateService.isNonCriticalUpdateFailure(f.file) && !f.nonCritical
|
|
);
|
|
const nonCriticalFailures = (result.failed || []).filter(f =>
|
|
updateService.isNonCriticalUpdateFailure(f.file) || f.nonCritical
|
|
);
|
|
|
|
if (criticalFailures.length) {
|
|
console.log(`\n${criticalFailures.length} critical failure(s) — update incomplete.`);
|
|
process.exitCode = 1;
|
|
return;
|
|
}
|
|
if (nonCriticalFailures.length) {
|
|
console.log(`\n${nonCriticalFailures.length} non-critical issue(s) (server binary not built or deployed).`);
|
|
console.log('Console and script files were applied successfully. Rebuild Go server manually if needed.');
|
|
}
|
|
|
|
step(5, 6, 'Restarting affected services');
|
|
if (result.needsServerRestart) {
|
|
const serviceName = process.platform === 'win32' ? 'BetterDeskServer' : 'betterdesk-server';
|
|
const restart = updateService.restartService(serviceName);
|
|
if (restart.success) console.log(` - ${serviceName}: restarted`);
|
|
else {
|
|
console.log(` - ${serviceName}: restart failed (${restart.error})`);
|
|
process.exitCode = 1;
|
|
}
|
|
}
|
|
if (result.needsConsoleRestart) {
|
|
const serviceName = process.platform === 'win32' ? 'BetterDeskConsole' : 'betterdesk-console';
|
|
const restart = updateService.restartService(serviceName);
|
|
if (restart.success) console.log(` - ${serviceName}: restarted`);
|
|
else {
|
|
console.log(` - ${serviceName}: restart failed (${restart.error})`);
|
|
process.exitCode = 1;
|
|
}
|
|
}
|
|
if (!result.needsServerRestart && !result.needsConsoleRestart) {
|
|
console.log(' - No service restart required');
|
|
}
|
|
|
|
step(6, 6, 'Done');
|
|
if (result.shaSaved) {
|
|
console.log(`Updated baseline SHA to ${check.remoteSHA.slice(0, 7)}.`);
|
|
}
|
|
}
|
|
|
|
main().catch(err => {
|
|
console.error(`Update failed: ${err.message}`);
|
|
process.exitCode = 1;
|
|
}); |