core.cron
Управление system-cron задачами через /etc/cron.d/: одно правило на файл.
core.cron держит job-файл /etc/cron.d/<name> в нужном состоянии — одна строка <schedule> <user> <command>. present идемпотентен по побайтовой сверке содержимого файла; cron подхватывает изменения сам, reload демона не нужен. Покрывает только system-level задачи (user-crontab через crontab -u вне области); требует root — запись идёт в /etc/cron.d/.
Требования
- Rootтребуется
- Сторона
soul-side - Коллекция
soulstack.system - Категория
system
run_as_rootfs_write_rootСостояния
core.cron.present — Job-файл /etc/cron.d/<name> существует с заданным расписанием и командой.
Файла не было либо его содержимое отличается от целевой строки <schedule> <user> <command> (побайтовая сверка).
Файл уже содержит целевую строку побайтово.
Параметры
| Параметр | Тип | Обяз. / дефолт | Описание |
|---|---|---|---|
name | string | required | Имя job (= имя файла в /etc/cron.d, [A-Za-z0-9_-]). |
schedule | string | required | Cron-расписание (5 полей), напр. "0 3 * * *". |
command | string | required | Команда, запускаемая по расписанию. |
user | string | optional | Пользователь запуска (default root). |
Пример — Ночная ротация логов
- name: Schedule nightly log rotation module: core.cron.present params: name: app-log-rotate schedule: "0 3 * * *" command: "/usr/local/bin/rotate-logs.sh" user: rootПример — Бэкап под выделенным пользователем (минимизация привилегий)
- name: Schedule nightly backup module: core.cron.present params: name: nightly-backup schedule: "0 3 * * *" command: "/usr/local/bin/backup.sh" user: backupOutput
| Поле | Тип | Описание |
|---|---|---|
name | string | |
path | string | |
installed | true |
core.cron.absent — Job-файл /etc/cron.d/<name> удалён.
Файл был и удалён.
Файла нет.
Параметры
| Параметр | Тип | Обяз. / дефолт | Описание |
|---|---|---|---|
name | string | required | Имя job (= имя файла в /etc/cron.d). |
Output
| Поле | Тип | Описание |
|---|---|---|
name | string | |
path | string | |
installed | false |
Заметки
- Файл пишется in-process (os.WriteFile / os.Remove), без shell и без подпроцессов; каталог /etc/cron.d создаётся при необходимости (на minimal-контейнерах его может не быть). Cron подхватывает изменения в /etc/cron.d/ автоматически — reload демона не требуется.
- Итоговое содержимое — одна строка <schedule> <user> <command>\n. present сверяет её с файлом побайтово: changed=true, если файла не было либо содержимое отличается.
- Файл пишется с mode 0644 (cron строго требует, чтобы файл в /etc/cron.d/ не был group/world-writable); owner модуль не правит — расчёт на то, что прод-Soul бежит из-под root.
- MVP — только system-level задачи (одно правило на файл /etc/cron.d/<name>); user-crontab (crontab -u) отложен. Платформа — Linux-дистрибутивы, чей cron читает /etc/cron.d/; на системах без этого каталога (например FreeBSD) применять нельзя — это контролируется where:-предикатом в scenario, а не самим модулем.
Безопасность и умолчания
- command исполняется cron-демоном по расписанию от имени user (по умолчанию root) — главный инвариант модуля. schedule, user и command подставляются в файл как есть, без валидации синтаксиса и без escape: недоверенная интерполяция в command = отложенное выполнение чужого кода под user.
- Дополнительный вектор: значение с \n в command или schedule впишет в файл лишние cron-строки (синтаксис модуль не парсит). Источник command / schedule / user должен быть автором Destiny/scenario, а не внешним вводом.
- Валидируется только имя job: name ограничен [A-Za-z0-9_-] (совместимость с run-parts + guard от path-injection — точка/слэш/.. отвергаются до записи). На schedule / command / user такой проверки нет — модуль доверяет автору задачи.
- required_capabilities [run_as_root, fs_write_root] — запись в /etc/cron.d/ идёт за пределами /var/lib/soul-stack и требует UID 0; exec_subprocess намеренно не объявлен (внешних исполняемых файлов модуль не запускает). Это декларация для статической сверки soul-lint, а не runtime-повышение прав.