Fix/telegram openrc service support - #130
Open
rvalitov wants to merge 3 commits into
Open
Conversation
setup_telegram_service() wrote a systemd unit only, with no else branch, so on
a host without systemd (Alpine/OpenRC) `mtproxymax telegram setup` reported
success while installing nothing. The bot stayed dead, and because the bot also
carries the "proxy down" alerts, the entire alert channel was lost with no
signal to the user. setup_autostart() had the identical no-else bug, so
"start on boot" was silently broken on the same hosts.
Add detect_init_system() and branch on it:
- OpenRC hosts get /etc/init.d/mtproxymax-telegram supervised by
supervise-daemon (respawn_delay=10, respawn_max=0), mirroring the systemd
unit's Restart=on-failure / RestartSec=10, plus /etc/init.d/mtproxymax for
autostart (plain start/stop, mirroring Type=oneshot + RemainAfterExit=yes).
- Hosts with neither init system now warn loudly and return nonzero instead of
failing silently, matching what setup_replication_service already does.
- A failed start is reported instead of logging "service started" regardless.
Route the remaining service calls (update restart, telegram disable/remove,
menu toggle, uninstall) through the same detector, and make `telegram status`
report whether the service is actually running rather than echoing the settings
flag.
Unit paths become injectable via SYSTEMD_DIR/INITD_DIR, following the existing
${VAR:-default} idiom, so the service installers are testable without root.
Adds tests/test_telegram_service_openrc.sh covering all three init systems.
Reconcile the generated init script with the unit running in production on an
Alpine LXC:
- `need net docker` rather than `use docker`. The daemon drives the proxy
container and is the only scheduler for the periodic tasks (quota/expiry
enforcement, sweep, proxy auto-restart), so a hard docker dependency fails
loudly instead of starting a bot that can only emit bogus "proxy down" alerts.
- Separate error_log (.err) from output_log so stderr does not interleave.
- start_pre tests ${command_args} via -f — the daemon is invoked through bash so
it need not be executable — and names the exact command to run.
Also fixes a generation bug this surfaced: in the unquoted heredoc
${command_args} was expanded at generation time, to empty, so the guard would
have been written as `if [ ! -f "" ]`. Now escaped, with a test assertion
pinning it.
Review on a live Alpine LXC surfaced three issues. 1. `rc-update add ... || true` swallowed failures and then logged success, so a user could be told boot-autostart was enabled when it was not — the same class of silent lie this branch set out to fix. Adds openrc_enable_service(), which verifies the service actually landed in the runlevel instead of trusting rc-update's exit status (which is also ambiguous when the service is already registered). setup_autostart now returns nonzero when it fails, since enabling boot-autostart is the whole point of that function. 2. Two pid files exist with different meanings: /run/<svc>.pid belongs to the supervision layer while the bot daemon writes its own PID under INSTALL_DIR. Killing the first stops the supervisor, not the bot. Documented in the generated unit. 3. respawn_max=0 restarts on any exit, whereas systemd's Restart=on-failure does not restart after a clean exit. Kept the behaviour — the daemon only exits on error or a signal — but documented the divergence. Also switches the runlevel check to -e rather than -L so the decision logic stays verifiable on hosts that cannot create symlinks.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #129
Problem
setup_telegram_service()wrote a systemd unit only, with noelsebranch, so on a hostwithout systemd (Alpine/OpenRC)
mtproxymax telegram setupreported success while installingnothing. The bot stayed dead — and because the bot also carries the "proxy down" alerts, the
whole alert channel was lost with no signal to the user.
setup_autostart()had the identical no-elsebug, so "start on boot" was silently broken onthe same hosts.
The blind spot also made the management commands lie. On the reporter's Alpine box, with the
bot service genuinely stopped:
telegram statusTelegram: ● EnabledTelegram: ● Enabled (service not running)+ how to fix ittelegram disableTelegram disabled, leaves the daemon runningtelegram setupChanges
detect_init_system()is the single detection point, returningsystemd | openrc | none. Itexists as a function so the test suite can override it, matching how the existing tests already
stub
check_rootandcurl.setup_telegram_service— three-way branch. systemd behaviour is unchanged. OpenRC gets/etc/init.d/mtproxymax-telegramsupervised bysupervise-daemon(respawn_delay=10,respawn_max=0), mirroring the unit'sRestart=on-failure/RestartSec=10. A host withneither init system now warns loudly and returns nonzero, the way
setup_replication_servicealready does.setup_autostart— same treatment; the OpenRC script is a plain start/stop wrapperaround the manager's own
start/stop, mirroringType=oneshot+RemainAfterExit=yes.via small
telegram_*_servicehelpers, so they no longer report work they did not do.telegram status— reports whether the service is actually running instead of echoingthe settings flag.
SYSTEMD_DIR/INITD_DIR/RUNLEVELS_DIR— unit paths become injectable via theexisting
${VAR:-default}idiom. This is what makes the service installers testable withoutroot; the tests deliberately never run as root, and hardcoded
/etc/systemd/systemwas theonly reason these functions could not be covered.
A failed start is now reported rather than logging "service started" regardless.
Testing
New
tests/test_telegram_service_openrc.sh— 54 assertions covering all three init systems,the failure branches, and the service helpers.
bash tests/test_telegram_service_openrc.sh,no root required. Existing tests unaffected.
test_client_mss.shandtest_lxc_ram_and_resources.shfail oncheck_rootin a non-rootenvironment; this is pre-existing and reproduces identically on
main.Validated on the reporter's Alpine LXC (OpenRC 0.63.2, no systemd):
default, service startssupervise-daemonrespawns it (~12s)telegram disablegenuinely stops it;telegram removecleans up unit + runlevel + settingstelegram statuscorrect in both running and stopped statesNotes for review
need net docker, notuse docker. The daemon drives the proxy container and is theonly scheduler for the periodic tasks (quota/expiry enforcement, sweep, proxy auto-restart),
so a hard dependency fails loudly instead of starting a bot that can only emit bogus
"proxy down" alerts. This is stricter than the systemd unit's
Wants=, deliberately;it's commented in the generated unit so it doesn't get "fixed" back.
rc-update's exit status is not trusted. It returns nonzero when the service is alreadyregistered, so gating on it would warn on every re-install.
openrc_enable_service()verifies the runlevel entry actually exists instead.
respawn_max=0restarts on any exit, whereasRestart=on-failuredoes not restart aftera clean exit. Kept, since the daemon only exits on error or a signal, and documented as a
real difference between the backends. Worth noting it cuts both ways: systemd's default
StartLimitBurst=5gives up after 5 failures in 10s, while this retries indefinitely at oneattempt per 10s.
/run/<svc>.pidbelongs to thesupervision layer, while the daemon writes its own PID under
INSTALL_DIR. Killing thefirst stops the supervisor, not the bot. Documented in the generated unit.
Out of scope: the replication sync service still has no OpenRC path. Giving it real
OpenRC/cron support is a separate change; its
setup_replication_servicecorrectly warnstoday, so it is not silent, and fixing its restart path alone would be pointless since
nothing is ever installed to restart.