THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

This is Gitea test Portainer repository mirror from Github
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

117 lines
3.2 KiB

  1. package cron
  2. import (
  3. "github.com/portainer/portainer/api"
  4. "github.com/robfig/cron/v3"
  5. )
  6. // JobScheduler represents a service for managing crons
  7. type JobScheduler struct {
  8. cron *cron.Cron
  9. }
  10. // NewJobScheduler initializes a new service
  11. func NewJobScheduler() *JobScheduler {
  12. return &JobScheduler{
  13. cron: cron.New(),
  14. }
  15. }
  16. // ScheduleJob schedules the execution of a job via a runner
  17. func (scheduler *JobScheduler) ScheduleJob(runner portainer.JobRunner) error {
  18. _, err := scheduler.cron.AddJob(runner.GetSchedule().CronExpression, runner)
  19. return err
  20. }
  21. // UpdateSystemJobSchedule updates the first occurence of the specified
  22. // scheduled job based on the specified job type.
  23. // It does so by re-creating a new cron
  24. // and adding all the existing jobs. It will then re-schedule the new job
  25. // with the update cron expression passed in parameter.
  26. // NOTE: the cron library do not support updating schedules directly
  27. // hence the work-around
  28. func (scheduler *JobScheduler) UpdateSystemJobSchedule(jobType portainer.JobType, newCronExpression string) error {
  29. cronEntries := scheduler.cron.Entries()
  30. newCron := cron.New()
  31. for _, entry := range cronEntries {
  32. if entry.Job.(portainer.JobRunner).GetSchedule().JobType == jobType {
  33. _, err := newCron.AddJob(newCronExpression, entry.Job)
  34. if err != nil {
  35. return err
  36. }
  37. continue
  38. }
  39. newCron.Schedule(entry.Schedule, entry.Job)
  40. }
  41. scheduler.cron.Stop()
  42. scheduler.cron = newCron
  43. scheduler.cron.Start()
  44. return nil
  45. }
  46. // UpdateJobSchedule updates a specific scheduled job by re-creating a new cron
  47. // and adding all the existing jobs. It will then re-schedule the new job
  48. // via the specified JobRunner parameter.
  49. // NOTE: the cron library do not support updating schedules directly
  50. // hence the work-around
  51. func (scheduler *JobScheduler) UpdateJobSchedule(runner portainer.JobRunner) error {
  52. cronEntries := scheduler.cron.Entries()
  53. newCron := cron.New()
  54. for _, entry := range cronEntries {
  55. if entry.Job.(portainer.JobRunner).GetSchedule().ID == runner.GetSchedule().ID {
  56. var jobRunner cron.Job = runner
  57. if entry.Job.(portainer.JobRunner).GetSchedule().JobType == portainer.SnapshotJobType {
  58. jobRunner = entry.Job
  59. }
  60. _, err := newCron.AddJob(runner.GetSchedule().CronExpression, jobRunner)
  61. if err != nil {
  62. return err
  63. }
  64. continue
  65. }
  66. newCron.Schedule(entry.Schedule, entry.Job)
  67. }
  68. scheduler.cron.Stop()
  69. scheduler.cron = newCron
  70. scheduler.cron.Start()
  71. return nil
  72. }
  73. // UnscheduleJob remove a scheduled job by re-creating a new cron
  74. // and adding all the existing jobs except for the one specified via scheduleID.
  75. // NOTE: the cron library do not support removing schedules directly
  76. // hence the work-around
  77. func (scheduler *JobScheduler) UnscheduleJob(scheduleID portainer.ScheduleID) {
  78. cronEntries := scheduler.cron.Entries()
  79. newCron := cron.New()
  80. for _, entry := range cronEntries {
  81. if entry.Job.(portainer.JobRunner).GetSchedule().ID == scheduleID {
  82. continue
  83. }
  84. newCron.Schedule(entry.Schedule, entry.Job)
  85. }
  86. scheduler.cron.Stop()
  87. scheduler.cron = newCron
  88. scheduler.cron.Start()
  89. }
  90. // Start starts the scheduled jobs
  91. func (scheduler *JobScheduler) Start() {
  92. if len(scheduler.cron.Entries()) > 0 {
  93. scheduler.cron.Start()
  94. }
  95. }