mirror of
https://github.com/containrrr/watchtower.git
synced 2025-09-22 05:40:50 +02:00
feat(notifications): support delayed sending (#1142)
This commit is contained in:
parent
2fa8a2ad0c
commit
1d59fb83dd
6 changed files with 37 additions and 13 deletions
|
@ -82,6 +82,10 @@ func (e *emailTypeNotifier) GetURL(c *cobra.Command) (string, error) {
|
||||||
return conf.GetURL().String(), nil
|
return conf.GetURL().String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *emailTypeNotifier) GetDelay() time.Duration {
|
||||||
|
return e.delay
|
||||||
|
}
|
||||||
|
|
||||||
func (e *emailTypeNotifier) getSubject(c *cobra.Command) string {
|
func (e *emailTypeNotifier) getSubject(c *cobra.Command) string {
|
||||||
subject := GetTitle(c)
|
subject := GetTitle(c)
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
package notifications
|
package notifications
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
ty "github.com/containrrr/watchtower/pkg/types"
|
ty "github.com/containrrr/watchtower/pkg/types"
|
||||||
"github.com/johntdyer/slackrus"
|
"github.com/johntdyer/slackrus"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewNotifier creates and returns a new Notifier, using global configuration.
|
// NewNotifier creates and returns a new Notifier, using global configuration.
|
||||||
|
@ -28,14 +30,14 @@ func NewNotifier(c *cobra.Command) ty.Notifier {
|
||||||
tplString, _ := f.GetString("notification-template")
|
tplString, _ := f.GetString("notification-template")
|
||||||
urls, _ := f.GetStringArray("notification-url")
|
urls, _ := f.GetStringArray("notification-url")
|
||||||
|
|
||||||
urls = AppendLegacyUrls(urls, c)
|
urls, delay := AppendLegacyUrls(urls, c)
|
||||||
|
|
||||||
title := GetTitle(c)
|
title := GetTitle(c)
|
||||||
return newShoutrrrNotifier(tplString, acceptedLogLevels, !reportTemplate, title, urls...)
|
return newShoutrrrNotifier(tplString, acceptedLogLevels, !reportTemplate, title, delay, urls...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppendLegacyUrls creates shoutrrr equivalent URLs from legacy notification flags
|
// AppendLegacyUrls creates shoutrrr equivalent URLs from legacy notification flags
|
||||||
func AppendLegacyUrls(urls []string, cmd *cobra.Command) []string {
|
func AppendLegacyUrls(urls []string, cmd *cobra.Command) ([]string, time.Duration) {
|
||||||
|
|
||||||
// Parse types and create notifiers.
|
// Parse types and create notifiers.
|
||||||
types, err := cmd.Flags().GetStringSlice("notifications")
|
types, err := cmd.Flags().GetStringSlice("notifications")
|
||||||
|
@ -43,6 +45,8 @@ func AppendLegacyUrls(urls []string, cmd *cobra.Command) []string {
|
||||||
log.WithError(err).Fatal("could not read notifications argument")
|
log.WithError(err).Fatal("could not read notifications argument")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delay := time.Duration(0)
|
||||||
|
|
||||||
for _, t := range types {
|
for _, t := range types {
|
||||||
|
|
||||||
var legacyNotifier ty.ConvertibleNotifier
|
var legacyNotifier ty.ConvertibleNotifier
|
||||||
|
@ -71,9 +75,13 @@ func AppendLegacyUrls(urls []string, cmd *cobra.Command) []string {
|
||||||
}
|
}
|
||||||
urls = append(urls, shoutrrrURL)
|
urls = append(urls, shoutrrrURL)
|
||||||
|
|
||||||
|
if delayNotifier, ok := legacyNotifier.(ty.DelayNotifier); ok {
|
||||||
|
delay = delayNotifier.GetDelay()
|
||||||
|
}
|
||||||
|
|
||||||
log.WithField("URL", shoutrrrURL).Trace("created Shoutrrr URL from legacy notifier")
|
log.WithField("URL", shoutrrrURL).Trace("created Shoutrrr URL from legacy notifier")
|
||||||
}
|
}
|
||||||
return urls
|
return urls, delay
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTitle returns a common notification title with hostname appended
|
// GetTitle returns a common notification title with hostname appended
|
||||||
|
|
|
@ -241,7 +241,7 @@ func testURL(args []string, expectedURL string) {
|
||||||
err := command.ParseFlags(args)
|
err := command.ParseFlags(args)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
urls := notifications.AppendLegacyUrls([]string{}, command)
|
urls, _ := notifications.AppendLegacyUrls([]string{}, command)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
stdlog "log"
|
stdlog "log"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/containrrr/shoutrrr"
|
"github.com/containrrr/shoutrrr"
|
||||||
"github.com/containrrr/shoutrrr/pkg/types"
|
"github.com/containrrr/shoutrrr/pkg/types"
|
||||||
|
@ -77,14 +78,14 @@ func (n *shoutrrrTypeNotifier) GetNames() []string {
|
||||||
return names
|
return names
|
||||||
}
|
}
|
||||||
|
|
||||||
func newShoutrrrNotifier(tplString string, acceptedLogLevels []log.Level, legacy bool, title string, urls ...string) t.Notifier {
|
func newShoutrrrNotifier(tplString string, acceptedLogLevels []log.Level, legacy bool, title string, delay time.Duration, urls ...string) t.Notifier {
|
||||||
|
|
||||||
notifier := createNotifier(urls, acceptedLogLevels, tplString, legacy)
|
notifier := createNotifier(urls, acceptedLogLevels, tplString, legacy)
|
||||||
notifier.params = &types.Params{"title": title}
|
notifier.params = &types.Params{"title": title}
|
||||||
log.AddHook(notifier)
|
log.AddHook(notifier)
|
||||||
|
|
||||||
// Do the sending in a separate goroutine so we don't block the main process.
|
// Do the sending in a separate goroutine so we don't block the main process.
|
||||||
go sendNotifications(notifier)
|
go sendNotifications(notifier, delay)
|
||||||
|
|
||||||
return notifier
|
return notifier
|
||||||
}
|
}
|
||||||
|
@ -112,8 +113,9 @@ func createNotifier(urls []string, levels []log.Level, tplString string, legacy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendNotifications(n *shoutrrrTypeNotifier) {
|
func sendNotifications(n *shoutrrrTypeNotifier, delay time.Duration) {
|
||||||
for msg := range n.messages {
|
for msg := range n.messages {
|
||||||
|
time.Sleep(delay)
|
||||||
errs := n.Router.Send(msg, n.params)
|
errs := n.Router.Send(msg, n.params)
|
||||||
|
|
||||||
for i, err := range errs {
|
for i, err := range errs {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package notifications
|
package notifications
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/containrrr/shoutrrr/pkg/types"
|
"github.com/containrrr/shoutrrr/pkg/types"
|
||||||
"github.com/containrrr/watchtower/internal/actions/mocks"
|
"github.com/containrrr/watchtower/internal/actions/mocks"
|
||||||
"github.com/containrrr/watchtower/internal/flags"
|
"github.com/containrrr/watchtower/internal/flags"
|
||||||
|
@ -212,7 +214,7 @@ Turns out everything is on fire
|
||||||
When("batching notifications", func() {
|
When("batching notifications", func() {
|
||||||
When("no messages are queued", func() {
|
When("no messages are queued", func() {
|
||||||
It("should not send any notification", func() {
|
It("should not send any notification", func() {
|
||||||
shoutrrr := newShoutrrrNotifier("", allButTrace, true, "", "logger://")
|
shoutrrr := newShoutrrrNotifier("", allButTrace, true, "", time.Duration(0), "logger://")
|
||||||
shoutrrr.StartNotification()
|
shoutrrr.StartNotification()
|
||||||
shoutrrr.SendNotification(nil)
|
shoutrrr.SendNotification(nil)
|
||||||
Consistently(logBuffer).ShouldNot(gbytes.Say(`Shoutrrr:`))
|
Consistently(logBuffer).ShouldNot(gbytes.Say(`Shoutrrr:`))
|
||||||
|
@ -220,7 +222,7 @@ Turns out everything is on fire
|
||||||
})
|
})
|
||||||
When("at least one message is queued", func() {
|
When("at least one message is queued", func() {
|
||||||
It("should send a notification", func() {
|
It("should send a notification", func() {
|
||||||
shoutrrr := newShoutrrrNotifier("", allButTrace, true, "", "logger://")
|
shoutrrr := newShoutrrrNotifier("", allButTrace, true, "", time.Duration(0), "logger://")
|
||||||
shoutrrr.StartNotification()
|
shoutrrr.StartNotification()
|
||||||
logrus.Info("This log message is sponsored by ContainrrrVPN")
|
logrus.Info("This log message is sponsored by ContainrrrVPN")
|
||||||
shoutrrr.SendNotification(nil)
|
shoutrrr.SendNotification(nil)
|
||||||
|
@ -282,7 +284,7 @@ func sendNotificationsWithBlockingRouter(legacy bool) (*shoutrrrTypeNotifier, *b
|
||||||
Message: "foo bar",
|
Message: "foo bar",
|
||||||
}
|
}
|
||||||
|
|
||||||
go sendNotifications(shoutrrr)
|
go sendNotifications(shoutrrr, time.Duration(0))
|
||||||
|
|
||||||
shoutrrr.StartNotification()
|
shoutrrr.StartNotification()
|
||||||
_ = shoutrrr.Fire(entry)
|
_ = shoutrrr.Fire(entry)
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
package types
|
package types
|
||||||
|
|
||||||
import "github.com/spf13/cobra"
|
import (
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
// ConvertibleNotifier is a notifier capable of creating a shoutrrr URL
|
// ConvertibleNotifier is a notifier capable of creating a shoutrrr URL
|
||||||
type ConvertibleNotifier interface {
|
type ConvertibleNotifier interface {
|
||||||
GetURL(c *cobra.Command) (string, error)
|
GetURL(c *cobra.Command) (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DelayNotifier is a notifier that might need to be delayed before sending notifications
|
||||||
|
type DelayNotifier interface {
|
||||||
|
GetDelay() time.Duration
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue