mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-18 22:57:38 +01:00
Try to parse the type of the artifact based on the media type when no resolver found
Try to parse the type of the artifact based on the media type when no resolver found, if parse failed, set it's type to unknown. This won't block the pushing for artifacts that has no resolver registered in Harbor Signed-off-by: Wenkai Yin <yinw@vmware.com>
This commit is contained in:
parent
63ef743ba7
commit
1f3fcbde36
@ -26,8 +26,15 @@ import (
|
|||||||
"github.com/goharbor/harbor/src/pkg/artifact"
|
"github.com/goharbor/harbor/src/pkg/artifact"
|
||||||
"github.com/goharbor/harbor/src/pkg/repository"
|
"github.com/goharbor/harbor/src/pkg/repository"
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
"github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ArtifactTypeUnknown defines the type for the unknown artifacts
|
||||||
|
const ArtifactTypeUnknown = "UNKNOWN"
|
||||||
|
|
||||||
|
var artifactTypeRegExp = regexp.MustCompile(`^application/vnd\.[^.]*\.(.*)\.config\.[^.]*\+json$`)
|
||||||
|
|
||||||
// Abstractor abstracts the specific information for different types of artifacts
|
// Abstractor abstracts the specific information for different types of artifacts
|
||||||
type Abstractor interface {
|
type Abstractor interface {
|
||||||
// Abstract the specific information for the specific artifact type into the artifact model,
|
// Abstract the specific information for the specific artifact type into the artifact model,
|
||||||
@ -109,10 +116,22 @@ func (a *abstractor) Abstract(ctx context.Context, artifact *artifact.Artifact)
|
|||||||
return fmt.Errorf("unsupported manifest media type: %s", artifact.ManifestMediaType)
|
return fmt.Errorf("unsupported manifest media type: %s", artifact.ManifestMediaType)
|
||||||
}
|
}
|
||||||
|
|
||||||
resolver, err := resolver.Get(artifact.MediaType)
|
resolver := resolver.Get(artifact.MediaType)
|
||||||
if err != nil {
|
if resolver != nil {
|
||||||
return err
|
artifact.Type = resolver.ArtifactType()
|
||||||
|
return resolver.Resolve(ctx, content, artifact)
|
||||||
}
|
}
|
||||||
artifact.Type = resolver.ArtifactType()
|
|
||||||
return resolver.Resolve(ctx, content, artifact)
|
// if got no resolver, try to parse the artifact type based on the media type
|
||||||
|
artifact.Type = parseArtifactType(artifact.MediaType)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseArtifactType(mediaType string) string {
|
||||||
|
strs := artifactTypeRegExp.FindStringSubmatch(mediaType)
|
||||||
|
if len(strs) == 2 {
|
||||||
|
return strings.ToUpper(strs[1])
|
||||||
|
}
|
||||||
|
// can not get the artifact type from the media type, return unknown
|
||||||
|
return ArtifactTypeUnknown
|
||||||
}
|
}
|
||||||
|
@ -294,6 +294,28 @@ func (a *abstractorTestSuite) TestAbstractUnsupported() {
|
|||||||
a.fetcher.AssertExpectations(a.T())
|
a.fetcher.AssertExpectations(a.T())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *abstractorTestSuite) TestParseArtifactType() {
|
||||||
|
mediaType := ""
|
||||||
|
typee := parseArtifactType(mediaType)
|
||||||
|
a.Equal(ArtifactTypeUnknown, typee)
|
||||||
|
|
||||||
|
mediaType = "unknown"
|
||||||
|
typee = parseArtifactType(mediaType)
|
||||||
|
a.Equal(ArtifactTypeUnknown, typee)
|
||||||
|
|
||||||
|
mediaType = "application/vnd.oci.image.config.v1+json"
|
||||||
|
typee = parseArtifactType(mediaType)
|
||||||
|
a.Equal("IMAGE", typee)
|
||||||
|
|
||||||
|
mediaType = "application/vnd.cncf.helm.chart.config.v1+json"
|
||||||
|
typee = parseArtifactType(mediaType)
|
||||||
|
a.Equal("HELM.CHART", typee)
|
||||||
|
|
||||||
|
mediaType = "application/vnd.sylabs.sif.config.v1+json"
|
||||||
|
typee = parseArtifactType(mediaType)
|
||||||
|
a.Equal("SIF", typee)
|
||||||
|
}
|
||||||
|
|
||||||
func TestAbstractorTestSuite(t *testing.T) {
|
func TestAbstractorTestSuite(t *testing.T) {
|
||||||
suite.Run(t, &abstractorTestSuite{})
|
suite.Run(t, &abstractorTestSuite{})
|
||||||
}
|
}
|
||||||
|
@ -49,10 +49,6 @@ func Register(resolver Resolver, mediaTypes ...string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the resolver according to the media type
|
// Get the resolver according to the media type
|
||||||
func Get(mediaType string) (Resolver, error) {
|
func Get(mediaType string) Resolver {
|
||||||
resolver, exist := registry[mediaType]
|
return registry[mediaType]
|
||||||
if !exist {
|
|
||||||
return nil, fmt.Errorf("resolver resolves %s not found", mediaType)
|
|
||||||
}
|
|
||||||
return resolver, nil
|
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,22 @@
|
|||||||
package resolver
|
package resolver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/goharbor/harbor/src/pkg/artifact"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type fakeResolver struct{}
|
||||||
|
|
||||||
|
func (f *fakeResolver) ArtifactType() string {
|
||||||
|
return ""
|
||||||
|
|
||||||
|
}
|
||||||
|
func (f *fakeResolver) Resolve(ctx context.Context, manifest []byte, artifact *artifact.Artifact) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type resolverTestSuite struct {
|
type resolverTestSuite struct {
|
||||||
suite.Suite
|
suite.Suite
|
||||||
}
|
}
|
||||||
@ -37,16 +49,16 @@ func (r *resolverTestSuite) TestRegister() {
|
|||||||
func (r *resolverTestSuite) TestGet() {
|
func (r *resolverTestSuite) TestGet() {
|
||||||
// registry a resolver
|
// registry a resolver
|
||||||
mediaType := "fake_media_type"
|
mediaType := "fake_media_type"
|
||||||
err := Register(nil, mediaType)
|
err := Register(&fakeResolver{}, mediaType)
|
||||||
r.Assert().Nil(err)
|
r.Assert().Nil(err)
|
||||||
|
|
||||||
// get the resolver
|
// get the resolver
|
||||||
_, err = Get(mediaType)
|
resolver := Get(mediaType)
|
||||||
r.Assert().Nil(err)
|
r.Assert().NotNil(resolver)
|
||||||
|
|
||||||
// get the not exist resolver
|
// get the not exist resolver
|
||||||
_, err = Get("not_existing_media_type")
|
resolver = Get("not_existing_media_type")
|
||||||
r.Assert().NotNil(err)
|
r.Assert().Nil(resolver)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestResolverTestSuite(t *testing.T) {
|
func TestResolverTestSuite(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user