Skip to content

List the timer unit files on disk, not only the loaded timers - #14

Merged
edimarlnx merged 1 commit into
mainfrom
fix/own-timer-visible
Sep 2, 2026
Merged

edimarlnx merged 1 commit into
mainfrom
fix/own-timer-visible

Conversation

@edimarlnx

Copy link
Copy Markdown
Contributor

A timer written with c was invisible in the tool that wrote it.

c installs the .service and the .timer, runs daemon-reload, and does not enable the timer. systemd loads no unit that nothing references, so the new timer is in neither systemctl list-timers --all nor systemctl list-units --type=timer — the two lists this tool enumerated from. The timer was on disk, correct, verified, and had no row: nothing to select, so nothing to enable, run or delete either. Reproduced here on systemd 257:

$ systemctl --user list-timers --all | grep -c probe   # 0
$ systemctl --user list-units --type=timer --all | grep -c probe   # 0
$ systemctl --user list-unit-files --type=timer | grep probe
zz-probe-cron.timer          disabled disabled

What changed

  • internal/timers: listTimers merges the loaded timers with systemctl list-unit-files --type=timer, loaded first and disk-only appended, so the order a reader knows does not move. Templates (name@.timer) and alias rows are dropped — neither is a unit systemctl show can be pointed at. The unit-file read is best-effort: if that systemctl refuses it, the loaded list is returned unchanged.
  • internal/jobs (--demo): the sample machine had the same hole twice — BuildCreate never staged the unit files into the map the install hook reads, and an installed whole unit was recorded nowhere — so the demo created a timer and then showed nothing. It now keeps installed units and builds the row from them, the way the real backend reads them off disk. A deletion forgets them again.
  • test/smoke.sh: the timer count was asserted against list-units alone, which any machine with an installed-but-disabled timer (fwupd-refresh.timer, typically) would now fail. It compares against the union of both lists.
  • README: how the list is built and why both halves are needed.

No new mutation, no change to any command a confirm dialog shows. Deleting such a timer works unchanged: systemctl disable --now on a never-enabled unit exits 0.

Verified

  • go test ./..., make lint clean; new unit tests for the unit-file parsing (real captures in internal/timers/testdata, including one of a freshly written timer), for the merge, a fuzz target, and an end-to-end demo test that creates a timer, finds the row, and deletes it.
  • test/smoke.sh against this Fedora 42 host: 25 passed, 0 failed, timer count 17 on both sides.

🤖 Generated with Claude Code

Writing a timer with c installed both unit files and reloaded systemd, and the
timer then appeared nowhere in the tool that made it. systemd loads no unit
that nothing references, so a timer that is written and not yet enabled is in
neither `list-timers --all` nor `list-units --type=timer`: it was on disk,
correct, verified, and unreachable — no row to select, and therefore no way to
enable it, run it or delete it.

The enumeration now merges the loaded timers with `list-unit-files
--type=timer`, keeping the loaded ones in place and appending what only the
disk has. Templates and alias rows are dropped, since neither is a unit
`systemctl show` can be pointed at. The extra list is best-effort: a systemctl
that refuses it leaves the loaded timers exactly as they were.

The sample machine had the same hole twice over — the create plan never staged
its unit files, and an installed unit was recorded nowhere — so --demo created
a timer it then failed to show. It now keeps the units it was asked to install
and builds the row from them, which is what the real backend reads from disk.

The smoke suite compared the tool's timer count against `list-units` alone,
which every machine with an installed-but-disabled timer would now fail; it
compares against the union of both lists.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MCypLQF5AD8JD831Ea9S9q
@edimarlnx
edimarlnx merged commit 7b588d1 into main Sep 2, 2026
8 checks passed
@edimarlnx
edimarlnx deleted the fix/own-timer-visible branch September 2, 2026 16:09
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.

1 participant