2022-03-26 13:23:39 +05:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/BurntSushi/toml"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
)
|
|
|
|
|
2022-03-29 19:45:31 +05:00
|
|
|
// JobConfig is a TOML representation of job
|
2022-03-26 13:23:39 +05:00
|
|
|
type JobConfig struct {
|
2022-03-29 19:45:31 +05:00
|
|
|
Cron string // cron decription
|
|
|
|
Command string // command for execution
|
|
|
|
Description string // job description
|
2022-03-26 13:23:39 +05:00
|
|
|
}
|
|
|
|
|
2022-03-28 19:55:43 +05:00
|
|
|
type Job struct {
|
|
|
|
Name string // from filename
|
|
|
|
|
2022-03-29 19:45:31 +05:00
|
|
|
JobConfig
|
2022-03-28 19:55:43 +05:00
|
|
|
|
|
|
|
// Fields for stats
|
|
|
|
CurrentRunningCount int
|
|
|
|
LastStartTime string
|
|
|
|
LastEndTime string
|
|
|
|
LastExecutionDuration string
|
|
|
|
LastError string
|
|
|
|
NextLaunch string
|
|
|
|
}
|
|
|
|
|
2022-03-26 20:38:39 +05:00
|
|
|
var globalMutex sync.RWMutex
|
2022-03-26 13:23:39 +05:00
|
|
|
|
|
|
|
func readJob(filePath string) (*Job, error) {
|
|
|
|
var jobConfig JobConfig
|
|
|
|
|
|
|
|
_, err := toml.DecodeFile(filePath, &jobConfig)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
job := &Job{
|
2022-03-29 19:45:31 +05:00
|
|
|
Name: strings.TrimSuffix(filepath.Base(filePath), filepath.Ext(filePath)),
|
|
|
|
JobConfig: jobConfig}
|
2022-03-26 13:23:39 +05:00
|
|
|
|
|
|
|
return job, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (js *JobConfig) Write() {
|
|
|
|
buf := new(bytes.Buffer)
|
|
|
|
toml.NewEncoder(buf).Encode(*js)
|
|
|
|
ioutil.WriteFile("job.conf", buf.Bytes(), 0644)
|
|
|
|
}
|
|
|
|
|
2022-03-29 19:45:31 +05:00
|
|
|
func (j *Job) CommandAndParams() (command string, params []string) {
|
|
|
|
quoted := false
|
|
|
|
items := strings.FieldsFunc(j.JobConfig.Command, func(r rune) bool {
|
|
|
|
if r == '"' {
|
|
|
|
quoted = !quoted
|
|
|
|
}
|
|
|
|
return !quoted && r == ' '
|
|
|
|
})
|
|
|
|
for i := range items {
|
|
|
|
items[i] = strings.Trim(items[i], `"`)
|
|
|
|
}
|
|
|
|
|
|
|
|
return items[0], items[1:]
|
|
|
|
}
|
|
|
|
|
2022-03-26 13:23:39 +05:00
|
|
|
func (j *Job) Run() {
|
|
|
|
startTime := time.Now()
|
|
|
|
|
2022-03-26 20:38:39 +05:00
|
|
|
globalMutex.Lock()
|
2022-03-26 13:23:39 +05:00
|
|
|
j.CurrentRunningCount++
|
2022-03-27 12:39:24 +05:00
|
|
|
j.LastStartTime = startTime.Format(config.TimeFormat)
|
2022-03-26 20:38:39 +05:00
|
|
|
globalMutex.Unlock()
|
2022-03-26 13:23:39 +05:00
|
|
|
|
|
|
|
defer jobLogFile.Close()
|
|
|
|
defer jobLogFile.WriteString("\n")
|
|
|
|
|
|
|
|
l := log.New()
|
|
|
|
l.SetOutput(jobLogFile)
|
2022-03-28 18:24:23 +05:00
|
|
|
l.SetFormatter(log.StandardLogger().Formatter)
|
2022-03-26 13:23:39 +05:00
|
|
|
|
2022-03-29 19:45:31 +05:00
|
|
|
log.WithField("job", j.Name).Info("started")
|
2022-03-26 13:23:39 +05:00
|
|
|
l.Info("started")
|
|
|
|
|
2022-03-29 19:45:31 +05:00
|
|
|
command, params := j.CommandAndParams()
|
|
|
|
|
|
|
|
cmd := exec.Command(command, params...)
|
2022-03-26 13:23:39 +05:00
|
|
|
cmd.Stdout = jobLogFile
|
|
|
|
cmd.Stderr = jobLogFile
|
2022-03-29 21:27:10 +05:00
|
|
|
jobLogFile, _ := os.OpenFile(filepath.Join(config.LogFilesPath, j.Name+".log"), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
|
2022-03-26 13:23:39 +05:00
|
|
|
|
|
|
|
err := cmd.Run()
|
|
|
|
if err != nil {
|
2022-03-29 19:45:31 +05:00
|
|
|
log.WithField("job", j.Name).Error(err.Error())
|
|
|
|
l.WithField("job", j.Name).Error(err.Error())
|
2022-03-26 13:23:39 +05:00
|
|
|
|
2022-03-26 20:38:39 +05:00
|
|
|
globalMutex.Lock()
|
2022-03-26 13:23:39 +05:00
|
|
|
j.LastError = err.Error()
|
2022-03-26 20:38:39 +05:00
|
|
|
globalMutex.Unlock()
|
2022-03-26 13:23:39 +05:00
|
|
|
} else {
|
2022-03-26 20:38:39 +05:00
|
|
|
globalMutex.Lock()
|
2022-03-26 13:23:39 +05:00
|
|
|
j.LastError = ""
|
2022-03-26 20:38:39 +05:00
|
|
|
globalMutex.Unlock()
|
2022-03-26 13:23:39 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
endTime := time.Now()
|
2022-03-29 19:45:31 +05:00
|
|
|
log.WithField("job", j.Name).Infof("finished (%s)", endTime.Sub(startTime).Truncate(time.Second).String())
|
2022-03-26 13:23:39 +05:00
|
|
|
l.Infof("finished (%s)", endTime.Sub(startTime).Truncate(time.Second).String())
|
|
|
|
|
2022-03-26 20:38:39 +05:00
|
|
|
globalMutex.Lock()
|
2022-03-26 13:23:39 +05:00
|
|
|
j.CurrentRunningCount--
|
2022-03-27 12:39:24 +05:00
|
|
|
j.LastEndTime = endTime.Format(config.TimeFormat)
|
2022-03-26 13:23:39 +05:00
|
|
|
j.LastExecutionDuration = endTime.Sub(startTime).Truncate(time.Second).String()
|
2022-03-26 20:38:39 +05:00
|
|
|
globalMutex.Unlock()
|
2022-03-26 13:23:39 +05:00
|
|
|
}
|