mirror of
https://github.com/crazy-max/diun.git
synced 2025-01-12 11:38:11 +00:00
129 lines
3.5 KiB
Go
129 lines
3.5 KiB
Go
package provider
|
|
|
|
import (
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/containerd/platforms"
|
|
"github.com/crazy-max/diun/v4/internal/model"
|
|
"github.com/crazy-max/diun/v4/pkg/registry"
|
|
"github.com/imdario/mergo"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
var (
|
|
metadataKeyChars = `a-zA-Z0-9_`
|
|
metadataKeyRegexp = regexp.MustCompile(`^[` + metadataKeyChars + `]+$`)
|
|
)
|
|
|
|
// ValidateImage returns a standard image through Docker labels
|
|
func ValidateImage(image string, metadata, labels map[string]string, watchByDef bool, defaults *model.Defaults) (img model.Image, err error) {
|
|
img = model.Image{
|
|
Name: image,
|
|
}
|
|
|
|
if defaults != nil {
|
|
img.WatchRepo = defaults.WatchRepo
|
|
img.NotifyOn = defaults.NotifyOn
|
|
img.MaxTags = defaults.MaxTags
|
|
img.SortTags = defaults.SortTags
|
|
img.IncludeTags = defaults.IncludeTags
|
|
img.ExcludeTags = defaults.ExcludeTags
|
|
img.Metadata = defaults.Metadata
|
|
}
|
|
|
|
if enableStr, ok := labels["diun.enable"]; ok {
|
|
enable, err := strconv.ParseBool(enableStr)
|
|
if err != nil {
|
|
return img, errors.Wrapf(err, "cannot parse %q value of label diun.enable", enableStr)
|
|
}
|
|
if !enable {
|
|
return model.Image{}, nil
|
|
}
|
|
} else if !watchByDef {
|
|
return model.Image{}, nil
|
|
}
|
|
|
|
for key, value := range labels {
|
|
switch {
|
|
case key == "diun.regopt":
|
|
img.RegOpt = value
|
|
case key == "diun.watch_repo":
|
|
if watchRepo, err := strconv.ParseBool(value); err == nil {
|
|
img.WatchRepo = &watchRepo
|
|
} else {
|
|
return img, errors.Wrapf(err, "cannot parse %q value of label %s", value, key)
|
|
}
|
|
case key == "diun.notify_on":
|
|
if len(value) == 0 {
|
|
break
|
|
}
|
|
img.NotifyOn = []model.NotifyOn{}
|
|
for _, no := range strings.Split(value, ";") {
|
|
notifyOn := model.NotifyOn(no)
|
|
if !notifyOn.Valid() {
|
|
return img, errors.Errorf("unknown notify status %q", value)
|
|
}
|
|
img.NotifyOn = append(img.NotifyOn, notifyOn)
|
|
}
|
|
case key == "diun.sort_tags":
|
|
if value == "" {
|
|
break
|
|
}
|
|
sortTags := registry.SortTag(value)
|
|
if !sortTags.Valid() {
|
|
return img, errors.Errorf("unknown sort tags type %q", value)
|
|
}
|
|
img.SortTags = sortTags
|
|
case key == "diun.max_tags":
|
|
if img.MaxTags, err = strconv.Atoi(value); err != nil {
|
|
return img, errors.Wrapf(err, "cannot parse %q value of label %s", value, key)
|
|
}
|
|
case key == "diun.include_tags":
|
|
img.IncludeTags = strings.Split(value, ";")
|
|
case key == "diun.exclude_tags":
|
|
img.ExcludeTags = strings.Split(value, ";")
|
|
case key == "diun.hub_tpl":
|
|
img.HubTpl = value
|
|
case key == "diun.hub_link":
|
|
img.HubLink = value
|
|
case key == "diun.platform":
|
|
platform, err := platforms.Parse(value)
|
|
if err != nil {
|
|
return img, errors.Wrapf(err, "cannot parse %q platform of label %s", value, key)
|
|
}
|
|
img.Platform = model.ImagePlatform{
|
|
OS: platform.OS,
|
|
Arch: platform.Architecture,
|
|
Variant: platform.Variant,
|
|
}
|
|
case strings.HasPrefix(key, "diun.metadata."):
|
|
mkey := strings.TrimPrefix(key, "diun.metadata.")
|
|
if len(mkey) == 0 || len(value) == 0 {
|
|
break
|
|
}
|
|
if err := validateMetadataKey(mkey); err != nil {
|
|
return img, errors.Wrapf(err, "invalid metadata key %q", mkey)
|
|
}
|
|
if img.Metadata == nil {
|
|
img.Metadata = map[string]string{}
|
|
}
|
|
img.Metadata[mkey] = value
|
|
}
|
|
}
|
|
|
|
// Update provider metadata with metadata from img labels
|
|
if err := mergo.Merge(&img.Metadata, metadata); err != nil {
|
|
return img, errors.Wrapf(err, "failed merging metadata")
|
|
}
|
|
|
|
return img, nil
|
|
}
|
|
|
|
func validateMetadataKey(key string) error {
|
|
if !metadataKeyRegexp.MatchString(key) {
|
|
return errors.Errorf("only %q are allowed", metadataKeyChars)
|
|
}
|
|
return nil
|
|
}
|