Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

preparations for soft deprecation of legacy notification args #1377

Merged
merged 15 commits into from
Oct 31, 2022
111 changes: 111 additions & 0 deletions cmd/notify-upgrade.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Package cmd contains the watchtower (sub-)commands
package cmd

import (
"fmt"
"os"
"os/signal"
"strings"
"syscall"
"time"

"github.com/containrrr/watchtower/internal/flags"
"github.com/containrrr/watchtower/pkg/container"
"github.com/containrrr/watchtower/pkg/notifications"
"github.com/spf13/cobra"
)

var notifyUpgradeCommand = NewNotifyUpgradeCommand()

// NewNotifyUpgradeCommand creates the notify upgrade command for watchtower
func NewNotifyUpgradeCommand() *cobra.Command {
return &cobra.Command{
Use: "notify-upgrade",
Short: "Upgrade legacy notification configuration to shoutrrr URLs",
Run: runNotifyUpgrade,
}
}

func runNotifyUpgrade(cmd *cobra.Command, args []string) {
if err := runNotifyUpgradeE(cmd, args); err != nil {
logf("Notification upgrade failed: %v", err)
}
}

func runNotifyUpgradeE(cmd *cobra.Command, _ []string) error {
f := cmd.Flags()
flags.ProcessFlagAliases(f)

notifier = notifications.NewNotifier(cmd)
urls := notifier.GetURLs()

logf("Found notification configurations for: %v", strings.Join(notifier.GetNames(), ", "))

outFile, err := os.CreateTemp("/", "watchtower-notif-urls-*")
if err != nil {
return fmt.Errorf("failed to create output file: %v", err)
}
logf("Writing notification URLs to %v", outFile.Name())
logf("")

sb := strings.Builder{}
sb.WriteString("WATCHTOWER_NOTIFICATION_URL=")

for i, u := range urls {
if i != 0 {
sb.WriteRune(' ')
}
sb.WriteString(u)
}

_, err = fmt.Fprint(outFile, sb.String())
tryOrLog(err, "Failed to write to output file")

tryOrLog(outFile.Sync(), "Failed to sync output file")
tryOrLog(outFile.Close(), "Failed to close output file")

containerID := "<CONTAINER>"
cid, err := container.GetRunningContainerID()
tryOrLog(err, "Failed to get running container ID")
if cid != "" {
containerID = cid.ShortID()
}
logf("To get the environment file, use:")
logf("cp %v:%v ./watchtower-notifications.env", containerID, outFile.Name())
logf("")
logf("Note: This file will be removed in 5 minutes or when this container is stopped!")

signalChannel := make(chan os.Signal, 1)
time.AfterFunc(5*time.Minute, func() {
signalChannel <- syscall.SIGALRM
})

signal.Notify(signalChannel, os.Interrupt)
signal.Notify(signalChannel, syscall.SIGTERM)

switch <-signalChannel {
case syscall.SIGALRM:
logf("Timed out!")
case os.Interrupt, syscall.SIGTERM:
logf("Stopping...")
default:
}

if err := os.Remove(outFile.Name()); err != nil {
logf("Failed to remove file, it may still be present in the container image! Error: %v", err)
} else {
logf("Environment file has been removed.")
}

return nil
}

func tryOrLog(err error, message string) {
if err != nil {
logf("%v: %v\n", message, err)
}
}

func logf(format string, v ...interface{}) {
fmt.Fprintln(os.Stderr, fmt.Sprintf(format, v...))
}
2 changes: 2 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func init() {

// Execute the root func and exit in case of errors
func Execute() {
rootCmd.AddCommand(notifyUpgradeCommand)
if err := rootCmd.Execute(); err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -139,6 +140,7 @@ func PreRun(cmd *cobra.Command, _ []string) {
})

notifier = notifications.NewNotifier(cmd)
notifier.AddLogHook()
}

// Run is the main execution flow of the command
Expand Down
Loading