141 lines
3.3 KiB
Go
141 lines
3.3 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"os/exec"
|
|
"syscall"
|
|
"time"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
var currentConfig config
|
|
|
|
func main() {
|
|
var err error
|
|
currentConfig, err = ReadFromFile("config.yml")
|
|
if err != nil {
|
|
log.Fatal().Err(err).Msg("Cant read config file")
|
|
}
|
|
log.Debug().Interface("config", currentConfig).Msg("config")
|
|
|
|
if len(currentConfig.Jobs) == 0 {
|
|
log.Warn().Msg("config dont include any jobs")
|
|
}
|
|
cronTicker, configTicker := createTickers(realTimeProvider{})
|
|
|
|
// Hauptloop mit select
|
|
for {
|
|
select {
|
|
case t := <-cronTicker:
|
|
execucteJobs(t, currentConfig)
|
|
case <-configTicker:
|
|
log.Debug().Msg("Reload Config")
|
|
currentConfig, err = ReadFromFile("config.yml")
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("cant read config")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func execucteJobs(t time.Time, c config) {
|
|
for _, job := range c.Jobs {
|
|
execute, err := job.MatchCurrentTime(t)
|
|
log.Debug().Bool("execution", execute).Time("t", t).Msg("check cron execution")
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("cant pars time for job")
|
|
}
|
|
if !execute {
|
|
continue
|
|
}
|
|
|
|
go executeJob(t, job, c)
|
|
}
|
|
}
|
|
|
|
func executeJob(t time.Time, job jobconfig, c config) {
|
|
result, err := executeCommand(job)
|
|
log.Info().Str("name", job.Name).Str("command", job.Command).Time("execute-for", t).Int("execCode", result.execCode).Str("output", result.outputString).Err(result.err).Msg("Done execute task")
|
|
if err != nil {
|
|
log.Err(err).Msg("Error while Execute command")
|
|
}
|
|
nc := notificationConfig{}
|
|
for _, n := range c.Notification {
|
|
if n.Name == job.Notification {
|
|
nc = n
|
|
}
|
|
}
|
|
sendNotification(result, nc)
|
|
}
|
|
|
|
func sendNotification(result jobResult, notification notificationConfig) error {
|
|
title := ""
|
|
msg := Message{}
|
|
msg.Priority = 10
|
|
|
|
if result.isSuccess() {
|
|
title = "✅ [scron] " + result.job.Name
|
|
msg.Priority = -1
|
|
} else {
|
|
title = "❌ [scron] " + result.job.Name
|
|
}
|
|
|
|
msg.Message = result.outputString
|
|
msg.Title = title
|
|
|
|
if result.isSuccess() {
|
|
if notification.Success.Gotify.URL != "" {
|
|
err := SendGotifyNotification(notification.Success.Gotify.URL, msg)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("cant send gotify notification")
|
|
}
|
|
}
|
|
if notification.Success.Smtp.Host != "" {
|
|
err := SendSMTPNotification(notification.Success.Smtp, title, result.outputString)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("cant send smtp notification")
|
|
}
|
|
}
|
|
} else {
|
|
if notification.Error.Gotify.URL != "" {
|
|
err := SendGotifyNotification(notification.Error.Gotify.URL, msg)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("cant send gotify notification")
|
|
}
|
|
}
|
|
if notification.Error.Smtp.Host != "" {
|
|
err := SendSMTPNotification(notification.Error.Smtp, title, result.outputString)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("cant send smtp notification")
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func executeCommand(job jobconfig) (jobResult, error) {
|
|
j := jobResult{}
|
|
j.job = job
|
|
var output bytes.Buffer
|
|
cmd := exec.Command("bash", "-c", job.Command)
|
|
cmd.Stdout = &output
|
|
cmd.Stderr = &output
|
|
err := cmd.Run()
|
|
|
|
j.outputString = output.String()
|
|
|
|
if err != nil {
|
|
if exitErr, ok := err.(*exec.ExitError); ok {
|
|
if status, ok := exitErr.Sys().(syscall.WaitStatus); ok {
|
|
j.execCode = status.ExitStatus()
|
|
}
|
|
} else {
|
|
j.err = err
|
|
return j, err
|
|
}
|
|
}
|
|
|
|
return j, nil
|
|
}
|