Add runtime version reporting and display
This commit is contained in:
@@ -3,6 +3,7 @@ import http from 'node:http';
|
||||
import path from 'node:path';
|
||||
import { settings } from './config.js';
|
||||
import { createSingboxRuntime } from './singboxRuntime.js';
|
||||
import { buildVersionInfo } from './version.js';
|
||||
|
||||
const socketPath = settings.dataplaneSocket;
|
||||
const runtime = createSingboxRuntime({
|
||||
@@ -10,6 +11,7 @@ const runtime = createSingboxRuntime({
|
||||
gateway: true,
|
||||
tproxyChain: settings.tproxyChain,
|
||||
});
|
||||
const versionInfo = buildVersionInfo('gateway');
|
||||
let ready = false;
|
||||
|
||||
function sendJson(res, statusCode, payload) {
|
||||
@@ -22,6 +24,8 @@ const server = http.createServer(async (req, res) => {
|
||||
if (req.method === 'GET' && req.url === '/status') {
|
||||
return sendJson(res, ready ? 200 : 503, {
|
||||
...await runtime.refresh(),
|
||||
gatewayBackendVersion: versionInfo.components.gatewayBackend,
|
||||
singBoxVersion: versionInfo.runtime.singBox,
|
||||
ready,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
} from '../shared/contracts/state.js';
|
||||
import { HarborError, normalizeHarborError } from '../shared/errors.js';
|
||||
import { createJsonStore, createStateStore } from './services/stateStore.js';
|
||||
import { buildVersionInfo } from './version.js';
|
||||
|
||||
const MAX_BODY_BYTES = 1_000_000;
|
||||
const SUBSCRIPTION_REFRESH_INTERVAL_MS = 15 * 60 * 1000;
|
||||
@@ -63,6 +64,7 @@ if (stateStore.recovery) {
|
||||
}
|
||||
|
||||
const remoteDataplane = settings.appMode === 'gateway' && Boolean(process.env.DATAPLANE_SOCKET);
|
||||
const versionInfo = buildVersionInfo(settings.appMode);
|
||||
const singboxRuntime = remoteDataplane
|
||||
? createDataplaneClient(settings.dataplaneSocket)
|
||||
: createSingboxRuntime({
|
||||
@@ -462,6 +464,16 @@ async function handleApi(req, res) {
|
||||
return sendJson(res, 200, await publicState());
|
||||
}
|
||||
|
||||
if (req.method === 'GET' && req.url === '/api/version') {
|
||||
if (!remoteDataplane) return sendJson(res, 200, versionInfo);
|
||||
const runtime = await singboxRuntime.refresh();
|
||||
return sendJson(res, 200, {
|
||||
...versionInfo,
|
||||
components: { gatewayBackend: runtime.gatewayBackendVersion || null },
|
||||
runtime: { singBox: runtime.singBoxVersion || null },
|
||||
});
|
||||
}
|
||||
|
||||
if (req.method === 'GET' && req.url === '/api/shared-proxy') {
|
||||
return sendJson(res, 200, buildSharedProxyInfo({
|
||||
appMode: settings.appMode,
|
||||
|
||||
20
src/server/version.js
Normal file
20
src/server/version.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import { HARBOR_VERSIONS } from '../shared/versions.js';
|
||||
|
||||
export function detectSingBoxVersion(run = spawnSync) {
|
||||
const result = run('sing-box', ['version'], { encoding: 'utf8', timeout: 1000 });
|
||||
const match = /sing-box version\s+v?([^\s]+)/i.exec(`${result.stdout || ''}\n${result.stderr || ''}`);
|
||||
return match?.[1] || null;
|
||||
}
|
||||
|
||||
export function buildVersionInfo(appMode, run = spawnSync) {
|
||||
const client = appMode === 'client';
|
||||
return {
|
||||
apiVersion: 1,
|
||||
location: client ? 'mac' : 'gateway',
|
||||
components: client
|
||||
? { macClient: HARBOR_VERSIONS.macClient }
|
||||
: { gatewayBackend: HARBOR_VERSIONS.gatewayBackend },
|
||||
runtime: { singBox: detectSingBoxVersion(run) },
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user