mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-04 22:32:12 +03:00
chore(build): build + ship the TPROXY native addon in the standalone (prebuilds 4e) (#4236)
Integrated into release/v3.8.29
This commit is contained in:
committed by
GitHub
parent
291103513e
commit
910a202e79
@@ -83,6 +83,15 @@ const NATIVE_ASSET_ENTRIES = [
|
||||
src: ["node_modules", "better-sqlite3", "build"],
|
||||
dest: ["node_modules", "better-sqlite3", "build"],
|
||||
},
|
||||
{
|
||||
// TPROXY IP_TRANSPARENT addon (Fase 3 / Epic A). Built by build-tproxy-native
|
||||
// before assembly; Linux-only + opt-in, so the source is absent on non-Linux
|
||||
// builds → syncNativeAssetsToDir skips it gracefully. The runtime loader
|
||||
// (transparentSocket.ts) resolves it cwd-relative to this same dest.
|
||||
label: "TPROXY transparent-socket addon (Linux-only, opt-in)",
|
||||
src: ["src", "mitm", "tproxy", "native", "build", "Release", "transparent.node"],
|
||||
dest: ["src", "mitm", "tproxy", "native", "build", "Release", "transparent.node"],
|
||||
},
|
||||
];
|
||||
|
||||
/** @type {{label:string, src:string[], dest:string[]}[]} */
|
||||
|
||||
@@ -209,6 +209,25 @@ export async function main() {
|
||||
);
|
||||
}
|
||||
|
||||
// Best-effort: build the TPROXY native addon (Linux-only, opt-in) BEFORE
|
||||
// assembling, so its transparent.node is present for assembleStandalone's
|
||||
// NATIVE_ASSET_ENTRIES copy. Non-Linux / no-toolchain is non-fatal — the
|
||||
// capture mode degrades gracefully when the addon is absent.
|
||||
try {
|
||||
const { buildTproxyNative } = await import("./build-tproxy-native.mjs");
|
||||
const res = buildTproxyNative(projectRoot);
|
||||
console.log(
|
||||
res.built
|
||||
? "[build-next-isolated] Built TPROXY native addon (transparent.node)"
|
||||
: `[build-next-isolated] TPROXY native addon skipped: ${res.reason}`
|
||||
);
|
||||
} catch (nativeErr) {
|
||||
console.warn(
|
||||
"[build-next-isolated] Non-fatal error building TPROXY native addon:",
|
||||
nativeErr?.message
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(
|
||||
"[build-next-isolated] Assembling standalone bundle (static + public + natives + extras)..."
|
||||
|
||||
54
scripts/build/build-tproxy-native.mjs
Normal file
54
scripts/build/build-tproxy-native.mjs
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Best-effort build of the TPROXY IP_TRANSPARENT native addon so the production
|
||||
* build can copy `build/Release/transparent.node` into the standalone bundle
|
||||
* (assembleStandalone's NATIVE_ASSET_ENTRIES). Called from build-next-isolated.mjs
|
||||
* before the standalone is assembled.
|
||||
*
|
||||
* IP_TRANSPARENT is Linux-only, so this is a no-op everywhere else. A missing C
|
||||
* toolchain is NOT fatal — the TPROXY capture mode degrades gracefully when the
|
||||
* addon is absent (transparentSocket.ts returns "unavailable"). Every effectful
|
||||
* seam (platform/run/exists) is injectable so the decision logic is unit-testable.
|
||||
*
|
||||
* Hard Rule #13: the command + args are a fixed allowlist (no interpolation of
|
||||
* external/runtime values); `cwd` is derived from `projectRoot`, never user input.
|
||||
*/
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { existsSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
/**
|
||||
* @param {string} projectRoot
|
||||
* @param {{ platform?: string, run?: (cmd:string, args:string[], cwd:string) => void,
|
||||
* exists?: (p:string) => boolean }} [opts]
|
||||
* @returns {{ built: boolean, reason?: string }}
|
||||
*/
|
||||
export function buildTproxyNative(projectRoot, opts = {}) {
|
||||
const platform = opts.platform ?? process.platform;
|
||||
const run = opts.run ?? defaultRun;
|
||||
const exists = opts.exists ?? existsSync;
|
||||
|
||||
if (platform !== "linux") {
|
||||
return { built: false, reason: "non-linux host (IP_TRANSPARENT is Linux-only)" };
|
||||
}
|
||||
|
||||
const nativeDir = path.join(projectRoot, "src", "mitm", "tproxy", "native");
|
||||
if (!exists(path.join(nativeDir, "binding.gyp"))) {
|
||||
return { built: false, reason: "native sources absent (binding.gyp not found)" };
|
||||
}
|
||||
|
||||
const out = path.join(nativeDir, "build", "Release", "transparent.node");
|
||||
try {
|
||||
run("npx", ["--yes", "node-gyp", "rebuild"], nativeDir);
|
||||
} catch (err) {
|
||||
return { built: false, reason: `toolchain/build failed: ${err?.message ?? String(err)}` };
|
||||
}
|
||||
if (!exists(out)) {
|
||||
return { built: false, reason: "node-gyp produced no transparent.node" };
|
||||
}
|
||||
return { built: true };
|
||||
}
|
||||
|
||||
/** @type {(cmd: string, args: string[], cwd: string) => void} */
|
||||
function defaultRun(cmd, args, cwd) {
|
||||
execFileSync(cmd, args, { cwd, stdio: "inherit" });
|
||||
}
|
||||
Reference in New Issue
Block a user