From f618593296ee0a7519721c71911150ebd9e7766e Mon Sep 17 00:00:00 2001 From: Vladimir Ermakov Date: Thu, 23 Jan 2025 10:33:37 +0100 Subject: [PATCH] feat(sync): add tag reject_regex filter Fix #2902 Signed-off-by: Vladimir Ermakov --- pkg/extensions/config/sync/config.go | 5 +-- pkg/extensions/sync/content.go | 33 ++++++++++++++++++++ pkg/extensions/sync/content_internal_test.go | 19 +++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/pkg/extensions/config/sync/config.go b/pkg/extensions/config/sync/config.go index ec888a084..d857e21f8 100644 --- a/pkg/extensions/config/sync/config.go +++ b/pkg/extensions/config/sync/config.go @@ -42,6 +42,7 @@ type Content struct { } type Tags struct { - Regex *string - Semver *bool + Regex *string + RejectRegex *string + Semver *bool } diff --git a/pkg/extensions/sync/content.go b/pkg/extensions/sync/content.go index 3a1de48ab..dfa8d649b 100644 --- a/pkg/extensions/sync/content.go +++ b/pkg/extensions/sync/content.go @@ -63,6 +63,13 @@ func (cm ContentManager) FilterTags(repo string, tags []string) ([]string, error } } + if content.Tags.RejectRegex != nil { + tags, err = rejectTagsByRegex(tags, *content.Tags.RejectRegex, cm.log) + if err != nil { + return []string{}, err + } + } + if content.Tags.Semver != nil && *content.Tags.Semver { tags = filterTagsBySemver(tags, cm.log) } @@ -240,6 +247,32 @@ func filterTagsByRegex(tags []string, regex string, log log.Logger) ([]string, e return filteredTags, nil } +// rejectTagsByRegex filter-out images by tag regex given in the config. +func rejectTagsByRegex(tags []string, regex string, log log.Logger) ([]string, error) { + if len(tags) == 0 || regex == "" { + return tags, nil + } + + filteredTags := make([]string, 0, len(tags)) + + log.Info().Str("reject_regex", regex).Msg("filtering out tags using regex") + + tagReg, err := regexp.Compile(regex) + if err != nil { + log.Error().Err(err).Str("reject_regex", regex).Msg("failed to compile regex") + + return filteredTags, err + } + + for _, tag := range tags { + if !tagReg.MatchString(tag) { + filteredTags = append(filteredTags, tag) + } + } + + return filteredTags, nil +} + // filterTagsBySemver filters tags by checking if they are semver compliant. func filterTagsBySemver(tags []string, log log.Logger) []string { filteredTags := []string{} diff --git a/pkg/extensions/sync/content_internal_test.go b/pkg/extensions/sync/content_internal_test.go index 78b03b6c6..de1178008 100644 --- a/pkg/extensions/sync/content_internal_test.go +++ b/pkg/extensions/sync/content_internal_test.go @@ -170,6 +170,7 @@ func TestGetContentByLocalRepo(t *testing.T) { func TestFilterTags(t *testing.T) { allTagsRegex := ".*" badRegex := "[*" + rejectArchRegex := ".*(x86_64|aarch64|amd64|arm64)$" semverFalse := false semverTrue := true testCases := []struct { @@ -234,6 +235,24 @@ func TestFilterTags(t *testing.T) { filteredTags: []string{}, err: false, }, + { + repo: "alpine", + content: []syncconf.Content{ + {Prefix: "**", Tags: &syncconf.Tags{RejectRegex: &allTagsRegex}}, + }, + tags: []string{"v1", "v2", "v3"}, + filteredTags: []string{}, + err: false, + }, + { + repo: "alpine", + content: []syncconf.Content{ + {Prefix: "**", Tags: &syncconf.Tags{RejectRegex: &rejectArchRegex}}, + }, + tags: []string{"v1", "v2-x86_64", "v3-aarch64"}, + filteredTags: []string{"v1"}, + err: false, + }, } Convey("Test FilterTags()", t, func() {