dockron/main.go

91 lines
2.1 KiB
Go
Raw Normal View History

2018-08-01 15:56:13 +00:00
package main
import (
"fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/robfig/cron"
"golang.org/x/net/context"
"strings"
"time"
)
2018-08-03 01:56:02 +00:00
var WatchInterval = (5 * time.Second)
2018-08-01 15:56:13 +00:00
type ContainerStartJob struct {
Client *client.Client
ContainerID string
Context context.Context
Name string
Schedule string
}
func (job ContainerStartJob) Run() {
2018-08-03 01:56:02 +00:00
fmt.Println("Starting:", job.Name)
2018-08-01 15:56:13 +00:00
err := job.Client.ContainerStart(job.Context, job.ContainerID, types.ContainerStartOptions{})
if err != nil {
panic(err)
}
}
2018-08-03 01:56:02 +00:00
func QueryScheduledJobs(cli *client.Client) (jobs []ContainerStartJob) {
fmt.Println("Scanning containers for new schedules...")
2018-08-01 15:56:13 +00:00
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true})
if err != nil {
panic(err)
}
for _, container := range containers {
if val, ok := container.Labels["cron.schedule"]; ok {
jobName := strings.Join(container.Names, "/")
2018-08-01 15:59:52 +00:00
jobs = append(jobs, ContainerStartJob{
2018-08-01 15:56:13 +00:00
Schedule: val,
Client: cli,
ContainerID: container.ID,
Context: context.Background(),
Name: jobName,
})
}
}
2018-08-03 01:56:02 +00:00
return
}
2018-08-01 15:59:52 +00:00
2018-08-03 01:56:02 +00:00
func ScheduleJobs(c *cron.Cron, jobs []ContainerStartJob) {
2018-08-01 15:59:52 +00:00
for _, job := range jobs {
2018-08-03 01:56:02 +00:00
fmt.Printf("Scheduling %s (%s) with schedule '%s'\n", job.Name, job.ContainerID[:10], job.Schedule)
2018-08-01 15:59:52 +00:00
c.AddJob(job.Schedule, job)
}
2018-08-03 01:56:02 +00:00
}
func main() {
cli, err := client.NewEnvClient()
if err != nil {
panic(err)
}
2018-08-01 15:59:52 +00:00
2018-08-03 01:56:02 +00:00
// Create a cron
c := cron.New()
2018-08-01 15:56:13 +00:00
// Start the loop
for {
fmt.Println("Tick...")
2018-08-03 01:56:02 +00:00
// HACK: This is risky as it could fall on the same interval as a task and that task would get skipped
// It would be best to manage a ContainerID to Job mapping and then remove entries that are missing
// in the new list and add new entries. However, cron does not support this yet.
// Stop and create a new cron
c.Stop()
c = cron.New()
// Schedule jobs again
jobs := QueryScheduledJobs(cli)
ScheduleJobs(c, jobs)
c.Start()
// Sleep until the next query time
time.Sleep(WatchInterval)
2018-08-01 15:56:13 +00:00
}
}