mirror of
https://github.com/UNITRONIX/BetterDesk.git
synced 2026-09-10 09:35:39 +00:00
db0dfade24
Default C:\BetterDeskConsole installs no longer treat C:\ as the project root, so installer file writes and SHA tracking succeed; NSSM Access Denied on server restart is non-critical.
104 lines
3.2 KiB
JavaScript
104 lines
3.2 KiB
JavaScript
'use strict';
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const NON_CRITICAL_UPDATE_FAILURES = new Set([
|
|
'betterdesk-server',
|
|
'betterdesk-server-deploy',
|
|
'betterdesk-server.service',
|
|
'server-source',
|
|
'npm install',
|
|
'support-agent-source-sync',
|
|
// Installer / Docker root files — optional beside the console; EACCES/EPERM
|
|
// on these must not block SHA save (Windows drive-root bug #272, Linux root-owned /opt).
|
|
'betterdesk.sh',
|
|
'betterdesk.ps1',
|
|
'betterdesk-docker.sh',
|
|
'docker-compose.yml',
|
|
'docker-compose.single.yml',
|
|
'docker-compose.quick.yml',
|
|
'docker-compose.quick.single.yml',
|
|
'docker-compose.quick.single.macvlan.yml',
|
|
'Dockerfile',
|
|
'Dockerfile.server',
|
|
'Dockerfile.console',
|
|
'VERSION',
|
|
]);
|
|
|
|
function isNonCriticalUpdateFailure(fileKey) {
|
|
return NON_CRITICAL_UPDATE_FAILURES.has(fileKey);
|
|
}
|
|
|
|
function localPathFromFailureFile(fileKey) {
|
|
if (!fileKey || typeof fileKey !== 'string') return '';
|
|
return fileKey.startsWith('web-nodejs/') ? fileKey.slice('web-nodejs/'.length) : fileKey;
|
|
}
|
|
|
|
/** Repair step asked for a path Node never loads (routes.js, duplicated scripts/). */
|
|
function isPhantomRepairFailure(fileKey, rootDir) {
|
|
const localPath = localPathFromFailureFile(fileKey);
|
|
if (!localPath || !rootDir) return false;
|
|
if (localPath === 'routes.js') {
|
|
return fs.existsSync(path.join(rootDir, 'routes', 'index.js'));
|
|
}
|
|
if (/^scripts\/scripts\//.test(localPath)) return true;
|
|
if (localPath.endsWith('.js')) {
|
|
const indexPath = path.join(rootDir, `${localPath.slice(0, -3)}`, 'index.js');
|
|
if (fs.existsSync(indexPath)) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function isFailureNonCritical(entry, rootDir) {
|
|
if (!entry) return false;
|
|
if (entry.nonCritical) return true;
|
|
if (isNonCriticalUpdateFailure(entry.file)) return true;
|
|
if (entry.file === 'npm install' && entry.nodeModulesOk) return true;
|
|
if (isPhantomRepairFailure(entry.file, rootDir)) return true;
|
|
return false;
|
|
}
|
|
|
|
function splitUpdateFailures(failed, rootDir) {
|
|
const critical = [];
|
|
const nonCritical = [];
|
|
for (const entry of failed || []) {
|
|
if (isFailureNonCritical(entry, rootDir)) nonCritical.push(entry);
|
|
else critical.push(entry);
|
|
}
|
|
return { critical, nonCritical };
|
|
}
|
|
|
|
function canScheduleConsoleRestart(result, dataDir) {
|
|
if (!result?.needsConsoleRestart) {
|
|
return { allowed: false };
|
|
}
|
|
const patch = result.servicePatch || {};
|
|
if (patch.consolePermissionsOk !== false) {
|
|
return { allowed: true };
|
|
}
|
|
try {
|
|
fs.accessSync(dataDir, fs.constants.W_OK);
|
|
return {
|
|
allowed: true,
|
|
note: 'Console data directory is writable — restart allowed despite permission-sync warning',
|
|
};
|
|
} catch (_) {
|
|
return {
|
|
allowed: false,
|
|
blockedReason: patch.consoleUserError
|
|
|| `Console data directory is not writable: ${dataDir}`,
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
NON_CRITICAL_UPDATE_FAILURES,
|
|
isNonCriticalUpdateFailure,
|
|
isPhantomRepairFailure,
|
|
isFailureNonCritical,
|
|
splitUpdateFailures,
|
|
canScheduleConsoleRestart,
|
|
localPathFromFailureFile,
|
|
};
|