mirror of
https://github.com/whyour/qinglong.git
synced 2026-11-02 06:58:52 +08:00
fix: validate ARMv6 upgrades and publish rolling development bundles
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
// Node 24's ARMv6 JS compiler tiers can trap on ARM1176. Keep WebAssembly
|
||||
// enabled for fetch/undici; --jitless disables their HTTP parser as well.
|
||||
const armv6ServerArgs = Object.freeze([
|
||||
'--no-opt',
|
||||
'--no-sparkplug',
|
||||
'--no-maglev',
|
||||
]);
|
||||
function serverRuntimeArgs(runtime = process) {
|
||||
return runtime.arch === 'arm' &&
|
||||
Number(runtime.config.variables.arm_version) === 6 &&
|
||||
Number(runtime.versions.node.split('.')[0]) >= 24
|
||||
? [...armv6ServerArgs]
|
||||
: [];
|
||||
}
|
||||
|
||||
module.exports = { serverRuntimeArgs, armv6ServerArgs };
|
||||
if (require.main === module)
|
||||
process.stdout.write(serverRuntimeArgs().join(' '));
|
||||
@@ -7,6 +7,10 @@ import type { LocalContext } from '../runtime/context';
|
||||
import { atomicWrite } from '../runtime/files';
|
||||
import { runProcess, checkedProcess } from '../runtime/process';
|
||||
import { findDirectBackendPids } from '../runtime/backendProcesses';
|
||||
const { serverRuntimeArgs, armv6ServerArgs } = require('./nodeRuntime.cjs') as {
|
||||
serverRuntimeArgs(): string[];
|
||||
armv6ServerArgs: readonly string[];
|
||||
};
|
||||
|
||||
export async function repairConfiguration(
|
||||
context: LocalContext,
|
||||
@@ -117,7 +121,11 @@ async function stopDirectBackend(context: LocalContext): Promise<void> {
|
||||
for (const line of result.stdout.split('\n')) {
|
||||
const match = line.trim().match(/^(\d+)\s+(\S+)\s+(.*)$/);
|
||||
if (!match || !/^node(?:\d+)?$/.test(path.basename(match[2]!))) continue;
|
||||
if (match[3] !== entry) continue;
|
||||
if (
|
||||
match[3] !== entry &&
|
||||
match[3] !== `${armv6ServerArgs.join(' ')} ${entry}`
|
||||
)
|
||||
continue;
|
||||
const pid = Number(match[1]);
|
||||
if (pid === process.pid) continue;
|
||||
try {
|
||||
@@ -179,7 +187,7 @@ export async function startPanel(
|
||||
0o600,
|
||||
);
|
||||
try {
|
||||
const child = spawn(process.execPath, [entry], {
|
||||
const child = spawn(process.execPath, [...serverRuntimeArgs(), entry], {
|
||||
...options,
|
||||
detached: true,
|
||||
stdio: ['ignore', log.fd, log.fd],
|
||||
|
||||
@@ -6,6 +6,7 @@ const os = require('node:os');
|
||||
const { execFile } = require('node:child_process');
|
||||
const { promisify } = require('node:util');
|
||||
const tar = require('tar');
|
||||
const { serverRuntimeArgs } = require('./nodeRuntime.cjs');
|
||||
const {
|
||||
prestartBackend,
|
||||
dependencyFailure,
|
||||
@@ -211,10 +212,12 @@ async function smokeDependencies(source, signal) {
|
||||
`;
|
||||
// Match the server's normal runtime. Node 20.18's built-in HTTP parser needs
|
||||
// WebAssembly, which --jitless disables; only archive workers need that flag.
|
||||
await execute(process.execPath, ['-e', probe], {
|
||||
await execute(process.execPath, [...serverRuntimeArgs(process), '-e', probe], {
|
||||
cwd: source,
|
||||
env: { ...process.env, NODE_PATH: '', NODE_OPTIONS: '' },
|
||||
timeout: 30000,
|
||||
// ARM1176 devices need the same startup allowance as the backend probe.
|
||||
// Keep this bounded and cancellable without forcing an unnecessary repair.
|
||||
timeout: nodeRuntimeArgs().length ? 300000 : 30000,
|
||||
signal,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ const path = require('node:path');
|
||||
const { spawn } = require('node:child_process');
|
||||
const crypto = require('node:crypto');
|
||||
const os = require('node:os');
|
||||
const { serverRuntimeArgs } = require('./nodeRuntime.cjs');
|
||||
|
||||
function probeLimits(target) {
|
||||
const small = target.arch === 'armv6';
|
||||
@@ -122,7 +123,7 @@ async function prestartBackend(
|
||||
// one backend process. Keep normal V8 mode for Node 20's HTTP/WASM support.
|
||||
const child = spawn(
|
||||
process.execPath,
|
||||
[`--max-old-space-size=${limits.heapMb}`, entry],
|
||||
[...serverRuntimeArgs(), `--max-old-space-size=${limits.heapMb}`, entry],
|
||||
{
|
||||
cwd: workspace,
|
||||
env,
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
const { armv6ServerArgs } = require('../maintenance/nodeRuntime.cjs') as {
|
||||
armv6ServerArgs: readonly string[];
|
||||
};
|
||||
|
||||
// Linux preserves argv boundaries in cmdline. Resolve relative entrypoints from
|
||||
// each process's cwd, not from the operator's cwd or a broad ps substring match.
|
||||
@@ -27,11 +30,18 @@ export async function findDirectBackendPids(
|
||||
);
|
||||
const args = command.split('\0');
|
||||
if (args.at(-1) === '') args.pop();
|
||||
// Both the legacy fallback and the TS fallback launch one script without
|
||||
// Node flags or application arguments. Reject other command shapes.
|
||||
if (args.length !== 2 || !/^node(?:\d+)?$/.test(path.basename(args[0]!)))
|
||||
// Accept only the two launch shapes we own. Never treat eval, preload or
|
||||
// application arguments containing this path as a running backend.
|
||||
const scriptIndex =
|
||||
args.length === 2
|
||||
? 1
|
||||
: args.length === armv6ServerArgs.length + 2 &&
|
||||
armv6ServerArgs.every((flag, i) => args[i + 1] === flag)
|
||||
? args.length - 1
|
||||
: -1;
|
||||
if (scriptIndex < 0 || !/^node(?:\d+)?$/.test(path.basename(args[0]!)))
|
||||
continue;
|
||||
const script = args[1]!;
|
||||
const script = args[scriptIndex]!;
|
||||
if (!script) continue;
|
||||
const absolute = path.isAbsolute(script)
|
||||
? script
|
||||
|
||||
Reference in New Issue
Block a user