diff --git a/package.json b/package.json index 3ee61e562f..822560e717 100644 --- a/package.json +++ b/package.json @@ -536,6 +536,11 @@ "url": "" } ], + "releaseInfo": { + "vendor": { + "minGlibcVersion": "2.31" + } + }, "extraResources": [ { "from": "build", diff --git a/ts/updater/common.main.ts b/ts/updater/common.main.ts index b600022f64..366d77b302 100644 --- a/ts/updater/common.main.ts +++ b/ts/updater/common.main.ts @@ -69,7 +69,8 @@ const { throttle } = lodash; const POLL_INTERVAL = 30 * durations.MINUTE; -type JSONVendorSchema = { +export type JSONVendorSchema = { + minGlibcVersion?: string; minOSVersion?: string; requireManualUpdate?: 'true' | 'false'; requireUserConfirmation?: 'true' | 'false'; @@ -244,6 +245,31 @@ export abstract class Updater { ipcMain.handleOnce('start-update', performUpdateCallback); } + protected checkSystemRequirements(vendor: JSONVendorSchema): boolean { + if (vendor.requireManualUpdate === 'true') { + this.logger.warn('checkSystemRequirements: manual update required'); + this.markCannotUpdate( + new Error('yaml file has requireManualUpdate flag'), + DialogType.Cannot_Update_Require_Manual + ); + return false; + } + + if (vendor.minOSVersion && lt(osRelease(), vendor.minOSVersion)) { + this.logger.warn( + `checkSystemRequirements: OS version ${osRelease()} is less than the ` + + `minimum supported version ${vendor.minOSVersion}` + ); + this.markCannotUpdate( + new Error('yaml file has unsatisfied minOSVersion value'), + DialogType.UnsupportedOS + ); + return false; + } + + return true; + } + protected markCannotUpdate( error: Error, dialogType = DialogType.Cannot_Update @@ -563,27 +589,8 @@ export abstract class Updater { const parsedYaml = parseYaml(yaml); const { vendor } = parsedYaml; - if (vendor) { - if (vendor.requireManualUpdate === 'true') { - this.logger.warn('checkForUpdates: manual update required'); - this.markCannotUpdate( - new Error('yaml file has requireManualUpdate flag'), - DialogType.Cannot_Update_Require_Manual - ); - return; - } - - if (vendor.minOSVersion && lt(osRelease(), vendor.minOSVersion)) { - this.logger.warn( - `checkForUpdates: OS version ${osRelease()} is less than the ` + - `minimum supported version ${vendor.minOSVersion}` - ); - this.markCannotUpdate( - new Error('yaml file has unsatisfied minOSVersion value'), - DialogType.UnsupportedOS - ); - return; - } + if (vendor && !this.checkSystemRequirements(vendor)) { + return; } const version = getVersion(parsedYaml); diff --git a/ts/updater/linuxAppImage.main.ts b/ts/updater/linuxAppImage.main.ts index 4ed8c8695e..78df7d2891 100644 --- a/ts/updater/linuxAppImage.main.ts +++ b/ts/updater/linuxAppImage.main.ts @@ -6,10 +6,13 @@ import { chmod } from 'fs-extra'; import config from 'config'; import { app } from 'electron'; +import { coerce, lt } from 'semver'; +import type { JSONVendorSchema } from './common.main.js'; import { Updater } from './common.main.js'; import { appRelaunch } from '../util/relaunch.main.js'; import { hexToBinary } from './signature.node.js'; +import { DialogType } from '../types/Dialogs.std.js'; export class LinuxAppImageUpdater extends Updater { #installing = false; @@ -71,4 +74,49 @@ export class LinuxAppImageUpdater extends Updater { await copyFile(updateFilePath, appImageFile); await chmod(appImageFile, 0o700); } + + override checkSystemRequirements(vendor: JSONVendorSchema): boolean { + const { minGlibcVersion } = vendor; + if (minGlibcVersion) { + const parsedMinGlibcVersion = coerce(minGlibcVersion); + if (!parsedMinGlibcVersion) { + this.logger.warn( + 'checkSystemRequirements: yaml had unparseable minGlibcVersion, ignoring. ' + + `yaml value: ${minGlibcVersion}` + ); + return true; + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const sysReport = process.report.getReport() as any; + const glibcVersion = sysReport?.header?.glibcVersionRuntime; + const parsedGlibcVersion = glibcVersion ? coerce(glibcVersion) : null; + if (!parsedGlibcVersion) { + this.logger.warn( + 'checkSystemRequirements: yaml had minGlibcVersion but unable to' + + 'get OS glibc version from system report, blocking update. ' + + `system value: ${glibcVersion}` + ); + this.markCannotUpdate( + new Error('system glibc version missing or unparseable'), + DialogType.UnsupportedOS + ); + return false; + } + + if (lt(parsedGlibcVersion, parsedMinGlibcVersion)) { + this.logger.warn( + `checkSystemRequirements: OS glibc ${glibcVersion} is less than the ` + + `minimum supported version ${minGlibcVersion}` + ); + this.markCannotUpdate( + new Error('yaml file has unsatisfied minGlibcVersion value'), + DialogType.UnsupportedOS + ); + return false; + } + } + + return true; + } }