- dl_content no longer runs with no timeout at all: every attempt carries
--connect-timeout, and a content transfer that connects then crawls below
1 KiB/s for 30s is aborted so the next try can take over (a slow but moving
download is still never cut off by a total cap)
- verify the release binary by looking up its SHA256SUMS entry explicitly
instead of `sha256sum -c --ignore-missing`, which quietly succeeded when the
manifest held no line for the arch
- copy the local vps-prebuild instead of moving it, so a later failure cannot
destroy the only snapshot along with the temp dir
- fail loudly when lib-download.sh is missing instead of degrading silently
- drop the unused dl_handshake helper, accept binary-mode `*asset` lines, and
lower-case v4_forward in 30-haproxy so True/TRUE match like 00-ip-ask
When piped through /dev/fd the script's $0 is not a filesystem path, so
sourcing scripts/lib-download.sh failed ("... /dev/fd/scripts/lib-download.sh:
No such file or directory"). Inline dl_content() instead so the gitless
bootstrap can still retry the repo tarball download.
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
The installed unit started HAProxy with the static entry config alone:
-Ws -f /etc/haproxy/haproxy.cfg
That file declares the frontends, the reject backends and the timeouts; the
per-domain backends and the routing maps live in the generation the panel
publishes, and the maps' paths point at it. So HAProxy came up healthy, bound
80/443 and answered 404 on :80 and closed every :443 connection — no managed
domain was reachable. `haproxy -c` on the entry config alone passes, which is
why the install-time check did not catch it.
- the unit now passes both files, the generation through "current" so a reload
picks up whatever the panel published last;
- 30-haproxy.sh validates exactly that command line (entry + generation) and
requires domains.cfg AND both maps before it considers the bootstrap
generation in place, so the pre-start check can no longer pass a setup that
serves nothing;
- tests: TestUnitLoadsBothConfigFiles parses the unit's own ExecStart and fails
if it does not pass two config files, and TestUnitCommandLineRoutesTraffic
runs that command line against a real HAProxy and asserts a registered host
reaches its backend. Both fail against the old unit.
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
The panel now fronts user domains with HAProxy 3.4 LTS (official performance
packages) instead of Traefik: about 100 MB of RSS and 200 MB of disk saved for
a feature set that never used more than Host routing on :80 and SNI passthrough
on :443.
- hpx: publish the proxy configuration as immutable GENERATIONS. Every domain
mutation renders the whole set from the DB, validates it with the pinned
`haproxy -c`, and only then repoints the `current` symlink, so a rejected
candidate leaves the running proxy untouched and a stale domain can never
survive into a later generation. Routing is carried by two map files
(Host -> backend, SNI -> backend): per-domain frontend rules cannot work from
a second file because HAProxy rejects duplicate section names since 3.3 and
attaches bare directives to the section opened last.
- mgr: republish and reload (SIGUSR2, i.e. `systemctl reload`) after every
domain change, so a change takes effect without dropping established HTTP or
TLS connections. Rollback semantics (DB first, then publish) are unchanged.
- cfg,db: `net.traefik` is renamed to `net.haproxy` with identical values. A
pre-rename config.yaml key and the legacy VPSMGR_TRAEFIK env var are still
read (new name wins), and schema migration v18 moves the settings mirror from
`traefik` to `haproxy`, keeping a newer value when both rows exist.
- 30-haproxy.sh: install the pinned branch from the vendor repository and
migrate a Traefik host in one run — install and validate HAProxy first, then
remove Traefik's binary, unit, service account and dynamic rules (only its
config file is kept, inert). No fallback keeps both proxies alive.
- upgrade-haproxy.sh: follow the pinned branch to its newest patch, with a
configuration check and a graceful reload; `install.sh --update` runs it.
- tests: generation publish/rollback, map rendering, config-key and settings
migrations, plus real-binary tests (skipped unless
VPSMGR_TEST_HAPROXY_BIN is set) that run the generated configuration through
`haproxy -c` and start it in a network namespace.
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>