feat: add yaml egress proxy benchmark

This commit is contained in:
Codex
2026-06-26 10:32:43 +00:00
parent 0bfff97848
commit 0ef9129bef
14 changed files with 1090 additions and 46 deletions
+34 -6
View File
@@ -7,6 +7,7 @@ import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "n
import { dirname, isAbsolute, join } from "node:path";
import type { UniDeskConfig } from "../config";
import { rootPath } from "../config";
import { resolveEgressProxySourceRef } from "../egress-proxy-sources";
import { startJob } from "../jobs";
import type { RenderedCliResult } from "../output";
import { pk01CaddyMergeManagedBlocksPython, renderCaddyManagedBlock, renderSimpleReverseProxyCaddySiteBlock } from "../pk01-caddy";
@@ -282,12 +283,16 @@ export function parseEgressProxyConfig(value: unknown, path: string): Sub2ApiEgr
if (value === undefined || value === null) return null;
if (typeof value !== "object" || Array.isArray(value)) throw new Error(`${configPath}.${path}.egressProxy must be an object`);
const record = value as Record<string, unknown>;
const sourceType = enumField(record, "sourceType", `${path}.egressProxy`, ["subscription-url", "master-shadowsocks"] as const);
const sourceConfigRef = optionalConfigStringField(record, "sourceConfigRef", `${path}.egressProxy`);
const source = sourceConfigRef === null ? null : resolveEgressProxySourceRef(sourceConfigRef, `${configPath}.${path}.egressProxy.sourceConfigRef`);
const sourceType = source?.sourceType ?? enumField(record, "sourceType", `${path}.egressProxy`, ["subscription-url", "master-shadowsocks"] as const);
assertOptionalMatch(record, "sourceType", sourceType, `${path}.egressProxy`);
const preferredOutbound = sourceType === "subscription-url" || record.preferredOutbound !== undefined
? enumField(record, "preferredOutbound", `${path}.egressProxy`, ["vless-reality", "hysteria2"] as const)
? source?.preferredOutbound ?? enumField(record, "preferredOutbound", `${path}.egressProxy`, ["vless-reality", "hysteria2"] as const)
: null;
if (source !== null && source.preferredOutbound !== null && record.preferredOutbound !== undefined) assertOptionalMatch(record, "preferredOutbound", source.preferredOutbound, `${path}.egressProxy`);
const masterShadowsocks = sourceType === "master-shadowsocks"
? parseMasterShadowsocksConfig(record.masterShadowsocks, `${path}.egressProxy.masterShadowsocks`)
? source?.masterShadowsocks ?? parseMasterShadowsocksConfig(record.masterShadowsocks, `${path}.egressProxy.masterShadowsocks`)
: null;
const imagePullPolicy = enumField(record, "imagePullPolicy", `${path}.egressProxy`, ["Always", "IfNotPresent", "Never"] as const);
const noProxy = stringArrayField(record, "noProxy", `${path}.egressProxy`);
@@ -300,16 +305,23 @@ export function parseEgressProxyConfig(value: unknown, path: string): Sub2ApiEgr
image: stringField(record, "image", `${path}.egressProxy`),
imagePullPolicy,
listenPort: integerField(record, "listenPort", `${path}.egressProxy`),
sourceRef: stringField(record, "sourceRef", `${path}.egressProxy`),
sourceKey: stringField(record, "sourceKey", `${path}.egressProxy`),
sourceConfigRef,
sourceFingerprint: source?.fingerprint ?? null,
sourceRef: source?.sourceRef ?? stringField(record, "sourceRef", `${path}.egressProxy`),
sourceKey: source?.sourceKey ?? stringField(record, "sourceKey", `${path}.egressProxy`),
sourceType,
preferredOutbound,
masterShadowsocks,
noProxy,
applyToSub2Api: booleanField(record, "applyToSub2Api", `${path}.egressProxy`),
applyToSentinel: booleanField(record, "applyToSentinel", `${path}.egressProxy`),
healthProbeUrl: stringField(record, "healthProbeUrl", `${path}.egressProxy`),
healthProbeUrl: source?.healthProbeUrl ?? stringField(record, "healthProbeUrl", `${path}.egressProxy`),
};
if (source !== null) {
assertOptionalMatch(record, "sourceRef", source.sourceRef, `${path}.egressProxy`);
assertOptionalMatch(record, "sourceKey", source.sourceKey, `${path}.egressProxy`);
assertOptionalMatch(record, "healthProbeUrl", source.healthProbeUrl, `${path}.egressProxy`);
}
validateEgressProxyConfig(proxy, path);
return proxy;
}
@@ -406,6 +418,19 @@ export function stringArrayField(obj: Record<string, unknown>, key: string, path
return value.map((item) => item.trim());
}
function optionalConfigStringField(obj: Record<string, unknown>, key: string, path: string): string | null {
const value = obj[key];
if (value === undefined || value === null) return null;
if (typeof value !== "string" || value.trim().length === 0) throw new Error(`${fieldLabel(path, key)} must be a non-empty string when set`);
return value.trim();
}
function assertOptionalMatch(obj: Record<string, unknown>, key: string, expected: string | null, path: string): void {
if (obj[key] === undefined || obj[key] === null) return;
const actual = stringField(obj, key, path);
if (actual !== expected) throw new Error(`${fieldLabel(path, key)} must match sourceConfigRef value ${expected}`);
}
export function enumField<const T extends readonly string[]>(obj: Record<string, unknown>, key: string, path: string, values: T): T[number] {
const value = stringField(obj, key, path);
if (!(values as readonly string[]).includes(value)) throw new Error(`${fieldLabel(path, key)} must be one of ${values.join(", ")}`);
@@ -483,6 +508,9 @@ export function validateEgressProxyConfig(config: Sub2ApiEgressProxyConfig, path
if (config.secretKey !== "config.json") throw new Error(`${configPath}.${path}.egressProxy.secretKey must be config.json`);
if (!isImageReference(config.image)) throw new Error(`${configPath}.${path}.egressProxy.image has an unsupported format`);
validatePort(config.listenPort, `${path}.egressProxy.listenPort`);
if (config.sourceConfigRef !== null && (!config.sourceConfigRef.startsWith("config/") || !config.sourceConfigRef.includes("#sources.") || config.sourceConfigRef.includes(".."))) {
throw new Error(`${configPath}.${path}.egressProxy.sourceConfigRef must reference config/*.yaml#sources.<id>`);
}
if (!/^[A-Za-z0-9_./-]+$/u.test(config.sourceRef)) throw new Error(`${configPath}.${path}.egressProxy.sourceRef has an unsupported format`);
if (!/^[A-Z0-9_]+$/u.test(config.sourceKey)) throw new Error(`${configPath}.${path}.egressProxy.sourceKey must be an env key`);
if (config.sourceType === "subscription-url" && config.preferredOutbound === null) {