github.com/argoproj/argo-cd@v1.8.7/reposerver/gpgwatcher.go (about) 1 package reposerver 2 3 import ( 4 "fmt" 5 "path" 6 "time" 7 8 "github.com/fsnotify/fsnotify" 9 log "github.com/sirupsen/logrus" 10 11 "github.com/argoproj/argo-cd/util/gpg" 12 ) 13 14 const maxRecreateRetries = 5 15 16 // StartGPGWatcher watches a given directory for creation and deletion of files and syncs the GPG keyring 17 func StartGPGWatcher(sourcePath string) error { 18 log.Infof("Starting GPG sync watcher on directory '%s'", sourcePath) 19 forceSync := false 20 watcher, err := fsnotify.NewWatcher() 21 if err != nil { 22 return err 23 } 24 defer watcher.Close() 25 26 done := make(chan bool) 27 go func() { 28 for { 29 select { 30 case event, ok := <-watcher.Events: 31 if !ok { 32 return 33 } 34 if event.Op&fsnotify.Create == fsnotify.Create || event.Op&fsnotify.Remove == fsnotify.Remove { 35 // In case our watched path is re-created (i.e. during e2e tests), we need to watch again 36 // For more robustness, we retry re-creating the watcher up to maxRecreateRetries 37 if event.Name == sourcePath && event.Op&fsnotify.Remove == fsnotify.Remove { 38 log.Warnf("Re-creating watcher on %s", sourcePath) 39 attempt := 0 40 for { 41 err = watcher.Add(sourcePath) 42 if err != nil { 43 log.Errorf("Error re-creating watcher on %s: %v", sourcePath, err) 44 if attempt < maxRecreateRetries { 45 attempt += 1 46 log.Infof("Retrying to re-create watcher, attempt %d of %d", attempt, maxRecreateRetries) 47 time.Sleep(1 * time.Second) 48 continue 49 } else { 50 log.Errorf("Maximum retries exceeded.") 51 close(done) 52 return 53 } 54 } 55 break 56 } 57 // Force sync because we probably missed an event 58 forceSync = true 59 } 60 if gpg.IsShortKeyID(path.Base(event.Name)) || forceSync { 61 log.Infof("Updating GPG keyring on filesystem event") 62 added, removed, err := gpg.SyncKeyRingFromDirectory(sourcePath) 63 if err != nil { 64 log.Errorf("Could not sync keyring: %s", err.Error()) 65 } else { 66 log.Infof("Result of sync operation: keys added: %d, keys removed: %d", len(added), len(removed)) 67 } 68 forceSync = false 69 } 70 } 71 case err, ok := <-watcher.Errors: 72 if !ok { 73 return 74 } 75 log.Errorf("%v", err) 76 } 77 } 78 }() 79 80 err = watcher.Add(sourcePath) 81 if err != nil { 82 return err 83 } 84 <-done 85 return fmt.Errorf("Abnormal termination of GPG watcher, refusing to continue.") 86 }