Продакшн-фиксы install/reconfigure: rollback, firewall lifecycle, preflight и runbook
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user