Довёл fix20: firewall-mode, staged state, diagnostics, readiness и build-gate

This commit is contained in:
2026-05-07 23:38:55 +05:00
parent 0a8f4e0c3d
commit 4b382d6ef9
25 changed files with 840 additions and 133 deletions
+26 -14
View File
@@ -1,5 +1,5 @@
import type { RuntimeContext } from "../types/context";
import { exists } from "../lib/fs";
import { dirExists, fileExists } from "../lib/fs";
import { fail, info } from "../lib/log";
import { run } from "../lib/process";
import { assertPlatform } from "../platform/assert";
@@ -38,36 +38,46 @@ export async function preflight(context: RuntimeContext): Promise<void> {
fail("installer must run as root");
}
try {
await run`command -v sudo >/dev/null 2>&1`;
} catch {
fail("sudo is required for installer smoke checks. Install it with: apt-get update && apt-get install -y sudo");
}
await assertPlatform({
distro: "debian",
supportedVersions: [13],
architectures: ["amd64"]
});
if (!(await exists(`${context.options.packageDir}/systemd/hy2xs-admin.service`))) {
if (!(await fileExists(`${context.options.packageDir}/systemd/hy2xs-admin.service`))) {
fail("missing hy2xs-admin systemd unit in package");
}
if (!(await exists(`${context.options.packageDir}/systemd/hysteria-server.service`))) {
if (!(await fileExists(`${context.options.packageDir}/systemd/hysteria-server.service`))) {
fail("missing hysteria-server systemd unit in package");
}
if (!(await exists(`${context.options.packageDir}/templates/hysteria/config.yaml.tpl`))) {
if (!(await fileExists(`${context.options.packageDir}/templates/hysteria/config.yaml.tpl`))) {
fail("missing Hysteria config template in package");
}
if (context.mode === "install" && !(await exists(`${context.options.packageDir}/ui/hy2xs-admin/hy2xs-admin`))) {
if (context.mode === "install" && !(await fileExists(`${context.options.packageDir}/ui/hy2xs-admin/hy2xs-admin`))) {
fail("bundled HY2XS admin is missing from install package");
}
if (!isReconfigure && (await exists("/etc/hysteria/post-install.env"))) {
if (!(await fileExists("/usr/bin/apt-get")) && !(await fileExists("/bin/apt-get"))) {
fail("apt-get is required on target host");
}
if (!(await fileExists("/usr/bin/dpkg-query")) && !(await fileExists("/bin/dpkg-query"))) {
fail("dpkg-query is required on target host");
}
if (!isReconfigure) {
try {
await run`command -v sudo >/dev/null 2>&1`;
} catch {
info("sudo not found in preflight: installDeps step will install sudo before smoke checks");
}
}
if (!isReconfigure && (await fileExists("/etc/hysteria/post-install.env"))) {
fail("existing HY2XS post-install.env found; update/repair is out of scope");
}
if (!isReconfigure && (await exists(context.config.installDir))) {
if (!isReconfigure && (await dirExists(context.config.installDir))) {
fail("existing /opt/hy2xs-admin found; conflicting old state");
}
@@ -115,7 +125,9 @@ export async function preflight(context: RuntimeContext): Promise<void> {
try {
const aaaa = await run`getent ahostsv6 ${context.config.domain}`;
if (aaaa.trim()) {
info(`warning: domain ${context.config.domain} has AAAA record; HY2XS remains IPv4-only`);
fail(
`domain ${context.config.domain} has AAAA record while HY2XS is IPv4-only; remove AAAA or set HY2XS_ALLOW_AAAA_WITH_IPV4_ONLY=true`
);
}
} catch {
// no AAAA is acceptable