2021-09-06 13:05:10 +02:00
|
|
|
package schedules
|
|
|
|
|
|
|
|
import (
|
2021-09-06 14:01:38 +02:00
|
|
|
log "github.com/Sirupsen/logrus"
|
|
|
|
"github.com/ansible-semaphore/semaphore/api/tasks"
|
2021-09-06 13:05:10 +02:00
|
|
|
"github.com/ansible-semaphore/semaphore/db"
|
|
|
|
"github.com/robfig/cron/v3"
|
2021-09-06 17:45:43 +02:00
|
|
|
"sync"
|
2021-09-06 13:05:10 +02:00
|
|
|
)
|
|
|
|
|
2021-09-06 14:01:38 +02:00
|
|
|
type ScheduleRunner struct {
|
|
|
|
Store db.Store
|
|
|
|
Schedule db.Schedule
|
2021-09-06 13:05:10 +02:00
|
|
|
}
|
|
|
|
|
2021-09-06 14:01:38 +02:00
|
|
|
func (r ScheduleRunner) Run() {
|
2021-09-06 18:15:37 +02:00
|
|
|
_, err := tasks.AddTaskToPool(r.Store, db.Task{
|
|
|
|
TemplateID: r.Schedule.TemplateID,
|
|
|
|
ProjectID: r.Schedule.ProjectID,
|
|
|
|
}, nil, r.Schedule.ProjectID)
|
2021-09-06 14:01:38 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Error(err)
|
|
|
|
}
|
2021-09-06 13:05:10 +02:00
|
|
|
}
|
|
|
|
|
2021-09-06 14:01:38 +02:00
|
|
|
type SchedulePool struct {
|
2021-09-06 17:45:43 +02:00
|
|
|
cron *cron.Cron
|
|
|
|
locker sync.Locker
|
2021-09-06 13:05:10 +02:00
|
|
|
}
|
|
|
|
|
2021-09-06 17:45:43 +02:00
|
|
|
func (p *SchedulePool) init() {
|
2021-09-06 13:05:10 +02:00
|
|
|
p.cron = cron.New()
|
2021-09-06 17:45:43 +02:00
|
|
|
p.locker = &sync.Mutex{}
|
|
|
|
}
|
2021-09-06 13:05:10 +02:00
|
|
|
|
2021-09-06 17:45:43 +02:00
|
|
|
func (p *SchedulePool) Refresh(d db.Store) {
|
2021-09-06 13:05:10 +02:00
|
|
|
schedules, err := d.GetSchedules()
|
|
|
|
|
|
|
|
if err != nil {
|
2021-09-06 14:01:38 +02:00
|
|
|
log.Error(err)
|
2021-09-06 13:05:10 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-09-06 17:45:43 +02:00
|
|
|
p.locker.Lock()
|
|
|
|
p.clear()
|
2021-09-06 13:05:10 +02:00
|
|
|
for _, schedule := range schedules {
|
2021-09-06 17:45:43 +02:00
|
|
|
_, err := p.addRunner(ScheduleRunner{
|
2021-09-06 14:01:38 +02:00
|
|
|
Store: d,
|
|
|
|
Schedule: schedule,
|
|
|
|
})
|
2021-09-06 13:05:10 +02:00
|
|
|
if err != nil {
|
2021-09-06 14:01:38 +02:00
|
|
|
log.Error(err)
|
2021-09-06 13:05:10 +02:00
|
|
|
}
|
|
|
|
}
|
2021-09-06 17:45:43 +02:00
|
|
|
p.locker.Unlock()
|
2021-09-06 13:05:10 +02:00
|
|
|
}
|
|
|
|
|
2021-09-06 17:45:43 +02:00
|
|
|
func (p *SchedulePool) addRunner(runner ScheduleRunner) (int, error) {
|
|
|
|
id, err := p.cron.AddJob(runner.Schedule.CronFormat, runner)
|
|
|
|
|
2021-09-06 13:05:10 +02:00
|
|
|
if err != nil {
|
2021-09-06 17:45:43 +02:00
|
|
|
return 0, err
|
2021-09-06 13:05:10 +02:00
|
|
|
}
|
2021-09-06 17:45:43 +02:00
|
|
|
|
|
|
|
return int(id), nil
|
2021-09-06 13:05:10 +02:00
|
|
|
}
|
|
|
|
|
2021-09-06 14:01:38 +02:00
|
|
|
func (p *SchedulePool) Run() {
|
2021-09-06 13:05:10 +02:00
|
|
|
p.cron.Run()
|
|
|
|
}
|
|
|
|
|
2021-09-06 17:45:43 +02:00
|
|
|
func (p *SchedulePool) clear() {
|
2021-09-06 14:01:38 +02:00
|
|
|
runners := p.cron.Entries()
|
|
|
|
for _, r := range runners {
|
|
|
|
p.cron.Remove(r.ID)
|
|
|
|
}
|
2021-09-06 17:45:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (p *SchedulePool) Destroy() {
|
|
|
|
p.locker.Lock()
|
|
|
|
p.cron.Stop()
|
|
|
|
p.clear()
|
2021-09-06 14:01:38 +02:00
|
|
|
p.cron = nil
|
2021-09-06 17:45:43 +02:00
|
|
|
p.locker.Unlock()
|
2021-09-06 14:01:38 +02:00
|
|
|
}
|
2021-09-06 13:05:10 +02:00
|
|
|
|
2021-09-06 14:01:38 +02:00
|
|
|
func CreateSchedulePool(d db.Store) (pool SchedulePool) {
|
2021-09-06 17:45:43 +02:00
|
|
|
pool.init()
|
|
|
|
pool.Refresh(d)
|
2021-09-06 14:01:38 +02:00
|
|
|
return
|
2021-09-06 13:05:10 +02:00
|
|
|
}
|
2021-09-06 17:45:43 +02:00
|
|
|
|
|
|
|
func ValidateCronFormat(cronFormat string) error {
|
|
|
|
_, err := cron.ParseStandard(cronFormat)
|
|
|
|
return err
|
|
|
|
}
|