mirror of
https://github.com/anchore/syft.git
synced 2026-11-01 23:16:30 +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
@@ -3,10 +3,12 @@ package internal
|
||||
const (
|
||||
// JSONSchemaVersion is the current schema version output by the JSON encoder
|
||||
// This is roughly following the "SchemaVer" guidelines for versioning the JSON schema. Please see schema/json/README.md for details on how to increment.
|
||||
JSONSchemaVersion = "16.1.2"
|
||||
JSONSchemaVersion = "16.1.3"
|
||||
|
||||
// Changelog
|
||||
// 16.1.0 - reformulated the python pdm fields (added "URL" and removed the unused "path" field).
|
||||
// 16.1.1 - correct elf package osCpe field according to the document of systemd (also add appCpe field)
|
||||
// 16.1.2 - placeholder for 16.1.2 changelog
|
||||
// 16.1.3 - add GGUFFileParts to GGUFFileHeader metadata
|
||||
|
||||
)
|
||||
|
||||
@@ -82,12 +82,29 @@ func assembleTypeContainer(items []any) (any, map[string]string) {
|
||||
return reflect.New(structType).Elem().Interface(), mapping
|
||||
}
|
||||
|
||||
//nolint:funlen
|
||||
func build() *jsonschema.Schema {
|
||||
// create metadata mapping first so we can use it in the Namer function for self-referential types
|
||||
pkgMetadataContainer, pkgMetadataMapping := assembleTypeContainer(packagemetadata.AllTypes())
|
||||
pkgMetadataContainerType := reflect.TypeOf(pkgMetadataContainer)
|
||||
|
||||
// create a set of valid metadata display names for lookup
|
||||
// (since Namer now returns display names, the schema definitions use display names as keys)
|
||||
pkgMetadataDisplayNames := make(map[string]struct{}, len(pkgMetadataMapping))
|
||||
for _, displayName := range pkgMetadataMapping {
|
||||
pkgMetadataDisplayNames[displayName] = struct{}{}
|
||||
}
|
||||
|
||||
reflector := &jsonschema.Reflector{
|
||||
BaseSchemaID: schemaID(),
|
||||
AllowAdditionalProperties: true,
|
||||
Namer: func(r reflect.Type) string {
|
||||
return strings.TrimPrefix(r.Name(), "JSON")
|
||||
name := strings.TrimPrefix(r.Name(), "JSON")
|
||||
// if this is a metadata type, use the mapped name for consistent references
|
||||
if mappedName, ok := pkgMetadataMapping[name]; ok {
|
||||
return mappedName
|
||||
}
|
||||
return name
|
||||
},
|
||||
CommentMap: make(map[string]string),
|
||||
}
|
||||
@@ -123,9 +140,6 @@ func build() *jsonschema.Schema {
|
||||
copyAliasFieldComments(reflector.CommentMap, repoRoot)
|
||||
}
|
||||
|
||||
pkgMetadataContainer, pkgMetadataMapping := assembleTypeContainer(packagemetadata.AllTypes())
|
||||
pkgMetadataContainerType := reflect.TypeOf(pkgMetadataContainer)
|
||||
|
||||
// srcMetadataContainer := assembleTypeContainer(sourcemetadata.AllTypes())
|
||||
// srcMetadataContainerType := reflect.TypeOf(srcMetadataContainer)
|
||||
|
||||
@@ -144,11 +158,10 @@ func build() *jsonschema.Schema {
|
||||
continue
|
||||
}
|
||||
|
||||
displayName, ok := pkgMetadataMapping[typeName]
|
||||
if ok {
|
||||
// this is a package metadata type...
|
||||
documentSchema.Definitions[displayName] = definition
|
||||
metadataNames = append(metadataNames, displayName)
|
||||
if _, ok := pkgMetadataDisplayNames[typeName]; ok {
|
||||
// this is a package metadata type (typeName is already the display name from Namer)
|
||||
documentSchema.Definitions[typeName] = definition
|
||||
metadataNames = append(metadataNames, typeName)
|
||||
} else {
|
||||
// this is a type that the metadata type uses (e.g. DpkgFileRecord)
|
||||
documentSchema.Definitions[typeName] = definition
|
||||
|
||||
@@ -26,6 +26,7 @@ var knownNonMetadataTypeNames = strset.New(
|
||||
// known to be metadata types themselves. Adding to this list will prevent the removal of the type from the schema.
|
||||
var knownMetadataTypeNames = strset.New(
|
||||
"DotnetPortableExecutableEntry",
|
||||
"GGUFFileHeader",
|
||||
)
|
||||
|
||||
func DiscoverTypeNames() ([]string, error) {
|
||||
|
||||
@@ -94,25 +94,33 @@ func findMetadataDefinitionNamesInFile(path string) ([]string, []string, error)
|
||||
|
||||
// loop over all types declared in the type declaration
|
||||
for _, typ := range spec.Specs {
|
||||
// check if the type is a struct type
|
||||
spec, ok := typ.(*ast.TypeSpec)
|
||||
if !ok || spec.Type == nil {
|
||||
typeSpec, ok := typ.(*ast.TypeSpec)
|
||||
if !ok || typeSpec.Type == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
structType, ok := spec.Type.(*ast.StructType)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
// check if the struct type ends with "Metadata"
|
||||
name := spec.Name.String()
|
||||
name := typeSpec.Name.String()
|
||||
|
||||
// only look for exported types that end with "Metadata"
|
||||
if isMetadataTypeCandidate(name) {
|
||||
// print the full declaration of the struct type
|
||||
metadataDefinitions = append(metadataDefinitions, name)
|
||||
if !isMetadataTypeCandidate(name) {
|
||||
continue
|
||||
}
|
||||
|
||||
metadataDefinitions = append(metadataDefinitions, name)
|
||||
|
||||
// handle struct types (e.g., "type FooMetadata struct {...}")
|
||||
if structType, ok := typeSpec.Type.(*ast.StructType); ok {
|
||||
usedTypeNames = append(usedTypeNames, typeNamesUsedInStruct(structType)...)
|
||||
continue
|
||||
}
|
||||
|
||||
// handle type definitions from another type (e.g., "type FooMetadata BarMetadata")
|
||||
// if the base type is NOT a metadata candidate, track it as used
|
||||
// (e.g., we want both ImageMetadata and OCIModelMetadata which is an alias to it)
|
||||
if ident, ok := typeSpec.Type.(*ast.Ident); ok {
|
||||
if !isMetadataTypeCandidate(ident.Name) {
|
||||
usedTypeNames = append(usedTypeNames, ident.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,5 +6,5 @@ import "github.com/anchore/syft/syft/source"
|
||||
|
||||
// AllTypes returns a list of all source metadata types that syft supports (that are represented in the source.Description.Metadata field).
|
||||
func AllTypes() []any {
|
||||
return []any{source.DirectoryMetadata{}, source.FileMetadata{}, source.ImageMetadata{}, source.SnapMetadata{}}
|
||||
return []any{source.DirectoryMetadata{}, source.FileMetadata{}, source.ImageMetadata{}, source.OCIModelMetadata{}, source.SnapMetadata{}}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ var jsonNameFromType = map[reflect.Type][]string{
|
||||
reflect.TypeOf(source.FileMetadata{}): {"file"},
|
||||
reflect.TypeOf(source.ImageMetadata{}): {"image"},
|
||||
reflect.TypeOf(source.SnapMetadata{}): {"snap"},
|
||||
reflect.TypeOf(source.OCIModelMetadata{}): {"oci-model"},
|
||||
}
|
||||
|
||||
func AllTypeNames() []string {
|
||||
|
||||
Reference in New Issue
Block a user