fix(initsystem): don't let SysVinit match systemd hosts (#409) - #411
fix(initsystem): don't let SysVinit match systemd hosts (#409)#411vikramhh wants to merge 2 commits into
Conversation
`test -d /etc/init.d` succeeds on virtually every systemd distro (kept for LSB compatibility), so SysVinit's probe matched systemd hosts. With the shared registry's move-to-front reorder, a Windows host resolving first demoted Systemd behind SysVinit, so a subsequent systemd Linux host in a mixed Linux+Windows cluster resolved to SysVinit — Service.IsRunning() then probed /etc/init.d/<svc> and returned false for a running service. Require systemd to be absent (stat /run/systemd/system fails) in addition to /etc/init.d existing, mirroring RegisterSystemd's probe, so a systemd host never resolves to SysVinit regardless of factory ordering. Fixes k0sproject#409 Signed-off-by: Vikram bir Singh <vsingh@mirantis.com>
fd0438c to
6fc26fb
Compare
|
Heads-up: the failing |
There was a problem hiding this comment.
Pull request overview
This PR fixes init-system detection so that SysVinit no longer matches systemd-based Linux hosts, preventing incorrect ServiceManager selection in mixed Windows+Linux environments where the provider’s move-to-front optimization can reorder factory precedence.
Changes:
- Tighten SysVinit detection by requiring
/etc/init.dto exist and systemd to be absent (stat /run/systemd/systemmust fail). - Add unit tests covering (1) SysVinit declining when systemd is present and (2) the mixed-cluster regression scenario from #409.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| initsystem/sysvinit.go | Makes SysVinit probing systemd-aware so it can’t shadow Systemd due to registry ordering. |
| initsystem/service_ops_test.go | Adds targeted detector + regression tests reproducing and preventing the mixed Windows/Linux misdetection. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The "SysVinit not detected when systemd is present" test asserted only the ErrNoInitSystem outcome, not that the detection probes ran. Assert both the /etc/init.d and `stat /run/systemd/system` probes were received so the test stays specific and cannot pass without exercising the intended logic. Signed-off-by: Vikram bir Singh <vsingh@mirantis.com>
Implements fix suggestion 2 from #409 — the maintainer-preferred direction (#409 (comment)).
Problem
In a mixed Linux+Windows cluster, rig could resolve SysVinit instead of Systemd for a systemd Linux host.
SysVinit's probetest -d /etc/init.dsucceeds on virtually every systemd distro (the directory is kept for LSB compatibility), so SysVinit matches systemd hosts. Becauseplumbing.Provider.Getmoves a matching factory to the front of the shared registry (a homogeneity optimization), once a Windows host resolves — swappingWinSCMto the front and demotingSystemdbehindSysVinit— a subsequently resolved systemd host matchesSysVinitfirst.Service.IsRunning()then probes/etc/init.d/<svc>and returnsfalsefor a running systemd service, andStart/Stop/Restart/Enable/Disabletarget the wrong init system.Fix
Make SysVinit detection specific: require systemd to be absent (
stat /run/systemd/systemfails) in addition to/etc/init.dexisting, mirroringRegisterSystemd's probe. A systemd host now never resolves to SysVinit regardless of factory order — leaving the move-to-front optimization and the registration order untouched, as suggested in the issue.Tests
SysVinit not detected when systemd is present— SysVinit declines on a host where both/etc/init.dand systemd are present.Systemd wins on a systemd host after a Windows host resolved first (issue #409)— regression test that reproduces the mixed-cluster scenario using the default registry order.The regression test fails on
main(resolves tosysvinit) and passes with this change.go test ./initsystem/...,go vet, andgofmtare all clean.Fixes #409