From 7a8b4677fc41af7af65ef509a176c71f5125a21c Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Sun, 22 Dec 2019 16:32:27 +0100 Subject: [PATCH] Add option to skip notification at the very first analysis of an image (#10) --- doc/configuration.md | 2 ++ internal/app/job.go | 12 ++++++++++++ internal/config/config.go | 5 +++-- internal/config/config.test.yml | 1 + internal/db/client.go | 18 ++++++++++++++++++ internal/model/job.go | 9 +++++---- internal/model/watch.go | 5 +++-- pkg/docker/registry/README.md | 1 - pkg/docker/registry/image.go | 1 + pkg/docker/registry/name.go | 6 ++++++ 10 files changed, 51 insertions(+), 9 deletions(-) delete mode 100644 pkg/docker/registry/README.md create mode 100644 pkg/docker/registry/name.go diff --git a/doc/configuration.md b/doc/configuration.md index 9203f1ab..bed16d3b 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -9,6 +9,7 @@ db: watch: workers: 10 schedule: "0 * * * *" + first_check_notif: false notif: mail: @@ -94,6 +95,7 @@ providers: * `workers`: Maximum number of workers that will execute tasks concurrently. _Optional_. (default: `10`). * `schedule`: [CRON expression](https://godoc.org/github.com/robfig/cron#hdr-CRON_Expression_Format) to schedule Diun watcher. _Optional_. (default: `0 * * * *`). +* `first_check_notif`: Send notification at the very first analysis of an image. _Optional_. (default: `false`). ## notif diff --git a/internal/app/job.go b/internal/app/job.go index 3f450054..9d81f2f4 100644 --- a/internal/app/job.go +++ b/internal/app/job.go @@ -28,6 +28,13 @@ func (di *Diun) createJob(job model.Job) { return } + // First check? + job.FirstCheck, err = di.db.First(job.RegImage) + if err != nil { + sublog.Error().Err(err).Msg("Cannot check first") + return + } + // Registry options regOpts, err := di.getRegOpts(job.Image.RegOptsID) if err != nil { @@ -166,6 +173,11 @@ func (di *Diun) runJob(job model.Job) error { } sublog.Debug().Msg("Manifest saved to database") + if job.FirstCheck && !di.cfg.Watch.FirstCheckNotif { + sublog.Debug().Msg("Skipping notification (first check)") + return nil + } + di.notif.Send(model.NotifEntry{ Status: status, Provider: job.Provider, diff --git a/internal/config/config.go b/internal/config/config.go index db786386..e2e31eed 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -44,8 +44,9 @@ func Load(flags model.Flags, version string) (*Config, error) { Path: "diun.db", }, Watch: model.Watch{ - Workers: 10, - Schedule: "0 * * * *", + Workers: 10, + Schedule: "0 * * * *", + FirstCheckNotif: false, }, Notif: model.Notif{ Mail: model.NotifMail{ diff --git a/internal/config/config.test.yml b/internal/config/config.test.yml index e05250ef..0745b7c3 100644 --- a/internal/config/config.test.yml +++ b/internal/config/config.test.yml @@ -4,6 +4,7 @@ db: watch: workers: 100 schedule: "*/30 * * * *" + first_check_notif: false notif: mail: diff --git a/internal/db/client.go b/internal/db/client.go index 444d6119..6efe4d89 100644 --- a/internal/db/client.go +++ b/internal/db/client.go @@ -1,6 +1,7 @@ package db import ( + "bytes" "encoding/json" "fmt" "time" @@ -53,6 +54,23 @@ func (c *Client) Close() error { return c.DB.Close() } +// First checks if a Docker image has ever been analyzed +func (c *Client) First(image registry.Image) (bool, error) { + found := false + + err := c.View(func(tx *bolt.Tx) error { + c := tx.Bucket([]byte(bucket)).Cursor() + name := []byte(image.Name()) + for k, _ := c.Seek(name); k != nil && bytes.HasPrefix(k, name); k, _ = c.Next() { + found = true + return nil + } + return nil + }) + + return !found, err +} + // GetManifest returns Docker image manifest func (c *Client) GetManifest(image registry.Image) (docker.Manifest, error) { var manifest docker.Manifest diff --git a/internal/model/job.go b/internal/model/job.go index 437ec51b..4d19107c 100644 --- a/internal/model/job.go +++ b/internal/model/job.go @@ -7,8 +7,9 @@ import ( // Job holds job configuration type Job struct { - Provider string - Image Image - RegImage registry.Image - Registry *docker.RegistryClient + Provider string + Image Image + RegImage registry.Image + Registry *docker.RegistryClient + FirstCheck bool } diff --git a/internal/model/watch.go b/internal/model/watch.go index 385c4df1..2064adaf 100644 --- a/internal/model/watch.go +++ b/internal/model/watch.go @@ -2,6 +2,7 @@ package model // Watch holds data necessary for watch configuration type Watch struct { - Workers int `yaml:"workers,omitempty"` - Schedule string `yaml:"schedule,omitempty"` + Workers int `yaml:"workers,omitempty"` + Schedule string `yaml:"schedule,omitempty"` + FirstCheckNotif bool `yaml:"first_check_notif,omitempty"` } diff --git a/pkg/docker/registry/README.md b/pkg/docker/registry/README.md deleted file mode 100644 index 095de1a1..00000000 --- a/pkg/docker/registry/README.md +++ /dev/null @@ -1 +0,0 @@ -This is a copy of https://github.com/genuinetools/reg/blob/master/registry/image.go as of commit f3a9b00ec86f334702381edf842f03b3a9243a0a diff --git a/pkg/docker/registry/image.go b/pkg/docker/registry/image.go index cbb47e02..a842f677 100644 --- a/pkg/docker/registry/image.go +++ b/pkg/docker/registry/image.go @@ -1,3 +1,4 @@ +// Source: https://github.com/genuinetools/reg/blob/f3a9b00ec86f334702381edf842f03b3a9243a0a/registry/image.go package registry import ( diff --git a/pkg/docker/registry/name.go b/pkg/docker/registry/name.go new file mode 100644 index 00000000..e0ee2c22 --- /dev/null +++ b/pkg/docker/registry/name.go @@ -0,0 +1,6 @@ +package registry + +// Name returns the full name representation of an image. +func (i Image) Name() string { + return i.named.Name() +}