Skip to content

🐛 os: fix services.list reporting wrong running state for systemd services#6890

Merged
syrull merged 1 commit intomainfrom
jdm/fix-systemd-service-list-running-state
Mar 13, 2026
Merged

🐛 os: fix services.list reporting wrong running state for systemd services#6890
syrull merged 1 commit intomainfrom
jdm/fix-systemd-service-list-running-state

Conversation

@jaym
Copy link
Copy Markdown
Contributor

@jaym jaym commented Mar 12, 2026

Summary

  • services.list reported running=false for services that were actually running (e.g., systemd-journald), while service("systemd-journald").running correctly returned true
  • Root cause: batched systemctl show fails on template units (name@.service) with no stdout output and no blank-line separator, causing the parser to merge adjacent records and silently lose service data
  • Fix: replace batched systemctl show calls with a single systemctl list-units --type service --all command, which directly reports ActiveState for all loaded services
  • Also hardens ParseServiceSystemDShow to handle missing record separators (defense in depth)

Test plan

  • New TestParseSystemdListUnits — covers active/inactive/exited/not-found services, bullet prefix, non-service unit filtering
  • New TestParseServiceSystemDShowMergedRecords — verifies parser handles missing blank-line separators
  • Rewritten TestSystemDServiceManagerListUsesListUnits — verifies 2 commands issued, merge behavior, template units, unloaded services
  • Interactive verification on affected system: mql run local -c 'services.list.where(name == /journal/) { name running }' should show running=true for systemd-journald

🤖 Generated with Claude Code

…vices

services.list reported running=false for services that were actually
running (e.g., systemd-journald). The root cause was in the batched
"systemctl show" approach used by List(): template units (name@.service)
cause systemctl show to fail with no stdout output and no blank-line
separator. Since ParseServiceSystemDShow uses blank lines to delimit
records, the service before a template and the service after it get
merged into one record, silently losing the first service's data.

Fix: Replace the batched "systemctl show" calls with a single
"systemctl list-units --type service --all" command, which directly
reports ActiveState for all loaded services. This uses the already-
defined SYSTEMD_LIST_UNITS_REGEX and eliminates the template unit
issue entirely.

Also hardens ParseServiceSystemDShow with defense-in-depth: if a new
Id= is encountered while building a record (missing separator), flush
the current record first.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@mondoo-code-review mondoo-code-review Bot left a comment

Choose a reason for hiding this comment

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

Fixes systemd service listing reporting incorrect running state by replacing fragile batched systemctl show with systemctl list-units.


var (
SYSTEMD_LIST_UNITS_REGEX = regexp.MustCompile(`(?m)^(?:[^\S\n]{2}|●[^\S\n]|)(\S+)(?:[^\S\n])+(loaded|not-found|masked)(?:[^\S\n])+(\S+)(?:[^\S\n])+(\S+)(?:[^\S\n])+(.+)$`)
SYSTEMD_LIST_UNITS_REGEX = regexp.MustCompile(`(?m)^(?:[^\S\n]{2}|●[^\S\n]|)(\S+)(?:[^\S\n])+(\S+)(?:[^\S\n])+(\S+)(?:[^\S\n])+(\S+)(?:[^\S\n])+(.+)$`)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 suggestion — The regex change from (loaded|not-found|masked) to (\S+) for the LOAD column is intentionally more permissive, which is fine since you only check for "not-found" in ParseSystemdListUnits. However, the old restricted pattern would reject malformed lines early. Consider adding a brief comment noting the LOAD column is intentionally matched broadly (e.g., # LOAD column: loaded, not-found, masked, error, etc.).

@jaym jaym marked this pull request as draft March 12, 2026 20:44
@github-actions
Copy link
Copy Markdown
Contributor

Test Results

5 426 tests  +2   5 422 ✅ +2   2m 2s ⏱️ -37s
  412 suites ±0       4 💤 ±0 
   31 files   ±0       0 ❌ ±0 

Results for commit 49edba9. ± Comparison against base commit 2116076.

This pull request removes 1 and adds 3 tests. Note that renamed tests count towards both.
go.mondoo.com/mql/v13/providers/os/resources/services ‑ TestSystemDServiceManagerListUsesBatchedShow
go.mondoo.com/mql/v13/providers/os/resources/services ‑ TestParseServiceSystemDShowMergedRecords
go.mondoo.com/mql/v13/providers/os/resources/services ‑ TestParseSystemdListUnits
go.mondoo.com/mql/v13/providers/os/resources/services ‑ TestSystemDServiceManagerListUsesListUnits

@jaym jaym marked this pull request as ready for review March 12, 2026 23:48
@syrull syrull merged commit bff2bc4 into main Mar 13, 2026
23 checks passed
@syrull syrull deleted the jdm/fix-systemd-service-list-running-state branch March 13, 2026 06:32
@github-actions github-actions Bot locked and limited conversation to collaborators Mar 13, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants