61dcea2d25
The previous fix closed one branch and left its neighbours open. Both remaining paths could still end with the host having no swap, and one of them said the opposite in its own error message. 1. The message claimed a fallback that was no longer running. The forward path deactivates the staging swap *before* renaming it onto the managed path. A failure at that rename, or at anything after it, therefore reached the rollback with staging_active = false. The rollback then returned "the staging swap is left active" - which was false: it had been switched off several steps earlier, and with the original also unable to activate, the host had nothing. The rollback now brings the replacement back up as the fallback when it is not running, and the error describes what is actually active rather than assuming. 2. The replacement was deleted before the original was known to work. With new_installed the rollback removed the file at the managed path to make room for the restore. That discarded the only other swap area on the host before finding out whether the original could be activated. The replacement is now moved aside to the staging name instead, so it is still available as the fallback if the restore fails. 3. An installed replacement could be moved while the kernel was swapping to it. ReplacementState had no way to express "installed and active", so a failure in the final verification - a failed read of /proc/swaps after a successful swapon - left the rollback moving a live swapfile. new_active closes that: if the replacement is active it is deactivated first, and if that fails the rollback stops and reports that the replacement is in place and serving, because a working swap is the outcome to keep. Also from the same audit: - mkswap --file creates the file itself, so a non-zero exit is not a guarantee that nothing was left behind. Both creation paths now remove the file on failure; previously a failed mkswap left an unowned file at the managed path, which the next run correctly called Foreign and refused, wedging the module. - stale_ownership_help gave advice that could not work. Removing the ownership record leaves the file Foreign, which is refused just as firmly, so "mv previous main, delete the record" only changed which error appeared. Both cases now give one recipe that actually restores managed state: swapoff, remove the three files and the record, re-run ensure-swap. Swap holds no persistent data, so a rebuild loses nothing. - LastActionState kept a single error slot shared by all subsystems, so a successful firewall reconcile cleared a live traffic failure and logged firewall=recovered for something that had never failed. Errors are now tracked per subsystem; the shared field that status reads mirrors whatever is still outstanding. - tools/README.md still showed 0.1.6. Five rollback tests covering the branches that exist: original unrestorable with staging running, original unrestorable with staging already stopped (it is reactivated and never released), an installed replacement preserved by being moved aside rather than deleted, the success path releasing the replacement only after the original is back, and the no-op case. cargo fmt --check, clippy -D warnings, cargo test --locked --workspace --release: 193 + 4 passed.
AWG2 Harness builder
tools/build.sh — единый build/package helper для AWG2 Harness. Он предназначен в первую очередь для build-machine. Production-хост обычно получает только готовый .deb и /etc/awg2-harness/config.toml.
Скрипт собирает workspace из двух бинарей:
traffic_core -> awg2-harness
reboot_module -> awg2-reboot-scheduler
И при --package создаёт Debian-пакет dist/awg2-harness_<version>_amd64.deb с checksum-файлом dist/SHA256SUMS.
Поддерживаемая build-среда
- Debian 13 с
apt. - Debian package architecture: amd64.
- Rust toolchain из
rust-toolchain.toml(1.95.0в текущем дереве). Cargo.lockобязателен: build gate работает в--lockedрежиме.
Быстрый production build
cd awg2_harness
chmod +x tools/build.sh
./tools/build.sh --prepare-build-env --bootstrap-rust --yes
./tools/build.sh --package --version 0.3.0
(cd dist && sha256sum -c SHA256SUMS)
dpkg-deb -I dist/awg2-harness_0.3.0_amd64.deb
dpkg-deb -c dist/awg2-harness_0.3.0_amd64.deb | sort
Что делает default запуск
./tools/build.sh
Если не указан ни один action flag, включается --build.
Проверка пакета перед переносом
(cd dist && sha256sum -c SHA256SUMS)
dpkg-deb -I dist/awg2-harness_<version>_amd64.deb
dpkg-deb -c dist/awg2-harness_<version>_amd64.deb | sort
Production transfer
scp -P 2323 dist/awg2-harness_<version>_amd64.deb root@<server-ip>:/root/
scp -P 2323 dist/SHA256SUMS root@<server-ip>:/root/
Runtime config bootstrap на production
--package кладёт config.example.toml только в:
/usr/share/doc/awg2-harness/repo/config.example.toml
Боевой /etc/awg2-harness/config.toml создаётся вручную после установки пакета:
apt install ./awg2-harness_<version>_amd64.deb
install -d -m 0755 /etc/awg2-harness
cp /usr/share/doc/awg2-harness/repo/config.example.toml /etc/awg2-harness/config.toml
nano /etc/awg2-harness/config.toml
Перед первым apply-firewall обязательно сверяйте ssh_port, amnezia_port и peer_ipv4_cidr с реальным состоянием хоста и Amnezia.
Что скрипт намеренно не делает
- не устанавливает AmneziaVPN;
- не генерирует client keys/configs;
- не копирует
config.example.tomlв/etc/awg2-harness/config.toml; - не включает services без
--enable; - не управляет SSH hardening.