Skip to content

fix(initsystem): don't let SysVinit match systemd hosts (#409) - #411

Open
vikramhh wants to merge 2 commits into
k0sproject:mainfrom
vikramhh:fix/sysvinit-detection-issue-409
Open

fix(initsystem): don't let SysVinit match systemd hosts (#409)#411
vikramhh wants to merge 2 commits into
k0sproject:mainfrom
vikramhh:fix/sysvinit-detection-issue-409

Conversation

@vikramhh

Copy link
Copy Markdown
Contributor

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 probe test -d /etc/init.d succeeds on virtually every systemd distro (the directory is kept for LSB compatibility), so SysVinit matches systemd hosts. Because plumbing.Provider.Get moves a matching factory to the front of the shared registry (a homogeneity optimization), once a Windows host resolves — swapping WinSCM to the front and demoting Systemd behind SysVinit — a subsequently resolved systemd host matches SysVinit first. Service.IsRunning() then probes /etc/init.d/<svc> and returns false for a running systemd service, and Start/Stop/Restart/Enable/Disable target the wrong init system.

Fix

Make SysVinit detection specific: require systemd to be absent (stat /run/systemd/system fails) in addition to /etc/init.d existing, mirroring RegisterSystemd'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.d and 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 to sysvinit) and passes with this change. go test ./initsystem/..., go vet, and gofmt are all clean.

Fixes #409

`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>
@vikramhh
vikramhh force-pushed the fix/sysvinit-detection-issue-409 branch from fd0438c to 6fc26fb Compare July 29, 2026 03:28
@vikramhh

Copy link
Copy Markdown
Contributor Author

Heads-up: the failing schema-validation check is a pre-existing/flaky failure (go: updates to go.mod needed / go mod tidy), unrelated to this PR — it's also red on #402 and #403, and this change touches no imports or go.mod. All other checks (Lint, DCO, unit, integration-test-linux across alpine/debian12/ubuntu24.04, and windows) are green.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.d to exist and systemd to be absent (stat /run/systemd/system must 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.

Comment thread initsystem/service_ops_test.go
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>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Init-system misdetection on Linux hosts in a mixed Linux+Windows cluster (SysVinit selected instead of Systemd)

2 participants