Log rotation actually runs (logrotate is scheduled)
Verify that logrotate is not merely installed but actually scheduled: either logrotate.timer is active, or /etc/cron.daily/logrotate is executable. A perfect logrotate.conf behind a masked timer rotates nothing. This pavois-native growth-* control audits the mechanism that bounds /var/log, not the free space it happens to have today.
Checked against the resolved running state (e.g. sshd -T, sysctl, systemctl show), catches drop-ins and Includes a file read would miss. Caveat: runtime ≠ persistence; a value correct now may not survive a reboot.
What Pavois checks
The check interrogates the runtime scheduler state, not a configuration file: systemctl is-active logrotate.timer must return active, or /etc/cron.daily/logrotate must carry the executable bit (the older, cron-driven path still used on some images). Either path proves rotation will actually fire. Checking the mere presence of /etc/logrotate.conf would be a false-negative factory: the package can be installed, the rules impeccable, and the timer disabled or masked.
describe command('systemctl is-active logrotate.timer 2>/dev/null | grep -qx active || test -x /etc/cron.daily/logrotate && echo ok || echo ko') do
its('stdout.strip') { should eq 'ok' }
endHow to verify it is applied
Confirm the schedule, then that it actually fires:
systemctl is-active logrotate.timer
systemctl list-timers logrotate.timer --all
test -x /etc/cron.daily/logrotate && echo cron-path-ok
logrotate --debug /etc/logrotate.conf performs a dry run and prints which files would rotate, without touching them.
Inspect & investigate
Each run leaves a trace in journalctl -u logrotate.service, and logrotate stamps its own state file (/var/lib/logrotate/status on Debian and Ubuntu, /var/lib/logrotate.status on RHEL): every managed log carries the date of its last rotation. A state file whose timestamps are weeks old is the signature of a rotation that has stopped running, visible long before the disk fills.
Remediation
Pavois runs the logrotate-scheduled step: if a logrotate.timer unit file exists, it is enabled and started immediately (systemctl enable --now logrotate.timer); otherwise, on cron-driven images, /etc/cron.daily/logrotate is made executable. The step is guarded by a not_if that re-tests both paths, so an already-scheduled host is left untouched and confkit harden apply stays idempotent.
Pavois applies this with its own harden engine, the plan below, not a shell script:
| command | systemctl list-unit-files logrotate.timer --no-legend 2>/dev/null | grep -q . && systemctl enable --now logrotate.timer 2>/dev/null; test -f /etc/cron.daily/logrotate && chmod +x /etc/cron.daily/logrotate; true |
|---|---|
| name | logrotate-scheduled |
| not_if | systemctl is-active logrotate.timer 2>/dev/null | grep -qx active || test -x /etc/cron.daily/logrotate |
| resource | exec |
pavois harden plan localwhere the target is local, a user@host SSH alias, or a container , Docs
Impact & precautions
Near-zero operational risk: this re-enables a scheduler that ships enabled by default on every supported distribution. The one consequence to anticipate is that logs will now actually rotate: any tool holding an open file descriptor on a log, or tailing it by path, must handle rotation (copytruncate, or a postrotate signal to the daemon). Weigh that against the failure mode this family was born from: a pavois-hardened host that shut itself down six seconds into every boot because a log filesystem it had carved out reached 100%, with every control green.