Files
privatae-bastion/client-go/schedulers_linux.go
T
Privatae e4c9b69b46
ci / personal-data (push) Successful in 5s
ci / test (push) Successful in 3m4s
ci / fuzz (push) Successful in 3m45s
bastion 0.53.2
2026-10-20 04:42:14 +00:00

78 lines
2.0 KiB
Go

//go:build linux
package main
import (
"os"
"path/filepath"
"strings"
)
// Linux scheduler inventory: the system crontab and cron.d (five fields, a
// user, a command), every user's crontab under the spool (Debian and RHEL
// layouts), and systemd timers with the ExecStart of the unit they activate.
// User-level systemd timers (`systemctl --user`) are per login session and
// are not read from a root service; that gap is stated, not papered over.
const maxCronFiles = 500
func platformSchedulers() ([]schedEntry, []string, bool) {
all := []schedEntry{}
kinds := []string{}
cronRead := false
readSystem := func(path string) {
data, err := os.ReadFile(path)
if err != nil {
return
}
cronRead = true
all = append(all, parseCrontab(string(data), path, "", true)...)
}
readSystem("/etc/crontab")
if ents, err := os.ReadDir("/etc/cron.d"); err == nil {
for i, e := range ents {
if i >= maxCronFiles || e.IsDir() || strings.HasPrefix(e.Name(), ".") {
continue
}
readSystem(filepath.Join("/etc/cron.d", e.Name()))
}
}
for _, spool := range []string{"/var/spool/cron/crontabs", "/var/spool/cron"} {
ents, err := os.ReadDir(spool)
if err != nil {
continue
}
for i, e := range ents {
if i >= maxCronFiles || e.IsDir() {
continue
}
p := filepath.Join(spool, e.Name())
data, err := os.ReadFile(p)
if err != nil {
continue
}
cronRead = true
all = append(all, parseCrontab(string(data), p, e.Name(), false)...)
}
}
if cronRead {
kinds = append(kinds, "cron")
}
timers := systemdTimerUnits()
if len(timers) > 0 {
kinds = append(kinds, "systemd-timer")
}
for unit, timer := range timers {
out, err := runTimed("systemctl", "show", unit, "-p", "ExecStart", "--value")
if err != nil {
continue
}
cmd := parseExecStart(string(out))
if cmd == "" {
continue
}
all = append(all, schedEntry{Kind: "systemd-timer", Name: timer, Command: truncate(cmd, 200), Schedule: unit})
}
return all, kinds, true
}