mirror of
https://github.com/anchore/syft.git
synced 2026-11-03 07:56:36 +01:00
feat: Add support for scanning GGUF models from OCI registries (#4335)
--------- Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com> Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
co-authored by
Alex Goodman
parent
3a23cfff1d
commit
2c5e193f7a
@@ -114,6 +114,26 @@ func (c *Cataloger) WithParserByPath(parser Parser, paths ...string) *Cataloger
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Cataloger) WithParserByMediaType(parser Parser, types ...string) *Cataloger {
|
||||
c.requesters = append(c.requesters,
|
||||
func(resolver file.Resolver, _ Environment) []request {
|
||||
var requests []request
|
||||
log.WithFields("mediatypes", types).Trace("searching content matching mediatypes")
|
||||
ociResolver, ok := resolver.(file.OCIMediaTypeResolver)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
matches, err := ociResolver.FilesByMediaType(types...)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
requests = append(requests, makeRequests(parser, matches)...)
|
||||
return requests
|
||||
},
|
||||
)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Cataloger) WithProcessors(processors ...Processor) *Cataloger {
|
||||
for _, p := range processors {
|
||||
c.processors = append(c.processors, processorWrapper{Processor: p})
|
||||
|
||||
@@ -138,6 +138,10 @@ func (m spyReturningFileResolver) FilesByMIMEType(types ...string) ([]file.Locat
|
||||
return m.m.FilesByMIMEType(types...)
|
||||
}
|
||||
|
||||
func (m spyReturningFileResolver) FilesByMediaType(types ...string) ([]file.Location, error) {
|
||||
return m.m.FilesByMediaType(types...)
|
||||
}
|
||||
|
||||
func (m spyReturningFileResolver) RelativeFileByPath(f file.Location, path string) *file.Location {
|
||||
return m.m.RelativeFileByPath(f, path)
|
||||
}
|
||||
@@ -189,6 +193,55 @@ func TestClosesFileOnParserPanic(t *testing.T) {
|
||||
require.True(t, spy.closed)
|
||||
}
|
||||
|
||||
func Test_CatalogerWithParserByMediaType(t *testing.T) {
|
||||
allParsedPaths := make(map[string]bool)
|
||||
parser := func(_ context.Context, resolver file.Resolver, env *Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
allParsedPaths[reader.Path()] = true
|
||||
contents, err := io.ReadAll(reader)
|
||||
require.NoError(t, err)
|
||||
|
||||
if len(contents) == 0 {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
p := pkg.Package{
|
||||
Name: string(contents),
|
||||
Locations: file.NewLocationSet(reader.Location),
|
||||
}
|
||||
|
||||
return []pkg.Package{p}, nil, nil
|
||||
}
|
||||
|
||||
upstream := "media-type-cataloger"
|
||||
|
||||
// Create locations with test fixtures that exist on disk
|
||||
loc1 := file.NewLocation("test-fixtures/a-path.txt")
|
||||
loc2 := file.NewLocation("test-fixtures/another-path.txt")
|
||||
|
||||
// Create a mock resolver that maps media types to locations
|
||||
resolver := file.NewMockResolverForMediaTypes(map[string][]file.Location{
|
||||
"application/vnd.test.model": {loc1, loc2},
|
||||
})
|
||||
|
||||
cataloger := NewCataloger(upstream).
|
||||
WithParserByMediaType(parser, "application/vnd.test.model")
|
||||
|
||||
actualPkgs, _, err := cataloger.Catalog(context.Background(), resolver)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Verify both files were parsed
|
||||
assert.True(t, allParsedPaths["test-fixtures/a-path.txt"], "expected a-path.txt to be parsed")
|
||||
assert.True(t, allParsedPaths["test-fixtures/another-path.txt"], "expected another-path.txt to be parsed")
|
||||
|
||||
// Verify packages were created
|
||||
assert.Len(t, actualPkgs, 2)
|
||||
|
||||
// Verify FoundBy is set correctly
|
||||
for _, p := range actualPkgs {
|
||||
assert.Equal(t, upstream, p.FoundBy)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_genericCatalogerReturnsErrors(t *testing.T) {
|
||||
genericErrorReturning := NewCataloger("error returning").WithParserByGlobs(func(ctx context.Context, resolver file.Resolver, environment *Environment, locationReader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
return []pkg.Package{
|
||||
|
||||
Reference in New Issue
Block a user