]> ruderich.org/simon Gitweb - safcm/safcm.git/commitdiff
safcm: print unfinished hosts on Ctrl-C
authorSimon Ruderich <simon@ruderich.org>
Tue, 20 Apr 2021 14:17:53 +0000 (16:17 +0200)
committerSimon Ruderich <simon@ruderich.org>
Tue, 20 Apr 2021 14:17:53 +0000 (16:17 +0200)
cmd/safcm/sync.go

index 7fa2c936b637c7059e5429b273f310233ee92ed4..238ed62ae5e50f5f3516847817363a3bf894f8b7 100644 (file)
@@ -22,6 +22,7 @@ import (
        "fmt"
        "log"
        "os"
+       "os/signal"
        "sort"
        "strings"
        "sync"
@@ -135,6 +136,38 @@ func MainSync(args []string) error {
                done <- failed
        }()
 
+       hostsLeft := make(map[string]bool)
+       for _, x := range toSync {
+               hostsLeft[x.Name] = true
+       }
+       var hostsLeftMutex sync.Mutex // protects hostsLeft
+
+       // Show unfinished hosts on Ctrl-C
+       sigint := make(chan os.Signal, 1)   // buffered for Notify()
+       signal.Notify(sigint, os.Interrupt) // = SIGINT = Ctrl-C
+       go func() {
+               // Running `ssh` processes get killed by SIGINT which is sent
+               // to all processes
+
+               <-sigint
+               log.Print("Received SIGINT, aborting ...")
+
+               // Print all queued events
+               events <- Event{} // poison pill
+               <-done
+               // "races" with <-done in the main function and will hang here
+               // if the other is faster. This is fine because then all hosts
+               // were synced successfully.
+
+               hostsLeftMutex.Lock()
+               var hosts []string
+               for x := range hostsLeft {
+                       hosts = append(hosts, x)
+               }
+               sort.Strings(hosts)
+               log.Fatalf("Failed to sync %s", strings.Join(hosts, ", "))
+       }()
+
        // Sync all hosts concurrently
        var wg sync.WaitGroup
        for _, x := range toSync {
@@ -160,6 +193,10 @@ func MainSync(args []string) error {
                                }
                        }
                        wg.Done()
+
+                       hostsLeftMutex.Lock()
+                       defer hostsLeftMutex.Unlock()
+                       delete(hostsLeft, x.Name)
                }()
        }