Продакшн-фиксы install/reconfigure: rollback, firewall lifecycle, preflight и runbook

This commit is contained in:
2026-05-01 21:14:24 +05:00
parent 5ed99eac7f
commit d393308216
13 changed files with 379 additions and 51 deletions
+62 -28
View File
@@ -11,10 +11,35 @@ import { deployUi } from "../steps/ui";
import { installHysteria } from "../steps/hysteria";
import { generateConfig } from "../steps/config";
import { deploySystemd } from "../steps/systemd";
import { applyFirewall } from "../steps/firewall";
import { applyFirewall, cancelFirewallRollback, rollbackFirewallNow } from "../steps/firewall";
import { writeBootstrapAdminSecret, writePostInstallEnv } from "../steps/env";
import { smoke } from "../steps/smoke";
const INSTALL_STATE_PATH = "/var/lib/hy2xs/install-state.json";
async function markInstallSuccessful(context: InstallContext): Promise<void> {
await runVisible`install -d -m 0755 -o root -g root /var/lib/hy2xs`;
const state = JSON.stringify(
{
installed: true,
version: context.packageVersion,
build_id: context.packageBuildId,
installed_at: new Date().toISOString()
},
null,
2
);
await writeText(INSTALL_STATE_PATH, `${state}\n`, 0o644);
await runVisible`chown root:root ${INSTALL_STATE_PATH}`;
}
async function rollbackFailedInstall(context: InstallContext): Promise<void> {
await rollbackFirewallNow(context);
await runVisible`systemctl stop hysteria-server hy2xs-admin || true`;
await runVisible`systemctl disable hysteria-server hy2xs-admin || true`;
await runVisible`systemctl reset-failed hysteria-server hy2xs-admin || true`;
}
export async function install(options: InstallOptions): Promise<void> {
const hasSourceConfig = options.sourceConfigPath ? await exists(options.sourceConfigPath) : false;
if (options.sourceConfigPath && !hasSourceConfig) {
@@ -41,31 +66,40 @@ export async function install(options: InstallOptions): Promise<void> {
throw new Error("missing Hysteria lock metadata in package: hysteria.version/hysteria.url/hysteria.sha256");
}
step("preflight");
await preflight(context);
step("system dependencies");
await installDeps(context);
step("filesystem");
await prepareFilesystem(context);
step("write runtime env");
await runVisible`mkdir -p /etc/hy2xs`;
await writeText(options.runtimeConfigPath, renderRuntimeEnv(config), 0o600);
await runVisible`chown root:root ${options.runtimeConfigPath}`;
await runVisible`chmod 0600 ${options.runtimeConfigPath}`;
step("bundled UI");
await deployUi(context);
step("Hysteria2 upstream install");
await installHysteria(context);
step("config generation");
await generateConfig(context);
step("systemd units");
await deploySystemd(context);
step("firewall");
await applyFirewall(context);
step("post-install env");
await writePostInstallEnv(context);
step("bootstrap admin secret");
await writeBootstrapAdminSecret(context);
step("smoke checks");
await smoke(context);
try {
step("preflight");
await preflight(context);
step("system dependencies");
await installDeps(context);
step("filesystem");
await prepareFilesystem(context);
step("write runtime env");
await runVisible`mkdir -p /etc/hy2xs`;
await writeText(options.runtimeConfigPath, renderRuntimeEnv(config), 0o600);
await runVisible`chown root:root ${options.runtimeConfigPath}`;
await runVisible`chmod 0600 ${options.runtimeConfigPath}`;
step("bundled UI");
await deployUi(context);
step("Hysteria2 upstream install");
await installHysteria(context);
step("config generation");
await generateConfig(context);
step("systemd units");
await deploySystemd(context);
step("firewall");
await applyFirewall(context);
step("post-install env");
await writePostInstallEnv(context);
step("bootstrap admin secret");
await writeBootstrapAdminSecret(context);
step("smoke checks");
await smoke(context);
step("finalize firewall rollback guard");
await cancelFirewallRollback(context);
step("mark install successful");
await markInstallSuccessful(context);
} catch (error) {
await rollbackFailedInstall(context);
throw error;
}
}