mirror of
https://github.com/containrrr/watchtower.git
synced 2025-09-21 21:30:48 +02:00
Possibility to define a cron expression which specifies when to check for updated images. This allows to have a schedule in which updates should be made and therefore one could define a maintenance window.
This commit is contained in:
parent
5902e9e0be
commit
525dfea3f2
2 changed files with 58 additions and 24 deletions
81
main.go
81
main.go
|
@ -4,20 +4,21 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"strconv"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/robfig/cron"
|
||||
"github.com/urfave/cli"
|
||||
"github.com/v2tec/watchtower/actions"
|
||||
"github.com/v2tec/watchtower/container"
|
||||
)
|
||||
|
||||
var (
|
||||
wg sync.WaitGroup
|
||||
client container.Client
|
||||
pollInterval time.Duration
|
||||
scheduleSpec string
|
||||
cleanup bool
|
||||
noRestart bool
|
||||
)
|
||||
|
@ -45,6 +46,11 @@ func main() {
|
|||
Value: 300,
|
||||
EnvVar: "WATCHTOWER_POLL_INTERVAL",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "schedule, s",
|
||||
Usage: "the cron expression which defines when to update",
|
||||
EnvVar: "WATCHTOWER_SCHEDULE",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "no-pull",
|
||||
Usage: "do not pull new images",
|
||||
|
@ -86,7 +92,17 @@ func before(c *cli.Context) error {
|
|||
log.SetLevel(log.DebugLevel)
|
||||
}
|
||||
|
||||
pollInterval = time.Duration(c.Int("interval")) * time.Second
|
||||
pollingSet := c.IsSet("interval")
|
||||
cronSet := c.IsSet("schedule")
|
||||
|
||||
if pollingSet && cronSet {
|
||||
log.Fatal("Only schedule or interval can be defined, not both.")
|
||||
} else if cronSet {
|
||||
scheduleSpec = c.String("schedule")
|
||||
} else {
|
||||
scheduleSpec = "@every " + strconv.Itoa(c.Int("interval")) + "s"
|
||||
}
|
||||
|
||||
cleanup = c.GlobalBool("cleanup")
|
||||
noRestart = c.GlobalBool("no-restart")
|
||||
|
||||
|
@ -97,40 +113,57 @@ func before(c *cli.Context) error {
|
|||
}
|
||||
|
||||
client = container.NewClient(!c.GlobalBool("no-pull"))
|
||||
|
||||
handleSignals()
|
||||
return nil
|
||||
}
|
||||
|
||||
func start(c *cli.Context) {
|
||||
func start(c *cli.Context) error {
|
||||
names := c.Args()
|
||||
|
||||
if err := actions.CheckPrereqs(client, cleanup); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for {
|
||||
wg.Add(1)
|
||||
if err := actions.Update(client, names, cleanup, noRestart); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
wg.Done()
|
||||
tryLockSem := make(chan bool, 1)
|
||||
tryLockSem <- true
|
||||
|
||||
time.Sleep(pollInterval)
|
||||
cron := cron.New()
|
||||
err := cron.AddFunc(
|
||||
scheduleSpec,
|
||||
func() {
|
||||
select {
|
||||
case v := <-tryLockSem:
|
||||
defer func() { tryLockSem <- v }()
|
||||
if err := actions.Update(client, names, cleanup, noRestart); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
default:
|
||||
log.Debug("Skipped another update already running.")
|
||||
}
|
||||
|
||||
nextRuns := cron.Entries()
|
||||
if len(nextRuns) > 0 {
|
||||
log.Debug("Scheduled next run: " + nextRuns[0].Next.String())
|
||||
}
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func handleSignals() {
|
||||
log.Info("First run: " + cron.Entries()[0].Schedule.Next(time.Now()).String())
|
||||
cron.Start()
|
||||
|
||||
// Graceful shut-down on SIGINT/SIGTERM
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
signal.Notify(c, syscall.SIGTERM)
|
||||
interrupt := make(chan os.Signal, 1)
|
||||
signal.Notify(interrupt, os.Interrupt)
|
||||
signal.Notify(interrupt, syscall.SIGTERM)
|
||||
|
||||
go func() {
|
||||
<-c
|
||||
wg.Wait()
|
||||
os.Exit(1)
|
||||
}()
|
||||
<-interrupt
|
||||
cron.Stop()
|
||||
log.Info("Waiting for running update to be finished...")
|
||||
<-tryLockSem
|
||||
os.Exit(1)
|
||||
return nil
|
||||
}
|
||||
|
||||
func setEnvOptStr(env string, opt string) error {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue