Skip to content

feat: auto-defer systemctl restart/start/reload for unordered modules#64

Draft
troglodyne-bot wants to merge 1 commit into
Troglodyne-Internet-Widgets:masterfrom
troglodyne-bot:koan/auto-defer-systemctl
Draft

feat: auto-defer systemctl restart/start/reload for unordered modules#64
troglodyne-bot wants to merge 1 commit into
Troglodyne-Internet-Widgets:masterfrom
troglodyne-bot:koan/auto-defer-systemctl

Conversation

@troglodyne-bot

Copy link
Copy Markdown
Contributor

What

new_config now automatically wraps bare systemctl restart/start/reload calls in queue_postrun_task for any recipe module that has no order defined in recipes.yaml.

Why

Closes #32. Service restarts during provisioning are fragile — they fire before all config is in place and before dependent services are ready. The existing workaround was for every template author to manually write [% script_dir %]/queue_postrun_task systemctl restart foo, which was easy to forget and created boilerplate noise.

The order key already signals intent: an ordered module (e.g. nostubresolver: order: 0) runs first because others depend on it, so its service calls are correctly left immediate. Unordered modules have no such urgency and should always defer.

How

  • _defer_systemctl_calls($fragment, $script_dir) post-processes each rendered module fragment: replaces systemctl (restart|start|reload) with $script_dir/queue_postrun_task systemctl $1. A fixed-width lookbehind ((?<!queue_postrun_task )) guards against double-deferral.
  • daemon-reload, enable, stop, disable, mask are intentionally left immediate — safe setup ops that don't start services.
  • tpsgi keeps explicit queue_postrun_task systemctl daemon-reload/enable because build_service (which creates the unit file) is itself queued — ordering dependency is real.
  • All 11 templates updated: removed manual [% script_dir %]/queue_postrun_task systemctl restart/start/reload wrappers.

Testing

8 unit tests in Perl for _defer_systemctl_calls: bare restart/start/reload deferred, already-deferred not double-deferred, daemon-reload/enable/stop not deferred, --user flag not matched.

Closes Troglodyne-Internet-Widgets#32.

Modules with `order` set in recipes.yaml run their systemctl calls
immediately during `make` (they're dependencies, everything must be
ready before other targets start).

Modules without `order` now have bare `systemctl restart/start/reload`
calls automatically wrapped in `queue_postrun_task` by `_defer_systemctl_calls`
in `new_config`. This defers service starts until post_install, so
services come up only after the entire provisioning run completes.

Template authors no longer need to manually write `queue_postrun_task systemctl`
for the common case. Exceptions:
- `systemctl daemon-reload` / `enable` / `stop` / `disable` / `mask`:
  left immediate — safe idempotent setup ops that don't start services.
- tpsgi: `daemon-reload` and `enable` remain explicitly queued because
  they must follow the queued `build_service` task that creates the unit file.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

Automatically make calls to systemctl in makefiles deferred if we haven't defined an order for this target

1 participant