Исправлен rollback/firewall lifecycle и shell execution, синхронизирована документация

This commit is contained in:
2026-05-01 21:26:42 +05:00
parent d393308216
commit 7c0b79588f
10 changed files with 53 additions and 18 deletions
+10 -3
View File
@@ -33,8 +33,10 @@ async function markInstallSuccessful(context: InstallContext): Promise<void> {
await runVisible`chown root:root ${INSTALL_STATE_PATH}`;
}
async function rollbackFailedInstall(context: InstallContext): Promise<void> {
await rollbackFirewallNow(context);
async function rollbackFailedInstall(context: InstallContext, state: { firewallTouched: boolean }): Promise<void> {
if (state.firewallTouched) {
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`;
@@ -66,6 +68,10 @@ export async function install(options: InstallOptions): Promise<void> {
throw new Error("missing Hysteria lock metadata in package: hysteria.version/hysteria.url/hysteria.sha256");
}
const state = {
firewallTouched: false
};
try {
step("preflight");
await preflight(context);
@@ -88,6 +94,7 @@ export async function install(options: InstallOptions): Promise<void> {
await deploySystemd(context);
step("firewall");
await applyFirewall(context);
state.firewallTouched = true;
step("post-install env");
await writePostInstallEnv(context);
step("bootstrap admin secret");
@@ -99,7 +106,7 @@ export async function install(options: InstallOptions): Promise<void> {
step("mark install successful");
await markInstallSuccessful(context);
} catch (error) {
await rollbackFailedInstall(context);
await rollbackFailedInstall(context, state);
throw error;
}
}
+12
View File
@@ -49,6 +49,18 @@ export async function runVisible(command: TemplateStringsArray, ...args: unknown
}
}
export async function runRawVisible(command: string): Promise<void> {
info(`running script:\n${command}`);
const process = Bun.spawn(["sh", "-eu", "-c", command], {
stdout: "inherit",
stderr: "inherit"
});
const exitCode = await process.exited;
if (exitCode !== 0) {
throw new Error(`script failed (${exitCode})`);
}
}
export async function runHidden(command: TemplateStringsArray, ...args: unknown[]): Promise<void> {
const rendered = renderCommand(command, args);
const process = Bun.spawn(["sh", "-c", rendered], {
+2 -2
View File
@@ -1,5 +1,5 @@
import type { InstallContext } from "../types/context";
import { runVisible } from "../lib/process";
import { runRawVisible, runVisible } from "../lib/process";
async function ensureRuntimeIdentity(user: string, expectedHome: string): Promise<void> {
const checkCmd = `
@@ -23,7 +23,7 @@ else
useradd --system --home ${expectedHome} --shell /usr/sbin/nologin ${user}
fi
`;
await runVisible`${checkCmd}`;
await runRawVisible(checkCmd);
}
export async function prepareFilesystem(context: InstallContext): Promise<void> {
+6 -1
View File
@@ -124,6 +124,11 @@ export async function rollbackFirewallNow(context: RuntimeContext): Promise<void
return;
}
if (!(await exists("/etc/nftables.d/nftables.conf.existed")) && !(await exists("/etc/nftables.d/hy2xs.nft.existed"))) {
info("firewall rollback skipped: no HY2XS rollback markers found");
return;
}
if (context.config.firewallStagedApply) {
await runVisible`systemctl stop hy2xs-fw-rollback || true`;
await runVisible`systemctl reset-failed hy2xs-fw-rollback || true`;
@@ -131,6 +136,6 @@ export async function rollbackFirewallNow(context: RuntimeContext): Promise<void
await runVisible`if [ -f /etc/nftables.d/nftables.conf.existed ]; then cp -a /etc/nftables.conf.hy2xs.bak /etc/nftables.conf 2>/dev/null || true; else rm -f /etc/nftables.conf; fi`;
await runVisible`if [ -f /etc/nftables.d/hy2xs.nft.existed ]; then cp -a /etc/nftables.d/hy2xs.nft.bak /etc/nftables.d/hy2xs.nft 2>/dev/null || true; else rm -f /etc/nftables.d/hy2xs.nft; fi`;
await runVisible`nft -f /etc/nftables.conf >/dev/null 2>&1 || true`;
await runVisible`if [ -f /etc/nftables.d/nftables.conf.existed ]; then nft -f /etc/nftables.conf >/dev/null 2>&1 || true; else nft flush ruleset >/dev/null 2>&1 || true; fi`;
await runVisible`rm -f ${FW_BACKUP_FILES}`;
}