(cherry-pick) Fix issue related to redhat registry proxy cache (#17825)

Fix issue related to redhat registry proxy cache

  fixes #16495

Signed-off-by: stonezdj <daojunz@vmware.com>

Signed-off-by: stonezdj <daojunz@vmware.com>
This commit is contained in:
stonezdj(Daojun Zhang) 2022-11-23 14:48:01 +08:00 committed by GitHub
parent 2b36a6ba64
commit 9e488f506e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 25 deletions

View File

@ -23,6 +23,8 @@ import (
"time"
"github.com/docker/distribution"
"github.com/opencontainers/go-digest"
"github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/controller/blob"
"github.com/goharbor/harbor/src/controller/event/operator"
@ -33,7 +35,6 @@ import (
"github.com/goharbor/harbor/src/lib/log"
"github.com/goharbor/harbor/src/lib/orm"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
"github.com/opencontainers/go-digest"
)
const (
@ -99,7 +100,7 @@ func (c *controller) EnsureTag(ctx context.Context, art lib.ArtifactInfo, tagNam
// search the digest in cache and query with trimmed digest
var trimmedDigest string
err := c.cache.Fetch(TrimmedManifestlist+art.Digest, &trimmedDigest)
if err == cache.ErrNotFound {
if errors.Is(err, cache.ErrNotFound) {
// skip to update digest, continue
} else if err != nil {
// for other error, return
@ -169,32 +170,31 @@ func (c *controller) UseLocalManifest(ctx context.Context, art lib.ArtifactInfo,
return a != nil && string(desc.Digest) == a.Digest, nil, nil // digest matches
}
err = c.cache.Fetch(manifestListKey(art.Repository, string(desc.Digest)), &content)
err = c.cache.Fetch(manifestListKey(art.Repository, art), &content)
if err != nil {
if err == cache.ErrNotFound {
log.Debugf("Digest is not found in manifest list cache, key=cache:%v", manifestListKey(art.Repository, string(desc.Digest)))
if errors.Is(err, cache.ErrNotFound) {
log.Debugf("Digest is not found in manifest list cache, key=cache:%v", manifestListKey(art.Repository, art))
} else {
log.Errorf("Failed to get manifest list from cache, error: %v", err)
}
return a != nil && string(desc.Digest) == a.Digest, nil, nil
}
err = c.cache.Fetch(manifestListContentTypeKey(art.Repository, string(desc.Digest)), &contentType)
err = c.cache.Fetch(manifestListContentTypeKey(art.Repository, art), &contentType)
if err != nil {
log.Debugf("failed to get the manifest list content type, not use local. error:%v", err)
return false, nil, nil
}
log.Debugf("Get the manifest list with key=cache:%v", manifestListKey(art.Repository, string(desc.Digest)))
log.Debugf("Get the manifest list with key=cache:%v", manifestListKey(art.Repository, art))
return true, &ManifestList{content, string(desc.Digest), contentType}, nil
}
func manifestListKey(repo, dig string) string {
// actual redis key format is cache:manifestlist:<repo name>:sha256:xxxx
return "manifestlist:" + repo + ":" + dig
func manifestListKey(repo string, art lib.ArtifactInfo) string {
// actual redis key format is cache:manifestlist:<repo name>:<tag> or cache:manifestlist:<repo name>:sha256:xxxx
return "manifestlist:" + repo + ":" + getReference(art)
}
func manifestListContentTypeKey(rep, dig string) string {
return manifestListKey(rep, dig) + ":contenttype"
func manifestListContentTypeKey(rep string, art lib.ArtifactInfo) string {
return manifestListKey(rep, art) + ":contenttype"
}
func (c *controller) ProxyManifest(ctx context.Context, art lib.ArtifactInfo, remote RemoteInterface) (distribution.Manifest, error) {

View File

@ -17,17 +17,19 @@ package proxy
import (
"context"
"fmt"
"strings"
"time"
"github.com/docker/distribution"
"github.com/docker/distribution/manifest/manifestlist"
"github.com/docker/distribution/manifest/schema2"
"github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/goharbor/harbor/src/lib"
libCache "github.com/goharbor/harbor/src/lib/cache"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/log"
"github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"strings"
"time"
)
const defaultHandler = "default"
@ -67,18 +69,20 @@ func (m *ManifestListCache) CacheContent(ctx context.Context, remoteRepo string,
log.Errorf("failed to get payload, error %v", err)
return
}
key := manifestListKey(art.Repository, art.Digest)
if len(getReference(art)) == 0 {
log.Errorf("failed to get reference, reference is empty, skip to cache manifest list")
return
}
// some registry will not return the digest in the HEAD request, if no digest returned, cache manifest list content with tag
key := manifestListKey(art.Repository, art)
log.Debugf("cache manifest list with key=cache:%v", key)
err = m.cache.Save(manifestListContentTypeKey(art.Repository, art.Digest), contentType, manifestListCacheInterval)
if err != nil {
if err := m.cache.Save(manifestListContentTypeKey(art.Repository, art), contentType, manifestListCacheInterval); err != nil {
log.Errorf("failed to cache content type, error %v", err)
}
err = m.cache.Save(key, payload, manifestListCacheInterval)
if err != nil {
if err := m.cache.Save(key, payload, manifestListCacheInterval); err != nil {
log.Errorf("failed to cache payload, error %v", err)
}
err = m.push(ctx, art.Repository, getReference(art), man)
if err != nil {
if err := m.push(ctx, art.Repository, getReference(art), man); err != nil {
log.Errorf("error when push manifest list to local :%v", err)
}
}
@ -96,7 +100,6 @@ func (m *ManifestListCache) cacheTrimmedDigest(ctx context.Context, newDig strin
return
}
log.Debugf("Saved key:%v, value:%v", key, newDig)
}
func (m *ManifestListCache) updateManifestList(ctx context.Context, repo string, manifest distribution.Manifest) (distribution.Manifest, error) {