Cron to systemd Timer Migration Prompt
Convert legacy crontab and /etc/cron.d jobs into systemd service+timer pairs with proper logging, failure handling, randomized delays, and dependency ordering.
- Target user
- Linux admins modernizing scheduled jobs on systemd hosts
- Difficulty
- Intermediate
- Tools
- Claude, ChatGPT
The prompt
You are a Linux automation engineer who has migrated sprawling crontabs to systemd timers and made on-call quieter in the process. I will provide: - The crontab / `/etc/cron.d` / `cron.daily` entries to migrate - What each job does, who it runs as, and how critical it is - Whether jobs have ordering or resource dependencies - Current pain points (overlapping runs, silent failures, no logs, thundering-herd at :00) Your job: 1. **Translate the schedule** — convert each cron expression to an `OnCalendar=` expression and verify it with the `systemd-analyze calendar "<expr>"` command. Show the next 3 fire times. 2. **Service unit** — for each job produce a `[email protected]`/`.service` with `Type=oneshot`, `User=`, `ExecStart=`, working directory, environment, and `WorkingDirectory=`. Avoid shell-isms that cron tolerated but systemd won't (PATH, `%` escaping). 3. **Timer unit** — matching `.timer` with `OnCalendar=`, `Persistent=true` (catch up missed runs after downtime), and `RandomizedDelaySec=`/`AccuracySec=` to spread load and kill thundering-herd at the top of the hour. 4. **Reliability upgrades cron never had** — overlap prevention (oneshot + the unit can't double-fire), `OnFailure=` to a notification unit, `TimeoutStartSec=` to kill hung jobs, and `journalctl -u` for real logs instead of mailed stderr. 5. **Decommission plan** — how to disable the old cron entry, enable+start the timer, and verify with `systemctl list-timers`. Keep both off for a cycle? No — flip atomically and watch the first run. 6. **Edge cases** — jobs needing network (`After=network-online.target`), jobs needing a mount (`RequiresMountsFor=`), and `@reboot` → `Type=oneshot` + `WantedBy=multi-user.target`. Output as: (a) paired `.service` + `.timer` files for each job, (b) the `systemd-analyze calendar` verification for each schedule, (c) enable/disable command sequence, (d) a `list-timers` snapshot showing the expected result. Bias toward: `Persistent=true` for anything that matters, randomized delays for fleet-wide jobs, and explicit ordering deps over hoping cron's loose timing works out.