chore: update golangci-lint and fix all issues (#3575)

* chore: Update golangci-lint

Signed-off-by: Lars Francke <git@lars-francke.de>

* chore: fix all golangci-lint issues

- Remove deprecated `// +build` tags
- Fix godoclint, modernize, wsl_v5, govet, lll, gci, noctx issues
- Update linter configuration
- Modernize code to use Go 1.22+ features (for range N, slices.Contains, etc.)
- Update make check lint the privileged tests

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>

---------

Signed-off-by: Lars Francke <git@lars-francke.de>
Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
Co-authored-by: Lars Francke <git@lars-francke.de>
This commit is contained in:
Andrei Aaron
2025-11-22 23:36:48 +02:00
committed by GitHub
parent 566286ae42
commit da426850e7
242 changed files with 811 additions and 1010 deletions
+10 -5
View File
@@ -27,8 +27,9 @@ type ExtensionConfig struct {
type ImageTrustConfig struct {
BaseConfig `mapstructure:",squash"`
Cosign bool
Notation bool
Cosign bool
Notation bool
}
type APIKeyConfig struct {
@@ -40,13 +41,15 @@ type MgmtConfig struct {
}
type LintConfig struct {
BaseConfig `mapstructure:",squash"`
BaseConfig `mapstructure:",squash"`
MandatoryAnnotations []string
}
type SearchConfig struct {
BaseConfig `mapstructure:",squash"`
CVE *CVEConfig
CVE *CVEConfig
}
type CVEConfig struct {
@@ -61,6 +64,7 @@ type TrivyConfig struct {
type MetricsConfig struct {
BaseConfig `mapstructure:",squash"`
Prometheus *PrometheusConfig
}
@@ -70,7 +74,8 @@ type PrometheusConfig struct {
type ScrubConfig struct {
BaseConfig `mapstructure:",squash"`
Interval time.Duration
Interval time.Duration
}
type UIConfig struct {
+10 -10
View File
@@ -216,7 +216,7 @@ func testConcurrentAccessWithConfig(
done := make(chan bool, 10)
errors := make(chan error, 10)
for i := 0; i < 10; i++ {
for range 10 {
go func() {
defer func() {
if r := recover(); r != nil {
@@ -229,7 +229,7 @@ func testConcurrentAccessWithConfig(
done <- true
}()
for j := 0; j < 100; j++ {
for range 100 {
result := testFunc(extensionConfig)
if !result {
errors <- expectedError
@@ -241,7 +241,7 @@ func testConcurrentAccessWithConfig(
}
// Wait for all goroutines to complete
for i := 0; i < 10; i++ {
for range 10 {
<-done
}
@@ -448,7 +448,7 @@ func TestExtensionConfig(t *testing.T) {
errors := make(chan error, 15)
// Launch goroutines for each method
for i := 0; i < 5; i++ {
for range 5 {
go func() {
defer func() {
if r := recover(); r != nil {
@@ -461,7 +461,7 @@ func TestExtensionConfig(t *testing.T) {
done <- true
}()
for j := 0; j < 50; j++ {
for range 50 {
result := extensionConfig.IsSearchEnabled()
if !result {
errors <- errIsSearchEnabledExpectedTrue
@@ -472,7 +472,7 @@ func TestExtensionConfig(t *testing.T) {
}()
}
for i := 0; i < 5; i++ {
for range 5 {
go func() {
defer func() {
if r := recover(); r != nil {
@@ -485,7 +485,7 @@ func TestExtensionConfig(t *testing.T) {
done <- true
}()
for j := 0; j < 50; j++ {
for range 50 {
result := extensionConfig.IsUIEnabled()
if !result {
errors <- errIsUIEnabledExpectedTrue
@@ -496,7 +496,7 @@ func TestExtensionConfig(t *testing.T) {
}()
}
for i := 0; i < 5; i++ {
for range 5 {
go func() {
defer func() {
if r := recover(); r != nil {
@@ -509,7 +509,7 @@ func TestExtensionConfig(t *testing.T) {
done <- true
}()
for j := 0; j < 50; j++ {
for range 50 {
result := extensionConfig.AreUserPrefsEnabled()
if !result {
errors <- errAreUserPrefsEnabledExpectedTrue
@@ -521,7 +521,7 @@ func TestExtensionConfig(t *testing.T) {
}
// Wait for all goroutines to complete
for i := 0; i < 15; i++ {
for range 15 {
<-done
}
+1
View File
@@ -35,6 +35,7 @@ type Config struct {
type SinkConfig struct {
*Credentials
*TLSConfig
Type SinkType
Address string
Channel string
+3 -3
View File
@@ -10,17 +10,17 @@ import (
// SinkConfigDecoderHook provides a mapstructure hook for decoding SinkConfig interfaces.
func SinkConfigDecoderHook() mapstructure.DecodeHookFunc {
return func(_ reflect.Type, target reflect.Type, data interface{}) (interface{}, error) {
return func(_ reflect.Type, target reflect.Type, data any) (any, error) {
// Only apply this hook when converting to SinkConfig
if target.Name() != "SinkConfig" {
return data, nil
}
if target != reflect.TypeOf((*SinkConfig)(nil)).Elem() {
if target != reflect.TypeFor[SinkConfig]() {
return data, nil
}
dataMap, ok := data.(map[string]interface{})
dataMap, ok := data.(map[string]any)
if !ok {
return data, nil
}
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"time"
)
// key is registry address.
// CredentialsFile is a map where key is registry address.
type CredentialsFile map[string]Credentials
type Credentials struct {
-1
View File
@@ -1,5 +1,4 @@
//go:build events
// +build events
package events
-1
View File
@@ -1,5 +1,4 @@
//go:build events
// +build events
package events
-1
View File
@@ -1,5 +1,4 @@
//go:build events
// +build events
package events_test
-1
View File
@@ -1,5 +1,4 @@
//go:build events
// +build events
package events
+2 -2
View File
@@ -1,5 +1,4 @@
//go:build events
// +build events
package events
@@ -18,6 +17,7 @@ import (
type HTTPSink struct {
cloudevents.Client
config eventsconf.SinkConfig
}
@@ -133,7 +133,7 @@ func GetHTTPClientForConfig(config eventsconf.SinkConfig) (*http.Client, error)
}, nil
}
// Helper function for basic auth encoding.
// BasicAuth is a helper function for basic auth encoding.
func BasicAuth(username, password string) string {
auth := username + ":" + password
-1
View File
@@ -1,5 +1,4 @@
//go:build events
// +build events
package events_test
+1 -1
View File
@@ -1,5 +1,4 @@
//go:build events
// +build events
package events
@@ -18,6 +17,7 @@ import (
// NATSSink implements a CloudEvents sink that publishes to NATS.
type NATSSink struct {
cloudevents.Client
conn *nats.Conn
config eventsconf.SinkConfig
}
-1
View File
@@ -1,5 +1,4 @@
//go:build events
// +build events
package events_test
-1
View File
@@ -1,5 +1,4 @@
//go:build events
// +build events
package extensions
@@ -1,5 +1,4 @@
//go:build !events
// +build !events
package extensions
@@ -1,5 +1,4 @@
//go:build !events
// +build !events
package extensions_test
+2 -3
View File
@@ -1,5 +1,4 @@
//go:build imagetrust
// +build imagetrust
package extensions
@@ -74,7 +73,7 @@ type ImageTrust struct {
Log log.Logger
}
// Cosign handler godoc
// HandleCosignPublicKeyUpload godoc
// @Summary Upload cosign public keys for verifying signatures
// @Description Upload cosign public keys for verifying signatures
// @Router /v2/_zot/ext/cosign [post]
@@ -108,7 +107,7 @@ func (trust *ImageTrust) HandleCosignPublicKeyUpload(response http.ResponseWrite
response.WriteHeader(http.StatusOK)
}
// Notation handler godoc
// HandleNotationCertificateUpload godoc
// @Summary Upload notation certificates for verifying signatures
// @Description Upload notation certificates for verifying signatures
// @Router /v2/_zot/ext/notation [post]
@@ -1,5 +1,4 @@
//go:build !imagetrust
// +build !imagetrust
package extensions
+4 -5
View File
@@ -1,5 +1,4 @@
//go:build search && imagetrust
// +build search,imagetrust
package extensions_test
@@ -118,7 +117,7 @@ func TestSignaturesAllowedMethodsHeader(t *testing.T) {
func TestSignatureUploadAndVerificationLocal(t *testing.T) {
Convey("test with local storage", t, func() {
var cacheDriverParams map[string]interface{}
var cacheDriverParams map[string]any
RunSignatureUploadAndVerificationTests(t, cacheDriverParams)
})
@@ -128,7 +127,7 @@ func TestSignatureUploadAndVerificationRedis(t *testing.T) {
Convey("test with local storage and redis metadb", t, func() {
miniRedis := miniredis.RunT(t)
cacheDriverParams := map[string]interface{}{
cacheDriverParams := map[string]any{
"name": "redis",
"url": "redis://" + miniRedis.Addr(),
}
@@ -152,7 +151,7 @@ func TestSignatureUploadAndVerificationAWS(t *testing.T) {
imageMetaTablename := "imageMetaTable" + uuid.String()
repoBlobsInfoTablename := "repoBlobsInfoTable" + uuid.String()
cacheDriverParams := map[string]interface{}{
cacheDriverParams := map[string]any{
"name": "dynamodb",
"endpoint": os.Getenv("DYNAMODBMOCK_ENDPOINT"),
"region": "us-east-2",
@@ -171,7 +170,7 @@ func TestSignatureUploadAndVerificationAWS(t *testing.T) {
})
}
func RunSignatureUploadAndVerificationTests(t *testing.T, cacheDriverParams map[string]interface{}) { //nolint: thelper
func RunSignatureUploadAndVerificationTests(t *testing.T, cacheDriverParams map[string]any) { //nolint: thelper
repo := "repo"
tag := "0.0.1"
certName := "test"
-1
View File
@@ -1,5 +1,4 @@
//go:build metrics
// +build metrics
package extensions
@@ -1,5 +1,4 @@
//go:build !metrics
// +build !metrics
package extensions
+1 -2
View File
@@ -1,5 +1,4 @@
//go:build mgmt
// +build mgmt
package extensions
@@ -113,7 +112,7 @@ type Mgmt struct {
Log log.Logger
}
// mgmtHandler godoc
// HandleGetConfig godoc
// @Summary Get current server configuration
// @Description Get current server configuration
// @Router /v2/_zot/ext/mgmt [get]
@@ -1,5 +1,4 @@
//go:build !mgmt
// +build !mgmt
package extensions
-1
View File
@@ -1,5 +1,4 @@
//go:build scrub
// +build scrub
package extensions
@@ -1,5 +1,4 @@
//go:build !scrub
// +build !scrub
package extensions
-1
View File
@@ -1,5 +1,4 @@
//go:build search
// +build search
package extensions
+1 -2
View File
@@ -1,5 +1,4 @@
//go:build !search
// +build !search
package extensions
@@ -13,7 +12,7 @@ import (
"zotregistry.dev/zot/v2/pkg/storage"
)
type CveScanner interface{}
type CveScanner any
func GetCveScanner(config *config.Config, storeController storage.StoreController,
metaDB mTypes.MetaDB, log log.Logger,
+1 -2
View File
@@ -1,5 +1,4 @@
//go:build sync
// +build sync
package extensions
@@ -140,7 +139,7 @@ func removeSelfURLs(httpAddress, httpPort string, registryConfig *syncconf.Regis
}
// check dns
ips, err := net.LookupIP(url.Hostname())
ips, err := net.LookupIP(url.Hostname()) //nolint: noctx
if err != nil {
// will not remove, maybe it will get resolved later after multiple retries
log.Warn().Str("url", registryURL).Msg("failed to lookup sync registry url's hostname")
@@ -1,5 +1,4 @@
//go:build !sync
// +build !sync
package extensions
-1
View File
@@ -1,5 +1,4 @@
//go:build search && ui
// +build search,ui
package extensions
-1
View File
@@ -1,5 +1,4 @@
//go:build !search || !ui
// +build !search !ui
package extensions
-1
View File
@@ -1,5 +1,4 @@
//go:build search && ui
// +build search,ui
package extensions_test
+1 -2
View File
@@ -1,5 +1,4 @@
//go:build userprefs
// +build userprefs
package extensions
@@ -49,7 +48,7 @@ func SetupUserPreferencesRoutes(conf *config.Config, router *mux.Router,
log.Info().Msg("finished setting up user preferences routes")
}
// Repo preferences godoc
// HandleUserPrefs godoc
// @Summary Add bookmarks/stars info
// @Description Add bookmarks/stars info
// @Router /v2/_zot/ext/userprefs [put]
@@ -1,5 +1,4 @@
//go:build !userprefs
// +build !userprefs
package extensions
@@ -1,5 +1,4 @@
//go:build userprefs
// +build userprefs
package extensions_test
-1
View File
@@ -1,5 +1,4 @@
//go:build lint
// +build lint
package extensions
@@ -1,5 +1,4 @@
//go:build !lint
// +build !lint
package extensions
-1
View File
@@ -1,5 +1,4 @@
//go:build sync && metrics && mgmt && userprefs && search
// +build sync,metrics,mgmt,userprefs,search
package extensions_test
-2
View File
@@ -1,5 +1,4 @@
//go:build imagetrust
// +build imagetrust
package imagetrust
@@ -117,7 +116,6 @@ func VerifyCosignSignature(
err = verifier.VerifySignature(bytes.NewReader(signature), bytes.NewReader(payload),
options.WithContext(context.Background()))
if err == nil {
return string(pubKeyContent), true, nil
}
+1 -2
View File
@@ -1,5 +1,4 @@
//go:build imagetrust
// +build imagetrust
package imagetrust
@@ -92,7 +91,7 @@ func NewAWSImageTrustStore(region, endpoint string) (*ImageTrustStore, error) {
func GetSecretsManagerClient(region, endpoint string) (*secretsmanager.Client, error) {
customResolver := aws.EndpointResolverWithOptionsFunc( //nolint: staticcheck
func(service, region string, options ...interface{}) (aws.Endpoint, error) { //nolint: staticcheck
func(service, region string, options ...any) (aws.Endpoint, error) { //nolint: staticcheck
return aws.Endpoint{ //nolint: staticcheck
PartitionID: "aws",
URL: endpoint,
@@ -1,5 +1,4 @@
//go:build !imagetrust
// +build !imagetrust
package imagetrust
@@ -1,5 +1,4 @@
//go:build imagetrust
// +build imagetrust
package imagetrust_test
@@ -648,7 +647,7 @@ func TestLocalTrustStore(t *testing.T) {
imageTrustStore, err := imagetrust.NewLocalImageTrustStore(rootDir)
So(err, ShouldBeNil)
var dbDriverParams map[string]interface{}
var dbDriverParams map[string]any
RunUploadTests(t, *imageTrustStore)
RunVerificationTests(t, dbDriverParams)
@@ -664,7 +663,7 @@ func TestLocalTrustStoreRedis(t *testing.T) {
imageTrustStore, err := imagetrust.NewLocalImageTrustStore(rootDir)
So(err, ShouldBeNil)
dbDriverParams := map[string]interface{}{
dbDriverParams := map[string]any{
"name": "redis",
"url": "redis://" + miniRedis.Addr(),
}
@@ -1094,7 +1093,7 @@ func TestAWSTrustStore(t *testing.T) {
imageMetaTablename := "imageMetaTable" + uuid.String()
repoBlobsInfoTablename := "repoBlobsInfoTable" + uuid.String()
dynamoDBDriverParams := map[string]interface{}{
dynamoDBDriverParams := map[string]any{
"name": "dynamodb",
"endpoint": os.Getenv("DYNAMODBMOCK_ENDPOINT"),
"region": "us-east-2",
@@ -1205,7 +1204,7 @@ func RunUploadTests(t *testing.T, imageTrustStore imagetrust.ImageTrustStore) {
})
}
func RunVerificationTests(t *testing.T, dbDriverParams map[string]interface{}) { //nolint: thelper
func RunVerificationTests(t *testing.T, dbDriverParams map[string]any) { //nolint: thelper
Convey("verify signatures are trusted", func() {
defaultValue := true
rootDir := t.TempDir()
+3 -3
View File
@@ -1,5 +1,4 @@
//go:build imagetrust
// +build imagetrust
package imagetrust
@@ -211,7 +210,7 @@ func (cloud *CertificateAWSStorage) recreateSecret(secretInputParam *secretsmana
var err error
for i := 0; i < maxAttempts; i++ {
for range maxAttempts {
_, err = cloud.secretsManagerClient.CreateSecret(context.Background(), secretInputParam)
if err == nil {
return nil
@@ -286,7 +285,8 @@ func (cloud *CertificateAWSStorage) GetCertificates(
return certificates, nil
}
// Equivalent function for trustpolicy.LoadDocument() but using a specific SysFS not the one returned by ConfigFS().
// LoadTrustPolicyDocument is equivalent to trustpolicy.LoadDocument() but using a specific SysFS
// not the one returned by ConfigFS().
func (local *CertificateLocalStorage) LoadTrustPolicyDocument() (*trustpolicy.Document, error) {
notationDir, err := local.GetNotationDirPath()
if err != nil {
-1
View File
@@ -1,5 +1,4 @@
//go:build lint
// +build lint
package lint
-1
View File
@@ -1,5 +1,4 @@
//go:build !lint
// +build !lint
package lint
-1
View File
@@ -1,5 +1,4 @@
//go:build lint
// +build lint
package lint_test
+3 -3
View File
@@ -9,10 +9,10 @@ import (
var re = regexp.MustCompile(`\/v2\/(.*?)\/(blobs|tags|manifests)\/(.*)$`)
type MetricServer interface {
SendMetric(interface{})
SendMetric(any)
// works like SendMetric, but adds the metric regardless of the value of 'enabled' field for MetricServer
ForceSendMetric(interface{})
ReceiveMetrics() interface{}
ForceSendMetric(any)
ReceiveMetrics() any
IsEnabled() bool
// Stop gracefully shuts down the metrics server
Stop()
+4 -5
View File
@@ -1,5 +1,4 @@
//go:build metrics
// +build metrics
package monitoring
@@ -157,8 +156,8 @@ func NewMetricsServer(enabled bool, log log.Logger) MetricServer {
}
}
// implementing the MetricServer interface.
func (ms *metricServer) SendMetric(mfunc interface{}) {
// SendMetric implements the MetricServer interface.
func (ms *metricServer) SendMetric(mfunc any) {
if ms.enabled {
mfn, ok := mfunc.(func())
if !ok {
@@ -172,7 +171,7 @@ func (ms *metricServer) SendMetric(mfunc interface{}) {
}
}
func (ms *metricServer) ForceSendMetric(mfunc interface{}) {
func (ms *metricServer) ForceSendMetric(mfunc any) {
mfn, ok := mfunc.(func())
if !ok {
ms.log.Error().Err(errors.ErrInvalidMetric).
@@ -184,7 +183,7 @@ func (ms *metricServer) ForceSendMetric(mfunc interface{}) {
mfn()
}
func (ms *metricServer) ReceiveMetrics() interface{} {
func (ms *metricServer) ReceiveMetrics() any {
return nil
}
+7 -8
View File
@@ -1,5 +1,4 @@
//go:build !metrics
// +build !metrics
//nolint:varnamelen,forcetypeassert
package monitoring
@@ -43,7 +42,7 @@ const (
type metricServer struct {
enabled bool
lastCheck time.Time
reqChan chan interface{}
reqChan chan any
cache *MetricsInfo
cacheChan chan MetricsCopy
bucketsF2S map[float64]string // float64 to string conversion of buckets label
@@ -110,8 +109,8 @@ func GetStorageLatencyBuckets() []float64 {
return []float64{.001, .01, 0.1, 1, 5, 10, 15, 30, 60, math.MaxFloat64}
}
// implements the MetricServer interface.
func (ms *metricServer) SendMetric(metric interface{}) {
// SendMetric implements the MetricServer interface.
func (ms *metricServer) SendMetric(metric any) {
ms.lock.RLock()
if ms.enabled {
ms.lock.RUnlock()
@@ -121,11 +120,11 @@ func (ms *metricServer) SendMetric(metric interface{}) {
}
}
func (ms *metricServer) ForceSendMetric(metric interface{}) {
func (ms *metricServer) ForceSendMetric(metric any) {
ms.reqChan <- metric
}
func (ms *metricServer) ReceiveMetrics() interface{} {
func (ms *metricServer) ReceiveMetrics() any {
ms.lock.Lock()
if !ms.enabled {
ms.enabled = true
@@ -250,7 +249,7 @@ func NewMetricsServer(enabled bool, log log.Logger) MetricServer {
ms := &metricServer{
enabled: enabled,
reqChan: make(chan interface{}),
reqChan: make(chan any),
cacheChan: make(chan MetricsCopy),
cache: mi,
bucketsF2S: bucketsFloat2String,
@@ -264,7 +263,7 @@ func NewMetricsServer(enabled bool, log log.Logger) MetricServer {
return ms
}
// contains a map with key=CounterName and value=CounterLabels.
// GetCounters contains a map with key=CounterName and value=CounterLabels.
func GetCounters() map[string][]string {
return map[string][]string{
httpConnRequests: {"method", "code"},
+3 -4
View File
@@ -1,5 +1,4 @@
//go:build !metrics
// +build !metrics
package monitoring
@@ -47,8 +46,8 @@ func newHTTPMetricsClient() *http.Client {
}
}
// Creates a MetricsClient that can be used to retrieve in memory metrics
// The new MetricsClient retrieved must be cached and reused by the Node Exporter
// NewMetricsClient creates a MetricsClient that can be used to retrieve in memory metrics.
// The new MetricsClient retrieved must be cached and reused by the Node Exporter
// in order to prevent concurrent memory leaks.
func NewMetricsClient(config *MetricsConfig, logger log.Logger) *MetricsClient {
if config.HTTPClient == nil {
@@ -67,7 +66,7 @@ func (mc *MetricsClient) GetMetrics() (*MetricsInfo, error) {
return metrics, nil
}
func (mc *MetricsClient) makeGETRequest(url string, resultsPtr interface{}) (http.Header, error) {
func (mc *MetricsClient) makeGETRequest(url string, resultsPtr any) (http.Header, error) {
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, url, nil)
if err != nil {
return nil, fmt.Errorf("metric scraping failed: %w", err)
@@ -1,5 +1,4 @@
//go:build metrics
// +build metrics
package monitoring_test
+1 -2
View File
@@ -1,5 +1,4 @@
//go:build scrub
// +build scrub
package scrub
@@ -13,7 +12,7 @@ import (
storageTypes "zotregistry.dev/zot/v2/pkg/storage/types"
)
// Scrub Extension for repo...
// RunScrubRepo runs the scrub extension for a repository.
func RunScrubRepo(ctx context.Context, imgStore storageTypes.ImageStore, repo string, log log.Logger) error {
execMsg := "executing scrub to check manifest/blob integrity for " + path.Join(imgStore.RootDir(), repo)
log.Info().Msg(execMsg)
-1
View File
@@ -1,5 +1,4 @@
//go:build scrub
// +build scrub
package scrub_test
+4 -6
View File
@@ -7,6 +7,7 @@ import (
)
const (
// AnnotationLabels is used for OCI annotation/label with backwards compatibility.
// See https://github.com/opencontainers/image-spec/blob/main/annotations.md#back-compatibility-with-label-schema
AnnotationLabels = "org.label-schema.labels"
LabelAnnotationCreated = "org.label-schema.build-date"
@@ -30,12 +31,9 @@ type ImageAnnotations struct {
Authors string
}
/*
OCI annotation/label with backwards compatibility
arg can be either labels or annotations
https://github.com/opencontainers/image-spec/blob/main/annotations.md.
*/
// GetAnnotationValue handles OCI annotation/label with backwards compatibility.
// Arg can be either labels or annotations.
// https://github.com/opencontainers/image-spec/blob/main/annotations.md.
func GetAnnotationValue(annotations map[string]string, annotationKey, labelKey string) string {
value, ok := annotations[annotationKey]
if !ok || value == "" {
-8
View File
@@ -45,8 +45,6 @@ func getReferrers(referrersInfo []mTypes.ReferrerInfo) []*gql_generated.Referrer
referrers := make([]*gql_generated.Referrer, 0, len(referrersInfo))
for _, referrerInfo := range referrersInfo {
referrerInfo := referrerInfo
referrers = append(referrers, &gql_generated.Referrer{
MediaType: &referrerInfo.MediaType,
ArtifactType: &referrerInfo.ArtifactType,
@@ -63,9 +61,6 @@ func getAnnotationsFromMap(annotationsMap map[string]string) []*gql_generated.An
annotations := make([]*gql_generated.Annotation, 0, len(annotationsMap))
for key, value := range annotationsMap {
key := key
value := value
annotations = append(annotations, &gql_generated.Annotation{
Key: &key,
Value: &value,
@@ -199,9 +194,6 @@ func StringMap2Annotations(strMap map[string]string) []*gql_generated.Annotation
annotations := make([]*gql_generated.Annotation, 0, len(strMap))
for key, value := range strMap {
key := key
value := value
annotations = append(annotations, &gql_generated.Annotation{
Key: &key,
Value: &value,
+41 -51
View File
@@ -1,19 +1,30 @@
package convert
import (
"slices"
zcommon "zotregistry.dev/zot/v2/pkg/common"
gql_gen "zotregistry.dev/zot/v2/pkg/extensions/search/gql_generated"
mTypes "zotregistry.dev/zot/v2/pkg/meta/types"
)
func ImgSumAcceptedByFilter(imageSummary *gql_gen.ImageSummary, filter mTypes.Filter) bool {
osFilters := strSliceFromRef(filter.Os)
archFilters := strSliceFromRef(filter.Arch)
// Early return if image is not signed and signing is required
if filter.HasToBeSigned != nil && *filter.HasToBeSigned && !*imageSummary.IsSigned {
return false
}
platforms := getImagePlatforms(imageSummary)
platformMatchFound := len(platforms) == 0 && filter.Os == nil && filter.Arch == nil
// Early return if no platforms and no filters means platform match passes
if len(platforms) == 0 && filter.Os == nil && filter.Arch == nil {
return true
}
for _, platform := range platforms {
osFilters := strSliceFromRef(filter.Os)
archFilters := strSliceFromRef(filter.Arch)
return slices.ContainsFunc(platforms, func(platform *gql_gen.Platform) bool {
osCheck := true
if len(osFilters) > 0 {
@@ -26,26 +37,12 @@ func ImgSumAcceptedByFilter(imageSummary *gql_gen.ImageSummary, filter mTypes.Fi
archCheck = platform.Arch != nil && zcommon.ContainsStringIgnoreCase(archFilters, *platform.Arch)
}
if osCheck && archCheck {
platformMatchFound = true
break
}
}
if !platformMatchFound {
return false
}
if filter.HasToBeSigned != nil && *filter.HasToBeSigned && !*imageSummary.IsSigned {
return false
}
return true
return osCheck && archCheck
})
}
func getImagePlatforms(imageSummary *gql_gen.ImageSummary) []*gql_gen.Platform {
platforms := []*gql_gen.Platform{}
platforms := make([]*gql_gen.Platform, 0, len(imageSummary.Manifests))
for _, manifest := range imageSummary.Manifests {
if manifest.Platform != nil {
@@ -57,35 +54,6 @@ func getImagePlatforms(imageSummary *gql_gen.ImageSummary) []*gql_gen.Platform {
}
func RepoSumAcceptedByFilter(repoSummary *gql_gen.RepoSummary, filter mTypes.Filter) bool {
osFilters := strSliceFromRef(filter.Os)
archFilters := strSliceFromRef(filter.Arch)
platformMatchFound := len(repoSummary.Platforms) == 0 && filter.Os == nil && filter.Arch == nil
for _, platform := range repoSummary.Platforms {
osCheck := true
if len(osFilters) > 0 {
osCheck = platform.Os != nil && zcommon.ContainsStringIgnoreCase(osFilters, *platform.Os)
}
archCheck := true
if len(archFilters) > 0 {
archCheck = platform.Arch != nil && zcommon.ContainsStringIgnoreCase(archFilters, *platform.Arch)
}
if osCheck && archCheck {
platformMatchFound = true
break
}
}
if !platformMatchFound {
return false
}
if filter.HasToBeSigned != nil && *filter.HasToBeSigned && !*repoSummary.NewestImage.IsSigned {
return false
}
@@ -98,7 +66,29 @@ func RepoSumAcceptedByFilter(repoSummary *gql_gen.RepoSummary, filter mTypes.Fil
return false
}
return true
// Early return if no platforms and no filters means platform match passes
if len(repoSummary.Platforms) == 0 && filter.Os == nil && filter.Arch == nil {
return true
}
osFilters := strSliceFromRef(filter.Os)
archFilters := strSliceFromRef(filter.Arch)
return slices.ContainsFunc(repoSummary.Platforms, func(platform *gql_gen.Platform) bool {
osCheck := true
if len(osFilters) > 0 {
osCheck = platform.Os != nil && zcommon.ContainsStringIgnoreCase(osFilters, *platform.Os)
}
archCheck := true
if len(archFilters) > 0 {
archCheck = platform.Arch != nil && zcommon.ContainsStringIgnoreCase(archFilters, *platform.Arch)
}
return osCheck && archCheck
})
}
func strSliceFromRef(slice []*string) []string {
-1
View File
@@ -436,7 +436,6 @@ func (cveinfo BaseCveInfo) GetCVEDiffListForImages(ctx context.Context, minuend,
subtrahendCVEMap := map[string]cvemodel.CVE{}
for _, cve := range subtrahendCVEList {
cve := cve
subtrahendCVEMap[cve.ID] = cve
}
+2 -4
View File
@@ -1,5 +1,4 @@
//go:build search
// +build search
//nolint:lll,gosimple
package cveinfo_test
@@ -12,6 +11,7 @@ import (
"net/url"
"os"
"path"
"slices"
"strings"
"testing"
"time"
@@ -969,7 +969,7 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
return result, nil
}
if repo == repo1 && zcommon.Contains([]string{image12Digest, image21Digest}, ref) {
if repo == repo1 && slices.Contains([]string{image12Digest, image21Digest}, ref) {
result := map[string]cvemodel.CVE{
"CVE1": {
ID: "CVE1",
@@ -1158,10 +1158,8 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
for _, imageLayer := range manifestData.Manifests[0].Manifest.Layers {
switch imageLayer.MediaType {
case ispec.MediaTypeImageLayerGzip, ispec.MediaTypeImageLayer, string(regTypes.DockerLayer):
return true, nil
default:
return false, zerr.ErrScanNotSupported
}
}
+4 -5
View File
@@ -1,5 +1,4 @@
//go:build search
// +build search
package cveinfo_test
@@ -77,7 +76,7 @@ func TestCVEPagination(t *testing.T) {
cveMap := map[string]cvemodel.CVE{}
if image == "repo1:0.1.0" {
for i := 0; i < 5; i++ {
for i := range 5 {
cveMap[fmt.Sprintf("CVE%d", i)] = cvemodel.CVE{
ID: fmt.Sprintf("CVE%d", i),
Severity: intToSeverity[i%5],
@@ -88,7 +87,7 @@ func TestCVEPagination(t *testing.T) {
}
if image == "repo1:1.0.0" {
for i := 0; i < 30; i++ {
for i := range 30 {
cveMap[fmt.Sprintf("CVE%d", i)] = cvemodel.CVE{
ID: fmt.Sprintf("CVE%d", i),
Severity: intToSeverity[i%5],
@@ -183,7 +182,7 @@ func TestCVEPagination(t *testing.T) {
Convey("no limit or offset", func() {
cveIds := []string{}
for i := 0; i < 30; i++ {
for i := range 30 {
cveIds = append(cveIds, fmt.Sprintf("CVE%d", i))
}
@@ -266,7 +265,7 @@ func TestCVEPagination(t *testing.T) {
Convey("limit < len(cves)", func() {
cveIds := []string{}
for i := 0; i < 30; i++ {
for i := range 30 {
cveIds = append(cveIds, fmt.Sprintf("CVE%d", i))
}
+2 -4
View File
@@ -1,5 +1,4 @@
//go:build search
// +build search
package cveinfo_test
@@ -8,6 +7,7 @@ import (
"errors"
"io"
"os"
"slices"
"testing"
"time"
@@ -249,7 +249,7 @@ func TestScanGeneratorWithMockedData(t *testing.T) { //nolint: gocyclo
return result, nil
}
if repo == repo1 && zcommon.Contains([]string{image12Digest, image21Digest}, ref) {
if repo == repo1 && slices.Contains([]string{image12Digest, image21Digest}, ref) {
result := map[string]cvemodel.CVE{
"CVE1": {
ID: "CVE1",
@@ -392,10 +392,8 @@ func TestScanGeneratorWithMockedData(t *testing.T) { //nolint: gocyclo
for _, imageLayer := range manifestData.Manifests[0].Manifest.Layers {
switch imageLayer.MediaType {
case ispec.MediaTypeImageLayerGzip, ispec.MediaTypeImageLayer, string(regTypes.DockerLayer):
return true, nil
default:
return false, zerr.ErrScanNotSupported
}
}
+2 -3
View File
@@ -3,6 +3,7 @@ package trivy
import (
"context"
"fmt"
"maps"
"os"
"path"
"strconv"
@@ -537,9 +538,7 @@ func (scanner Scanner) scanIndex(ctx context.Context, repo, digest string) (map[
return nil, err
}
for vulnerabilityID, CVE := range manifestCveIDMap {
indexCveIDMap[vulnerabilityID] = CVE
}
maps.Copy(indexCveIDMap, manifestCveIDMap)
}
}
@@ -1,5 +1,4 @@
//go:build search
// +build search
package trivy
-1
View File
@@ -1,5 +1,4 @@
//go:build search
// +build search
package cveinfo_test
-1
View File
@@ -1,5 +1,4 @@
//go:build search
// +build search
package search_test
@@ -136,7 +136,7 @@ func ImgSortByRelevance(pageBuffer []*gql_gen.ImageSummary) func(i, j int) bool
}
}
// SortByUpdateTime sorting descending by time.
// ImgSortByUpdateTime sorts descending by time.
func ImgSortByUpdateTime(pageBuffer []*gql_gen.ImageSummary) func(i, j int) bool {
repos2LastUpdated := map[string]time.Time{}
@@ -156,7 +156,7 @@ func ImgSortByUpdateTime(pageBuffer []*gql_gen.ImageSummary) func(i, j int) bool
}
}
// SortByDownloads returns a comparison function for descendant sorting by downloads.
// ImgSortByDownloads returns a comparison function for descendant sorting by downloads.
func ImgSortByDownloads(pageBuffer []*gql_gen.ImageSummary) func(i, j int) bool {
return func(i, j int) bool {
return *pageBuffer[i].DownloadCount > *pageBuffer[j].DownloadCount
@@ -111,14 +111,14 @@ func RepoSortByRelevance(pageBuffer []*gql_gen.RepoSummary) func(i, j int) bool
}
}
// SortByUpdateTime sorting descending by time.
// RepoSortByUpdateTime sorts descending by time.
func RepoSortByUpdateTime(pageBuffer []*gql_gen.RepoSummary) func(i, j int) bool {
return func(i, j int) bool {
return pageBuffer[i].LastUpdated.After(*pageBuffer[j].LastUpdated)
}
}
// SortByDownloads returns a comparison function for descendant sorting by downloads.
// RepoSortByDownloads returns a comparison function for descendant sorting by downloads.
func RepoSortByDownloads(pageBuffer []*gql_gen.RepoSummary) func(i, j int) bool {
return func(i, j int) bool {
return *pageBuffer[i].DownloadCount > *pageBuffer[j].DownloadCount
+4 -9
View File
@@ -8,6 +8,7 @@ import (
"context"
"errors"
"fmt"
"slices"
"sort"
"strings"
@@ -236,8 +237,6 @@ func getCVEListForImage(
pkgList := make([]*gql_generated.PackageInfo, 0)
for _, pkg := range cveDetail.PackageList {
pkg := pkg
pkgList = append(pkgList,
&gql_generated.PackageInfo{
Name: &pkg.Name,
@@ -386,8 +385,6 @@ func getCVEDiffListForImages(
pkgList := make([]*gql_generated.PackageInfo, 0)
for _, pkg := range cveDetail.PackageList {
pkg := pkg
pkgList = append(pkgList,
&gql_generated.PackageInfo{
Name: &pkg.Name,
@@ -805,7 +802,7 @@ func getBookmarkedRepos(
}
filterByName := func(repo string) bool {
return zcommon.Contains(bookmarkedRepos, repo)
return slices.Contains(bookmarkedRepos, repo)
}
return getFilteredPaginatedRepos(ctx, cveInfo, filterByName, log, requestedPage, metaDB)
@@ -824,7 +821,7 @@ func getStarredRepos(
}
filterFn := func(repo string) bool {
return zcommon.Contains(starredRepos, repo)
return slices.Contains(starredRepos, repo)
}
return getFilteredPaginatedRepos(ctx, cveInfo, filterFn, log, requestedPage, metaDB)
@@ -1445,7 +1442,7 @@ func expandedRepoInfo(ctx context.Context, repo string, metaDB mTypes.MetaDB, cv
digest := repoMeta.Tags[i].Digest
if !zcommon.Contains(tagsDigests, digest) {
if !slices.Contains(tagsDigests, digest) {
tagsDigests = append(tagsDigests, digest)
}
}
@@ -1582,8 +1579,6 @@ func getReferrers(metaDB mTypes.MetaDB, repo string, referredDigest string, arti
results := make([]*gql_generated.Referrer, 0, len(referrers))
for _, referrer := range referrers {
referrer := referrer
results = append(results, &gql_generated.Referrer{
MediaType: &referrer.MediaType,
ArtifactType: &referrer.ArtifactType,
+6 -13
View File
@@ -1,5 +1,4 @@
//go:build search
// +build search
package search_test
@@ -340,10 +339,8 @@ func getMockCveScanner(metaDB mTypes.MetaDB) cveinfo.Scanner {
for _, imageLayer := range manifestData.Manifests[0].Manifest.Layers {
switch imageLayer.MediaType {
case ispec.MediaTypeImageLayerGzip, ispec.MediaTypeImageLayer, string(regTypes.DockerLayer):
return true, nil
default:
return false, zerr.ErrScanNotSupported
}
}
@@ -3496,8 +3493,6 @@ func TestGlobalSearch(t *testing.T) { //nolint: gocyclo
So(newestImageMap["repo2"].LastUpdated, ShouldEqual, time.Date(2009, 2, 1, 12, 0, 0, 0, time.UTC))
for repoName, repoSummary := range actualRepoMap {
repoSummary := repoSummary
// Check if data in NewestImage is consistent with the data in RepoSummary
So(repoName, ShouldEqual, repoSummary.NewestImage.RepoName)
So(repoSummary.Name, ShouldEqual, repoSummary.NewestImage.RepoName)
@@ -3841,8 +3836,6 @@ func TestGlobalSearch(t *testing.T) { //nolint: gocyclo
So(newestImageMap["repo2"].LastUpdated, ShouldEqual, time.Date(2009, 2, 1, 12, 0, 0, 0, time.UTC))
for repoName, repoSummary := range actualRepoMap {
repoSummary := repoSummary
// Check if data in NewestImage is consistent with the data in RepoSummary
So(repoName, ShouldEqual, repoSummary.NewestImage.RepoName)
So(repoSummary.Name, ShouldEqual, repoSummary.NewestImage.RepoName)
@@ -4174,7 +4167,7 @@ func TestGlobalSearch(t *testing.T) { //nolint: gocyclo
Convey("test with redis", func() {
miniRedis := miniredis.RunT(t)
conf.Storage.CacheDriver = map[string]interface{}{
conf.Storage.CacheDriver = map[string]any{
"name": "redis",
"url": "redis://" + miniRedis.Addr(),
}
@@ -4337,7 +4330,7 @@ func TestGlobalSearch(t *testing.T) { //nolint: gocyclo
Convey("test with redis", func() {
miniRedis := miniredis.RunT(t)
conf.Storage.CacheDriver = map[string]interface{}{
conf.Storage.CacheDriver = map[string]any{
"name": "redis",
"url": "redis://" + miniRedis.Addr(),
}
@@ -4900,7 +4893,7 @@ func TestGlobalSearchPagination(t *testing.T) {
ctlrManager.StartAndWait(port)
defer ctlrManager.StopServer()
for i := 0; i < 3; i++ {
for i := range 3 {
image := CreateImageWith().RandomLayers(1, 10).DefaultConfig().Build()
err := UploadImage(image, baseURL, fmt.Sprintf("repo%d", i), "0.0.1")
@@ -7432,7 +7425,7 @@ func TestReadUploadDeleteDynamoDB(t *testing.T) {
imageMetaTablename := "ImageMeta" + uuid.String()
repoBlobsTablename := "RepoBlobs" + uuid.String()
cacheDriverParams := map[string]interface{}{
cacheDriverParams := map[string]any{
"name": "dynamodb",
"endpoint": os.Getenv("DYNAMODBMOCK_ENDPOINT"),
"region": "us-east-2",
@@ -7557,7 +7550,7 @@ func RunReadUploadDeleteTests(t *testing.T, baseURL string) {
})
})
Convey("Delete the image pushed multiple times", func() {
for i := 0; i < 3; i++ {
for range 3 {
status, err := DeleteImage(repo1, tag1, baseURL)
So(status, ShouldBeIn, []int{http.StatusAccepted, http.StatusNotFound, http.StatusBadRequest})
So(err, ShouldBeNil)
@@ -7567,7 +7560,7 @@ func RunReadUploadDeleteTests(t *testing.T, baseURL string) {
}
})
Convey("Upload same image multiple times", func() {
for i := 0; i < 3; i++ {
for range 3 {
err := UploadImage(image, baseURL, repo1, tag1)
So(err, ShouldBeNil)
}
-1
View File
@@ -1,5 +1,4 @@
//go:build sync
// +build sync
package sync
-1
View File
@@ -1,5 +1,4 @@
//go:build sync
// +build sync
package sync_test //nolint: testpackage
+4 -4
View File
@@ -1,5 +1,4 @@
//go:build sync
// +build sync
package sync
@@ -10,6 +9,7 @@ import (
"fmt"
"os"
"path"
"slices"
"strings"
"github.com/distribution/distribution/v3/registry/storage/driver"
@@ -53,7 +53,7 @@ func NewDestinationRegistry(
}
}
// Check if image is already synced.
// CanSkipImage checks if image is already synced.
func (registry *DestinationRegistry) CanSkipImage(repo, tag string, digest godigest.Digest) (bool, error) {
// check image already synced
imageStore := registry.storeController.GetImageStore(repo)
@@ -86,7 +86,7 @@ func (registry *DestinationRegistry) GetImageReference(repo, reference string) (
return registry.tempStorage.GetImageReference(repo, reference)
}
// finalize a syncing image.
// CommitAll finalizes a syncing image.
func (registry *DestinationRegistry) CommitAll(repo string, imageReference ref.Ref) error {
tempImageStore := getImageStoreFromImageReference(repo, imageReference, registry.log)
@@ -145,7 +145,7 @@ func (registry *DestinationRegistry) copyManifest(repo string, desc ispec.Descri
var err error
// seen
if common.Contains(*seen, desc.Digest) {
if slices.Contains(*seen, desc.Digest) {
return nil
}
+3 -4
View File
@@ -1,5 +1,4 @@
//go:build sync
// +build sync
package sync
@@ -73,7 +72,7 @@ func extractAccountAndRegion(url string) (string, string, error) {
return accountID, region, nil
}
// getMockECRCredentials provides mock credentials for testing purposes.
// GetMockECRCredentials provides mock credentials for testing purposes.
func GetMockECRCredentials(remoteAddress string) (ecrCredential, error) {
// Extract account ID and region from the URL.
accountID, region, err := extractAccountAndRegion(remoteAddress)
@@ -91,7 +90,7 @@ func GetMockECRCredentials(remoteAddress string) (ecrCredential, error) {
}, nil
}
// getECRCredentials retrieves actual ECR credentials using AWS SDK.
// GetECRCredentials retrieves actual ECR credentials using AWS SDK.
func GetECRCredentials(remoteAddress string) (ecrCredential, error) {
// Extract account ID and region from the URL.
accountID, region, err := extractAccountAndRegion(remoteAddress)
@@ -137,7 +136,7 @@ func GetECRCredentials(remoteAddress string) (ecrCredential, error) {
return ecrCredential{username: username, password: password, expiry: expiry, account: accountID, region: region}, nil
}
// GetECRCredentials retrieves the ECR credentials (username and password) from AWS ECR.
// GetCredentials retrieves the ECR credentials (username and password) from AWS ECR.
func (credHelper *ecrCredentialsHelper) GetCredentials(urls []string) (syncconf.CredentialsFile, error) {
ecrCredentials := make(syncconf.CredentialsFile)
-1
View File
@@ -1,5 +1,4 @@
//go:build sync
// +build sync
package sync
+2 -3
View File
@@ -1,5 +1,4 @@
//go:build sync
// +build sync
package sync
@@ -23,9 +22,9 @@ type request struct {
}
/*
a request can be an image/signature/sbom
BaseOnDemand tracks requests that can be an image/signature/sbom.
keep track of all parallel requests, if two requests of same image/signature/sbom comes at the same time,
It keeps track of all parallel requests, if two requests of same image/signature/sbom comes at the same time,
process just the first one, also keep track of all background retrying routines.
*/
type BaseOnDemand struct {
@@ -1,5 +1,4 @@
//go:build !sync
// +build !sync
package sync
-1
View File
@@ -1,5 +1,4 @@
//go:build sync
// +build sync
package sync
+1 -2
View File
@@ -1,5 +1,4 @@
//go:build sync
// +build sync
package sync
@@ -195,7 +194,7 @@ func (registry *RemoteRegistry) GetDigest(ctx context.Context, repo, tag string,
return man.GetDescriptor().Digest, err
}
// returns OCI remote digest, original remote digest (unconverted), if it was converted.
// GetOCIDigest returns OCI remote digest, original remote digest (unconverted), if it was converted.
func (registry *RemoteRegistry) GetOCIDigest(ctx context.Context, repo, tag string,
) (godigest.Digest, godigest.Digest, bool, error) {
var isConverted bool
+1 -2
View File
@@ -1,5 +1,4 @@
//go:build sync
// +build sync
package sync
@@ -27,7 +26,7 @@ func newTagsCache(expireAfter time.Duration) *tagsCache {
}
}
// returns true if still valid (not expired) and tags list.
// Get returns true if still valid (not expired) and tags list.
func (c *tagsCache) Get(repo string) (bool, []string) {
c.mu.Lock()
defer c.mu.Unlock()
+4 -4
View File
@@ -1,5 +1,4 @@
//go:build sync
// +build sync
package sync
@@ -9,6 +8,7 @@ import (
"fmt"
"net/http"
"net/url"
"slices"
"strconv"
"strings"
"sync"
@@ -397,7 +397,7 @@ func (service *BaseService) SyncReferrers(ctx context.Context, repo string,
return nil
}
// sync repo periodically.
// SyncRepo syncs repo periodically.
func (service *BaseService) SyncRepo(ctx context.Context, repo string) error {
service.log.Info().Str("repo", repo).Str("registry", service.remote.GetHostName()).
Msg("sync: syncing repo")
@@ -590,7 +590,7 @@ func (service *BaseService) syncImage(ctx context.Context, localRepo, remoteRepo
}
// verify repo contains a cosign signature for this manifest
hasCosignSignature := common.Contains(repoTags, fmt.Sprintf("%s-%s.sig", remoteDigest.Algorithm(),
hasCosignSignature := slices.Contains(repoTags, fmt.Sprintf("%s-%s.sig", remoteDigest.Algorithm(),
remoteDigest.Encoded()))
isSigned := hasSignatureReferrers(referrers) || hasCosignSignature
@@ -721,7 +721,7 @@ func (service *BaseService) syncReferrers(ctx context.Context, tags []string, lo
}
// is seen
if common.Contains(seen, remoteDigest.String()) {
if slices.Contains(seen, remoteDigest.String()) {
return nil
}
+4 -5
View File
@@ -1,5 +1,4 @@
//go:build sync
// +build sync
package sync
@@ -20,7 +19,7 @@ import (
// below types are used by regclient to copy images
// ref.Ref- describes a registry/repo:tag
// Sync general functionalities, one service per registry config.
// Service provides sync general functionalities, one service per registry config.
type Service interface {
// Get next repo from remote /v2/_catalog, will return empty string when there is no repo left.
GetNextRepo(lastRepo string) (string, error) // used by task scheduler
@@ -39,7 +38,7 @@ type Service interface {
GetSyncTimeout() time.Duration
}
// Local and remote registries must implement this interface.
// Registry interface must be implemented by local and remote registries.
type Registry interface {
// Get temporary ImageReference, is used by functions in regclient package
GetImageReference(repo string, tag string) (ref.Ref, error)
@@ -62,7 +61,7 @@ type CredentialHelper interface {
}
/*
Temporary oci layout, sync first pulls an image to this oci layout (using oci:// transport)
OciLayoutStorage is a temporary oci layout, sync first pulls an image to this oci layout (using oci:// transport)
then moves them into ImageStore.
*/
type OciLayoutStorage interface {
@@ -85,7 +84,7 @@ type Remote interface {
GetDigest(ctx context.Context, repo, tag string) (godigest.Digest, error)
}
// Local registry.
// Destination is a local registry.
type Destination interface {
Registry
// Check if descriptors are already synced
@@ -1,5 +1,4 @@
//go:build !sync
// +build !sync
package sync_test
+9 -10
View File
@@ -1,5 +1,4 @@
//go:build sync
// +build sync
package sync
@@ -225,7 +224,7 @@ func TestService(t *testing.T) {
// Step 1: Verify empty requestStore initially
initialImageCount := 0
onDemand.requestStore.Range(func(key, value interface{}) bool {
onDemand.requestStore.Range(func(key, value any) bool {
initialImageCount++
return true
})
@@ -242,7 +241,7 @@ func TestService(t *testing.T) {
// Step 3: Verify we now have 1 request
preImageCount := 0
onDemand.requestStore.Range(func(key, value interface{}) bool {
onDemand.requestStore.Range(func(key, value any) bool {
preImageCount++
return true
})
@@ -254,7 +253,7 @@ func TestService(t *testing.T) {
// Step 5: Verify CONTINUE PATH EXECUTED - no new requests created
postImageCount := 0
onDemand.requestStore.Range(func(key, value interface{}) bool {
onDemand.requestStore.Range(func(key, value any) bool {
postImageCount++
return true
})
@@ -267,7 +266,7 @@ func TestService(t *testing.T) {
// Step 7: Verify current state before referrer test - we should have 1 request
initialReferrerCount := 0
onDemand.requestStore.Range(func(key, value interface{}) bool {
onDemand.requestStore.Range(func(key, value any) bool {
initialReferrerCount++
return true
})
@@ -284,7 +283,7 @@ func TestService(t *testing.T) {
// Step 9: Verify we now have 2 requests (image + referrer)
preReferrerCount := 0
onDemand.requestStore.Range(func(key, value interface{}) bool {
onDemand.requestStore.Range(func(key, value any) bool {
preReferrerCount++
return true
})
@@ -296,7 +295,7 @@ func TestService(t *testing.T) {
// Step 11: Verify CONTINUE PATH EXECUTED - no new referrer requests created
postReferrerCount := 0
onDemand.requestStore.Range(func(key, value interface{}) bool {
onDemand.requestStore.Range(func(key, value any) bool {
postReferrerCount++
return true
})
@@ -309,7 +308,7 @@ func TestService(t *testing.T) {
// Step 13: Final verification - exactly 2 requests total (both pre-populated, none deleted)
finalCount := 0
onDemand.requestStore.Range(func(key, value interface{}) bool {
onDemand.requestStore.Range(func(key, value any) bool {
finalCount++
return true
})
@@ -434,7 +433,7 @@ func TestService(t *testing.T) {
// Verify initial requestStore is empty
initialCount := 0
onDemand.requestStore.Range(func(key, value interface{}) bool {
onDemand.requestStore.Range(func(key, value any) bool {
initialCount++
return true
})
@@ -475,7 +474,7 @@ func TestService(t *testing.T) {
// Verify initial requestStore is empty
initialCount := 0
onDemand.requestStore.Range(func(key, value interface{}) bool {
onDemand.requestStore.Range(func(key, value any) bool {
initialCount++
return true
})
+3 -4
View File
@@ -1,5 +1,4 @@
//go:build sync
// +build sync
package sync_test
@@ -5638,7 +5637,7 @@ func TestOnDemandMultipleImage(t *testing.T) {
defer dcm.StopServer()
callsNo := 5
for i := 0; i < callsNo; i++ {
for range callsNo {
_, _ = destClient.R().Get(destBaseURL + "/v2/" + testImage + "/manifests/" + testImageTag)
}
@@ -5801,7 +5800,7 @@ func TestOnDemandPullsReferrersOnce(t *testing.T) {
targetURL := destBaseURL + "/v2/" + testImage + "/referrers/" + digest
for i := 0; i < numConcurrentRequests; i++ {
for i := range numConcurrentRequests {
go func(routineID int) {
defer wg.Done()
t.Logf("Goroutine %d: Sending request to %s", routineID, targetURL)
@@ -5928,7 +5927,7 @@ func TestOnDemandPullsOnce(t *testing.T) {
targetURL := destBaseURL + "/v2/" + testImage + "/manifests/" + testImageTag
for i := 0; i < numConcurrentRequests; i++ {
for i := range numConcurrentRequests {
go func(routineID int) {
defer wg.Done()
t.Logf("Goroutine %d: Sending request to %s", routineID, targetURL)
-1
View File
@@ -1,5 +1,4 @@
//go:build sync
// +build sync
package sync