diff --git a/trigger/poll/watcher.go b/trigger/poll/watcher.go index 2290c351..3e457b14 100644 --- a/trigger/poll/watcher.go +++ b/trigger/poll/watcher.go @@ -18,6 +18,96 @@ type RepositoryWatcher struct { cron *cron.Cron } + +// Watch - starts watching repository for changes, if it's already watching - ignores, +// if details changed - updates details +func (w *RepositoryWatcher) Watch(imageName, schedule, registryUsername, registryPassword string) error { + + imageRef, err := image.Parse(imageName) + if err != nil { + log.WithFields(log.Fields{ + "error": err, + "image_name": imageName, + }).Error("trigger.poll.RepositoryWatcher.Watch: failed to parse image") + return err + } + + key := getImageIdentifier(imageRef) + + // checking whether it's already being watched + details, ok := w.watched[key] + if !ok { + err = w.addJob(imageRef, registryUsername, registryPassword, schedule) + if err != nil { + log.WithFields(log.Fields{ + "error": err, + "image_name": imageName, + "registry_username": registryUsername, + }).Error("trigger.poll.RepositoryWatcher.Watch: failed to add image watch job") + + } + return err + } + + // checking schedule + if details.schedule != schedule { + w.cron.UpdateJob(key, schedule) + } + + // checking auth details, if changed - need to update + if details.registryPassword != registryPassword || details.registryUsername != registryUsername { + // recreating job + w.cron.DeleteJob(key) + err = w.addJob(imageRef, registryUsername, registryPassword, schedule) + if err != nil { + log.WithFields(log.Fields{ + "error": err, + "image_name": imageName, + "registry_username": registryUsername, + }).Error("trigger.poll.RepositoryWatcher.Watch: failed to add image watch job") + } + return err + } + + // nothing to do + + return nil +} + +func (w *RepositoryWatcher) addJob(ref *image.Reference, registryUsername, registryPassword, schedule string) error { + // getting initial digest + digest, err := w.registryClient.Digest(registry.Opts{ + Registry: ref.Registry(), + Name: ref.ShortName(), + Tag: ref.Tag(), + }) + if err != nil { + log.WithFields(log.Fields{ + "error": err, + "image": ref.Remote(), + }).Error("trigger.poll.RepositoryWatcher.addJob: failed to get image digest") + return err + } + + key := getImageIdentifier(ref) + details := &watchDetails{ + imageRef: ref, + digest: digest, // current image digest + registryUsername: registryUsername, + registryPassword: registryPassword, + schedule: schedule, + } + // adding new job + job := NewWatchTagJob(w.providers, w.registryClient, details) + log.WithFields(log.Fields{ + "job_name": key, + "image": ref.Remote(), + "schedule": schedule, + }).Info("trigger.poll.RepositoryWatcher: new job added") + return w.cron.AddJob(key, schedule, job) + +} + // Watch specific tag job type WatchTagJob struct { providers provider.Providers