Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ regopts:
Or you can tweak the [`schedule` setting](config/watch.md#schedule) with something like `0 */6 * * *` (every 6 hours).

!!! warning
Also be careful with the `watch_repo` setting as it will fetch manifest for **ALL** tags available for the image.
Also be careful with the `watch_repo` setting as it will fetch manifest for **ALL** tags available for the image if set to true. If using semver sorting, you can set `watch_repo` to semver and it will instead only watch images that are newer versions than the current image.

## Tags sorting when using `watch_repo`

Expand Down
4 changes: 2 additions & 2 deletions internal/app/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (di *Diun) createJob(job model.Job) {
// Set defaults
if err := mergo.Merge(&job.Image, model.Image{
Platform: model.ImagePlatform{},
WatchRepo: utl.NewFalse(),
WatchRepo: model.WatchRepoNo,
MaxTags: 0,
}); err != nil {
sublog.Error().Err(err).Msg("Cannot set default values")
Expand Down Expand Up @@ -118,7 +118,7 @@ func (di *Diun) createJob(job model.Job) {
sublog.Error().Err(err).Msgf("Invoking job")
}

if !*job.Image.WatchRepo || len(job.RegImage.Domain) == 0 {
if job.Image.WatchRepo == model.WatchRepoNo || len(job.RegImage.Domain) == 0 {
return
}

Expand Down
2 changes: 1 addition & 1 deletion internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func TestLoadFile(t *testing.T) {
},
},
Defaults: &model.Defaults{
WatchRepo: utl.NewFalse(),
WatchRepo: model.WatchRepoNo,
NotifyOn: []model.NotifyOn{model.NotifyOnNew},
MaxTags: 5,
SortTags: registry.SortTagReverse,
Expand Down
5 changes: 2 additions & 3 deletions internal/model/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ package model

import (
"github.com/crazy-max/diun/v4/pkg/registry"
"github.com/crazy-max/diun/v4/pkg/utl"
)

// Defaults holds data necessary for image defaults configuration
type Defaults struct {
WatchRepo *bool `yaml:"watchRepo,omitempty" json:"watchRepo,omitempty"`
WatchRepo WatchRepo `yaml:"watchRepo,omitempty" json:"watchRepo,omitempty"`
NotifyOn []NotifyOn `yaml:"notifyOn,omitempty" json:"notifyOn,omitempty"`
MaxTags int `yaml:"maxTags,omitempty" json:"maxTags,omitempty"`
SortTags registry.SortTag `yaml:"sortTags,omitempty" json:"sortTags,omitempty"`
Expand All @@ -25,7 +24,7 @@ func (s *Defaults) GetDefaults() *Defaults {

// SetDefaults sets the default values
func (s *Defaults) SetDefaults() {
s.WatchRepo = utl.NewFalse()
s.WatchRepo = WatchRepoNo
s.NotifyOn = NotifyOnDefaults
s.SortTags = registry.SortTagReverse
}
23 changes: 22 additions & 1 deletion internal/model/image.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package model

import (
"slices"

"github.com/crazy-max/diun/v4/pkg/registry"
)

Expand All @@ -9,7 +11,7 @@ type Image struct {
Name string `yaml:"name,omitempty" json:",omitempty"`
Platform ImagePlatform `yaml:"platform,omitempty" json:",omitempty"`
RegOpt string `yaml:"regopt,omitempty" json:",omitempty"`
WatchRepo *bool `yaml:"watch_repo,omitempty" json:",omitempty"`
WatchRepo WatchRepo `yaml:"watch_repo,omitempty" json:",omitempty"`
NotifyOn []NotifyOn `yaml:"notify_on,omitempty" json:",omitempty"`
MaxTags int `yaml:"max_tags,omitempty" json:",omitempty"`
SortTags registry.SortTag `yaml:"sort_tags,omitempty" json:",omitempty"`
Expand All @@ -27,6 +29,25 @@ type ImagePlatform struct {
Variant string `yaml:"variant,omitempty" json:",omitempty"`
}

// WatchRepo constants
const (
WatchRepoNo = WatchRepo("false")
WatchRepoAll = WatchRepo("true")
WatchRepoSemver = WatchRepo("semver")
)

// Valid checks watch repo is valid
func (w WatchRepo) Valid() bool {
return slices.Contains([]WatchRepo{
WatchRepoNo,
WatchRepoAll,
WatchRepoSemver,
}, w)
}

// WatchRepo holds repo watching intent
type WatchRepo string

// ImageStatus constants
const (
ImageStatusNew = ImageStatus("new")
Expand Down
9 changes: 7 additions & 2 deletions internal/provider/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,14 @@ func ValidateImage(image string, metadata, labels map[string]string, watchByDef
img.RegOpt = value
case key == "diun.watch_repo":
if watchRepo, err := strconv.ParseBool(value); err == nil {
img.WatchRepo = &watchRepo
// If boolean value, coerce it into true/false
img.WatchRepo = model.WatchRepo(strconv.FormatBool(watchRepo))
} else {
return img, errors.Wrapf(err, "cannot parse %q value of label %s", value, key)
// Otherwise use it directly
img.WatchRepo = model.WatchRepo(value)
}
if !img.WatchRepo.Valid() {
return img, errors.Errorf(`invalid value of watch_repo %q`, value)
}
case key == "diun.notify_on":
if len(value) == 0 {
Expand Down
33 changes: 24 additions & 9 deletions internal/provider/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (

"github.com/crazy-max/diun/v4/internal/model"
"github.com/crazy-max/diun/v4/pkg/registry"
"github.com/crazy-max/diun/v4/pkg/utl"
"github.com/pkg/errors"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -111,11 +110,11 @@ func TestValidateImage(t *testing.T) {
image: "myimg",
watchByDef: true,
defaults: &model.Defaults{
WatchRepo: utl.NewTrue(),
WatchRepo: model.WatchRepoAll,
},
expectedImage: model.Image{
Name: "myimg",
WatchRepo: utl.NewTrue(),
WatchRepo: model.WatchRepoAll,
},
expectedErr: nil,
},
Expand All @@ -130,7 +129,7 @@ func TestValidateImage(t *testing.T) {
expectedImage: model.Image{
Name: "myimg",
},
expectedErr: errors.New(`cannot parse "chickens" value of label diun.watch_repo`),
expectedErr: errors.New(`invalid value of watch_repo "chickens"`),
},
{
name: "Override default image values with labels (true > false)",
Expand All @@ -140,27 +139,43 @@ func TestValidateImage(t *testing.T) {
"diun.watch_repo": "false",
},
defaults: &model.Defaults{
WatchRepo: utl.NewTrue(),
WatchRepo: model.WatchRepoAll,
},
expectedImage: model.Image{
Name: "myimg",
WatchRepo: utl.NewFalse(),
WatchRepo: model.WatchRepoNo,
},
expectedErr: nil,
},
{
name: "Override default image values with labels (false > true): invalid label error",
name: "Override default image values with labels (false > true)",
image: "myimg",
watchByDef: true,
labels: map[string]string{
"diun.watch_repo": "true",
},
defaults: &model.Defaults{
WatchRepo: utl.NewFalse(),
WatchRepo: model.WatchRepoNo,
},
expectedImage: model.Image{
Name: "myimg",
WatchRepo: utl.NewTrue(),
WatchRepo: model.WatchRepoAll,
},
expectedErr: nil,
},
{
name: "Override default image values with labels (false > semver)",
image: "myimg",
watchByDef: true,
labels: map[string]string{
"diun.watch_repo": "semver",
},
defaults: &model.Defaults{
WatchRepo: model.WatchRepoNo,
},
expectedImage: model.Image{
Name: "myimg",
WatchRepo: model.WatchRepoSemver,
},
expectedErr: nil,
},
Expand Down
15 changes: 7 additions & 8 deletions internal/provider/file/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (

"github.com/crazy-max/diun/v4/internal/model"
"github.com/crazy-max/diun/v4/pkg/registry"
"github.com/crazy-max/diun/v4/pkg/utl"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -42,7 +41,7 @@ var (
Provider: "file",
Image: model.Image{
Name: "docker.bintray.io/jfrog/xray-server:2.8.6",
WatchRepo: utl.NewTrue(),
WatchRepo: model.WatchRepoAll,
NotifyOn: []model.NotifyOn{
model.NotifyOnNew,
},
Expand Down Expand Up @@ -78,7 +77,7 @@ var (
Provider: "file",
Image: model.Image{
Name: "crazymax/swarm-cronjob",
WatchRepo: utl.NewTrue(),
WatchRepo: model.WatchRepoAll,
NotifyOn: model.NotifyOnDefaults,
SortTags: registry.SortTagSemver,
MaxTags: 25,
Expand All @@ -94,7 +93,7 @@ var (
Provider: "file",
Image: model.Image{
Name: "docker.io/portainer/portainer",
WatchRepo: utl.NewTrue(),
WatchRepo: model.WatchRepoAll,
NotifyOn: model.NotifyOnDefaults,
MaxTags: 10,
SortTags: registry.SortTagReverse,
Expand All @@ -110,7 +109,7 @@ var (
Provider: "file",
Image: model.Image{
Name: "traefik",
WatchRepo: utl.NewTrue(),
WatchRepo: model.WatchRepoAll,
NotifyOn: model.NotifyOnDefaults,
SortTags: registry.SortTagDefault,
MaxTags: 25,
Expand Down Expand Up @@ -176,7 +175,7 @@ var (
Provider: "file",
Image: model.Image{
Name: "crazymax/ddns-route53",
WatchRepo: utl.NewTrue(),
WatchRepo: model.WatchRepoAll,
NotifyOn: model.NotifyOnDefaults,
SortTags: registry.SortTagReverse,
MaxTags: 25,
Expand Down Expand Up @@ -261,10 +260,10 @@ func TestDefaultImageOptions(t *testing.T) {
fc := New(&model.PrdFile{
Filename: "./fixtures/dockerhub.yml",
}, &model.Defaults{
WatchRepo: utl.NewTrue(),
WatchRepo: model.WatchRepoAll,
})

for _, job := range fc.ListJob() {
assert.True(t, *job.Image.WatchRepo)
assert.Equal(t, model.WatchRepoAll, job.Image.WatchRepo)
}
}
2 changes: 1 addition & 1 deletion internal/provider/file/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (c *Client) listFileImage() []model.Image {

for _, item := range items {
// Set default WatchRepo
if item.WatchRepo == nil {
if item.WatchRepo == "" {
item.WatchRepo = c.defaults.WatchRepo
}
// Check NotifyOn
Expand Down
22 changes: 17 additions & 5 deletions pkg/registry/tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ type Tags struct {

// TagsOptions holds docker tags image options
type TagsOptions struct {
Image Image
Max int
Sort SortTag
Include []string
Exclude []string
Image Image
Max int
Sort SortTag
Include []string
Exclude []string
ExcludeOldVersions bool
}

// Tags returns tags of a Docker repository
Expand All @@ -53,6 +54,8 @@ func (c *Client) Tags(opts TagsOptions) (*Tags, error) {
// Sort tags
tags = SortTags(tags, opts.Sort)

foundCurrent := false

// Filter
for _, tag := range tags {
if !utl.IsIncluded(tag, opts.Include) {
Expand All @@ -61,6 +64,15 @@ func (c *Client) Tags(opts TagsOptions) (*Tags, error) {
} else if utl.IsExcluded(tag, opts.Exclude) {
res.Excluded++
continue
} else if opts.ExcludeOldVersions && opts.Sort == SortTagSemver {
if foundCurrent {
res.Excluded++
continue
}

if tag == opts.Image.Tag {
foundCurrent = true
}
}
res.List = append(res.List, tag)
}
Expand Down
Loading