Derive RPC readiness probe and shutdown host from rpc-bind-address - #327
Open
boomshadow wants to merge 1 commit into
Open
Derive RPC readiness probe and shutdown host from rpc-bind-address#327boomshadow wants to merge 1 commit into
boomshadow wants to merge 1 commit into
Conversation
The readiness probe in svc-transmission/run and the graceful shutdown in svc-transmission/finish both hardcoded localhost. When rpc-bind-address is a specific non-loopback address, `nc -z localhost` can never succeed, so s6-notifyoncheck never signals readiness, container init never completes, and s6 therefore never delivers SIGTERM to transmission-daemon -- every docker stop ends in SIGKILL with no resume data flushed and no "stopped" tracker announce. Derive the host from rpc-bind-address in both scripts, keeping wildcard binds (0.0.0.0, ::, [::]) on loopback as before. finish now builds a full RPC URL, since transmission-remote's host:port shorthand cannot express an IPv6 literal; the path comes from rpc-url rather than being hardcoded. Also add a timeout-finish, as s6 otherwise SIGKILLs the finish script at its 5000ms default while a large library legitimately needs longer to shut down. closes linuxserver#326 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Thanks for opening this pull request! Be sure to follow the pull request template!
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.
closes #326
Description:
svc-transmission/rungates readiness onnc -z localhost ${PORT}, andsvc-transmission/finishsends the graceful exit to127.0.0.1:${PORT}. Both readrpc-portfromsettings.jsonbut ignorerpc-bind-address.This PR derives the host from
rpc-bind-addressin both scripts. Wildcard binds (0.0.0.0,::,[::]) keep targeting loopback exactly as today, so the default configuration is unchanged.Two details worth flagging for review:
finishnow builds a full RPC URL.transmission-remote'shost:portshorthand cannot express an IPv6 literal — given[fd00::5]:9091it constructshttp://[fd00::5]:9091:9091/transmission/rpc/and fails with "URL using bad/illegal format". The URL form is the only one that works for IPv6. Since that means spelling out the path, it is taken fromrpc-urlrather than hardcoded, which also makes shutdown work for anyone who has customised that setting.timeout-finishfile is added. There is currently none, so s6 SIGKILLs the finish script at its 5000 ms default. On a large library the daemon legitimately needs longer than that (~8–9 s for ~1300 torrents on my host; ~16 s when RPC is bound to a global IPv6 address), sotail --pid=${pid}gets killed before the daemon is actually gone. 30000 ms gives it room while still bounding a wedged finish script; Docker's stop timeout remains the outer bound. This was found while investigating the above and is included here because it is part of the same "container shuts down cleanly" story — happy to split it out if you would rather it stood alone.Benefits of this PR and context:
Fixes #326. With a specific non-loopback
rpc-bind-addressthe probe can never succeed, so:s6-notifyonchecknever signals readinesss6-svlisten1 -U -- /run/s6-rc/servicedirs/svc-transmissionblocks foreverrc.init top/s6-rc -v1 -u -t 0 -- change topnever complete — init stays permanently in progressdocker stopends in SIGKILL — no resume data flushed, no "stopped" tracker announceThe failure is silent: the daemon is healthy and serving RPC the whole time, and nothing in the logs indicates a problem. It is invisible on the default config because
localhostmatches the wildcard socket, which is likely why it has gone unreported. Note that the workaround currently being suggested in #324 (hand-editingrpc-bind-address) is a route into it.How Has This Been Tested?
Tested against
ghcr.io/linuxserver/transmission:4.1.3@sha256:6b78970a0cb00709d3817fcb47b7cf74da56a43384bbd50d03955ca87e38c5f0(4.1.3-r0-ls356) with the patchedrun,finishandtimeout-finishbind-mounted over the servicedir, on both an IPv4 bridge network and a dual-stack one. Measured init completion ([ls.io-init] done.) anddocker stopduration/exit code.Before (stock image),
rpc-bind-address: 172.30.0.5:docker stop -t 30After, across every bind form:
rpc-bind-addressdocker stop172.30.0.5(specific v4)127.0.0.10.0.0.0[::](current default)fd00:dead:beef::5(specific v6)[fd00:dead:beef::5](bracketed)Control: the stock image with the default
[::]gives ~2 s init / 4 s stop / exit 0 — identical to patched, confirming no change to existing behaviour."graceful exit acked" =
transmission-remotelogs<addr>:9091/transmission/rpc/ acknowledged notificationand the daemon logsClosing transmission session... done.The 20 s in the two IPv6 rows is
transmission-daemonitself taking ~16 s to finish exiting once bound to a global IPv6 address — the daemon logsshutting down~1 s after the exit request, then the process lingers. That is outside these scripts (and is precisely the case thetimeout-finishaddition covers); on stock, that configuration never gets that far at all.Also verified
shellcheckreports no new findings on either script (the one remainingSC2086info ontail --pid=${pid}is pre-existing and untouched), and regeneratedREADME.mdwithlscr.io/linuxserver/jenkins-builderafter adding the changelog entry.Source / References:
USER/PASShalf of the graceful-exit problem, fixed previously)timeout-finishsemantics: https://skarnet.org/software/s6/servicedir.html