Files
zot/pkg/retention/rules.go
T
Luca Muscariello 2402296e9a fix: migrate to Go module v2 for proper semantic versioning (#3462)
* fix: migrate to Go module v2 for proper semantic versioning

This change updates the module path from 'zotregistry.dev/zot' to
'zotregistry.dev/zot/v2' to comply with Go's semantic versioning rules.

According to Go's module versioning requirements, major version v2+
must include the major version in the module path. The current
module path 'zotregistry.dev/zot' only supports v0.x.x and v1.x.x
versions, making existing v2.x.x tags (like v2.1.8) unusable.

Changes:
- Updated go.mod module path to zotregistry.dev/zot/v2
- Updated all internal import paths across 280+ Go source files
- Updated configuration files (golangcilint.yaml, gqlgen.yml)
- Updated README.md Go reference badge

This fix enables proper use of existing v2.x.x Git tags and allows
external packages to import zot v2+ versions without compatibility
errors.

Resolves: Go module import compatibility for v2+ versions
Fixes: #3071
Signed-off-by: Luca Muscariello <muscariello@ieee.org>

* fix: regenerate GraphQL files with updated v2 import paths

The gqlgen tool needs to regenerate the GraphQL schema files after
the module path change to use the new v2 imports.

Signed-off-by: Luca Muscariello <muscariello@ieee.org>

---------

Signed-off-by: Luca Muscariello <muscariello@ieee.org>
2025-10-16 22:43:47 -07:00

141 lines
3.0 KiB
Go

package retention
import (
"fmt"
"sort"
"time"
"zotregistry.dev/zot/v2/pkg/retention/types"
)
const (
// rules name.
daysPullName = "pulledWithin"
daysPushName = "pushedWithin"
latestPullName = "mostRecentlyPulledCount"
latestPushName = "mostRecentlyPushedCount"
)
// rules implementatio
type DaysPull struct {
duration time.Duration
}
func NewDaysPull(duration time.Duration) DaysPull {
return DaysPull{duration: duration}
}
func (dp DaysPull) Name() string {
return fmt.Sprintf("%s:%d", daysPullName, dp.duration)
}
func (dp DaysPull) Perform(candidates []*types.Candidate) []*types.Candidate {
filtered := make([]*types.Candidate, 0)
timestamp := time.Now().Add(-dp.duration)
for _, candidate := range candidates {
// we check pushtimestamp because we don't want to delete tags pushed after timestamp
// ie: if the tag doesn't meet PulledWithin: "3days" and the image is 1day old then do not remove!
if candidate.PullTimestamp.After(timestamp) || candidate.PushTimestamp.After(timestamp) {
candidate.RetainedBy = dp.Name()
filtered = append(filtered, candidate)
}
}
return filtered
}
type DaysPush struct {
duration time.Duration
}
func NewDaysPush(duration time.Duration) DaysPush {
return DaysPush{duration: duration}
}
func (dp DaysPush) Name() string {
return fmt.Sprintf("%s:%d", daysPushName, dp.duration)
}
func (dp DaysPush) Perform(candidates []*types.Candidate) []*types.Candidate {
filtered := make([]*types.Candidate, 0)
timestamp := time.Now().Add(-dp.duration)
for _, candidate := range candidates {
if candidate.PushTimestamp.After(timestamp) {
candidate.RetainedBy = dp.Name()
filtered = append(filtered, candidate)
}
}
return filtered
}
type latestPull struct {
count int
}
func NewLatestPull(count int) latestPull {
return latestPull{count: count}
}
func (lp latestPull) Name() string {
return fmt.Sprintf("%s:%d", latestPullName, lp.count)
}
func (lp latestPull) Perform(candidates []*types.Candidate) []*types.Candidate {
sort.Slice(candidates, func(i, j int) bool {
return candidates[i].PullTimestamp.After(candidates[j].PullTimestamp)
})
// take top count candidates
upper := lp.count
if lp.count > len(candidates) {
upper = len(candidates)
}
candidates = candidates[:upper]
for _, candidate := range candidates {
candidate.RetainedBy = lp.Name()
}
return candidates
}
type latestPush struct {
count int
}
func NewLatestPush(count int) latestPush {
return latestPush{count: count}
}
func (lp latestPush) Name() string {
return fmt.Sprintf("%s:%d", latestPushName, lp.count)
}
func (lp latestPush) Perform(candidates []*types.Candidate) []*types.Candidate {
sort.Slice(candidates, func(i, j int) bool {
return candidates[i].PushTimestamp.After(candidates[j].PushTimestamp)
})
// take top count candidates
upper := lp.count
if lp.count > len(candidates) {
upper = len(candidates)
}
candidates = candidates[:upper]
for _, candidate := range candidates {
candidate.RetainedBy = lp.Name()
}
return candidates
}