Skip to content

Fix runlevel fact on distros without /sbin/runlevel#339

Draft
Copilot wants to merge 1 commit into
masterfrom
copilot/fix-runlevel-issue-on-new-distros
Draft

Fix runlevel fact on distros without /sbin/runlevel#339
Copilot wants to merge 1 commit into
masterfrom
copilot/fix-runlevel-issue-on-new-distros

Conversation

Copilot AI commented May 11, 2026

Copy link
Copy Markdown

On newer distros (Fedora 43+), /sbin/runlevel no longer exists, causing facter/openfact to emit sh: line 1: /sbin/runlevel: No such file or directory on every run.

Changes

  • lib/facter/runlevel.rb: Replace hardcoded backtick call to /sbin/runlevel with a two-stage resolution:

    1. Use Facter::Core::Execution.which('runlevel') — if found, exec it (existing behaviour, now safe)
    2. Fall back to systemctl get-default and map the returned systemd target to the equivalent SysV runlevel; returns nil if neither binary is present
    systemd target runlevel
    poweroff.target 0
    rescue.target 1
    multi-user.target 3
    graphical.target 5
    reboot.target 6
  • spec/unit/facter/runlevel_spec.rb: New unit tests covering the runlevel-present path, all mapped systemd targets, an unmapped target, and the no-binary-available case.

Copilot AI linked an issue May 11, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Fix runlevel availability issue on newer distro releases Fix runlevel fact on distros without /sbin/runlevel May 11, 2026
Copilot finished work on behalf of silug May 11, 2026 16:25
Copilot AI requested a review from silug May 11, 2026 16:25

@op-ct op-ct left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

systemctl get-default isn't a good equivalent for runlevel; see inline comments.

Comment thread lib/facter/runlevel.rb
'graphical.target' => '5',
'reboot.target' => '6',
}
result = Facter::Core::Execution.exec('systemctl get-default')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

systemctl get-default will return the default boot target/"runlevel", but that's not necessarily its current state (which could include more than one runlevel-mapped target simultaneously; see "Q: How do I figure out the current runlevel?" at https://systemd.io/FAQ/ ).

A better way to approximate the number returned by runlevel in systemd would be to check the targets in target_to_runlevel from highest value to lowest, stopping at the first (highest-numbered) target that is currently active. So return 3 if multi-user.target is active and graphical.target is not. This is consistent with the behavior described in the runlevel man page.

- Use Facter::Core::Execution.which to check for runlevel binary
- Fall back to systemctl get-default with target→runlevel mapping
- Use Facter::Core::Execution.exec instead of backticks
- Add unit tests covering all scenarios

Agent-Logs-Url: https://github.com/simp/pupmod-simp-simplib/sessions/7a97386a-2830-4d7b-b32a-861a349ec7bd

Co-authored-by: silug <206992+silug@users.noreply.github.com>
@silug silug force-pushed the copilot/fix-runlevel-issue-on-new-distros branch from 2720e19 to 4964507 Compare June 22, 2026 19:22
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.

runlevel not available on newer distro releases

3 participants