Миграция оркестратора на Debian 13: platform layer, preflight, status/diagnostics и structured logging

This commit is contained in:
2026-05-03 02:16:52 +05:00
parent 18ff86058a
commit 52f1e5d909
12 changed files with 304 additions and 13 deletions
+43
View File
@@ -0,0 +1,43 @@
import { fail } from "../lib/log";
import { getPlatformProfile } from "./profile";
type AssertPlatformOptions = {
distro: "debian";
supportedVersions: number[];
architectures: Array<"amd64">;
};
export async function assertPlatform(options: AssertPlatformOptions): Promise<void> {
const profile = await getPlatformProfile();
if (profile.distro !== options.distro) {
fail(`HY2XS baseline supports only ${options.distro}; detected: ${profile.distro || "unknown"}`);
}
if (!options.supportedVersions.includes(profile.majorVersion)) {
fail(
`HY2XS baseline supports only ${options.distro} ${options.supportedVersions.join(", ")}; detected major version: ${profile.majorVersion || "unknown"}`
);
}
if (profile.architecture !== "amd64" || !options.architectures.includes("amd64")) {
fail(`HY2XS baseline supports only ${options.architectures.join(",")}; detected: ${profile.architecture}`);
}
if (!profile.capabilities.systemd) {
fail("required capability missing: systemd");
}
if (!profile.capabilities.systemdRun) {
fail("required capability missing: systemd-run");
}
if (!profile.capabilities.nftables) {
fail("required capability missing: nft");
}
if (!profile.capabilities.nftAtomicReplace) {
fail("required capability missing: nft atomic replace");
}
if (!profile.capabilities.openssl3) {
fail("required capability missing: OpenSSL 3.x runtime");
}
}
+82
View File
@@ -0,0 +1,82 @@
import { exists, readText } from "../lib/fs";
import { run } from "../lib/process";
export type PlatformProfile = {
distro: string;
majorVersion: number;
architecture: "amd64" | "unsupported";
capabilities: {
nftables: boolean;
systemd: boolean;
openssl3: boolean;
systemdRun: boolean;
nftAtomicReplace: boolean;
};
};
function parseOsRelease(content: string): Record<string, string> {
const result: Record<string, string> = {};
for (const rawLine of content.split("\n")) {
const line = rawLine.trim();
if (!line || line.startsWith("#")) {
continue;
}
const index = line.indexOf("=");
if (index <= 0) {
continue;
}
const key = line.slice(0, index);
let value = line.slice(index + 1);
value = value.replace(/^"(.*)"$/, "$1");
result[key] = value;
}
return result;
}
async function commandExists(command: string): Promise<boolean> {
try {
await run`command -v ${command} >/dev/null 2>&1`;
return true;
} catch {
return false;
}
}
async function detectOpenSsl3(): Promise<boolean> {
try {
const output = await run`openssl version`;
return /^OpenSSL\s+3\./.test(output);
} catch {
return false;
}
}
export async function getPlatformProfile(): Promise<PlatformProfile> {
const osReleaseRaw = await readText("/etc/os-release");
const parsed = parseOsRelease(osReleaseRaw);
const distro = (parsed.ID || "").toLowerCase();
const majorVersion = Number.parseInt((parsed.VERSION_ID || "").replace(/"/g, ""), 10);
const archRaw = await run`uname -m`;
const architecture: PlatformProfile["architecture"] = archRaw.trim() === "x86_64" ? "amd64" : "unsupported";
const nftables = await commandExists("nft");
const systemd = await commandExists("systemctl") && (await exists("/run/systemd/system"));
const systemdRun = await commandExists("systemd-run");
const openssl3 = await detectOpenSsl3();
const nftAtomicReplace = nftables;
return {
distro,
majorVersion,
architecture,
capabilities: {
nftables,
systemd,
openssl3,
systemdRun,
nftAtomicReplace
}
};
}