mirror of
https://github.com/anchore/syft.git
synced 2026-07-05 02:28:25 +02:00
fix: support v0.2
<optional footer> Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
This commit is contained in:
parent
1f035bc369
commit
58b6f5807e
@ -29,12 +29,12 @@ func NewGGUFCataloger() pkg.Cataloger {
|
|||||||
// covering three discovery paths:
|
// covering three discovery paths:
|
||||||
// - **/*.safetensors files (single-file models; header-only parse)
|
// - **/*.safetensors files (single-file models; header-only parse)
|
||||||
// - **/model.safetensors.index.json files (sharded models)
|
// - **/model.safetensors.index.json files (sharded models)
|
||||||
// - application/vnd.docker.ai.model.config.v0.1+json OCI layers (Docker Model
|
// - application/vnd.docker.ai.model.config.v0.1+json / v0.2+json OCI layers
|
||||||
// Runner artifacts whose config advertises format=="safetensors")
|
// (Docker Model Runner artifacts whose config advertises format=="safetensors")
|
||||||
func NewSafeTensorsCataloger() pkg.Cataloger {
|
func NewSafeTensorsCataloger() pkg.Cataloger {
|
||||||
return generic.NewCataloger(safeTensorsCatalogerName).
|
return generic.NewCataloger(safeTensorsCatalogerName).
|
||||||
WithParserByGlobs(parseSafeTensorsFile, "**/*.safetensors").
|
WithParserByGlobs(parseSafeTensorsFile, "**/*.safetensors").
|
||||||
WithParserByGlobs(parseSafeTensorsIndex, "**/*.safetensors.index.json").
|
WithParserByGlobs(parseSafeTensorsIndex, "**/*.safetensors.index.json").
|
||||||
WithParserByMediaType(parseSafeTensorsOCIConfig, dockerAIModelConfigMediaType).
|
WithParserByMediaType(parseSafeTensorsOCIConfig, dockerAIModelConfigMediaTypes...).
|
||||||
WithProcessors(safeTensorsMergeProcessor)
|
WithProcessors(safeTensorsMergeProcessor)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,11 +18,20 @@ import (
|
|||||||
|
|
||||||
// Docker AI OCI media types used by Docker Model Runner artifacts.
|
// Docker AI OCI media types used by Docker Model Runner artifacts.
|
||||||
const (
|
const (
|
||||||
dockerAIModelConfigMediaType = "application/vnd.docker.ai.model.config.v0.1+json"
|
dockerAIModelFileMediaType = "application/vnd.docker.ai.model.file"
|
||||||
dockerAIModelFileMediaType = "application/vnd.docker.ai.model.file"
|
dockerAILicenseMediaType = "application/vnd.docker.ai.license"
|
||||||
dockerAILicenseMediaType = "application/vnd.docker.ai.license"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// dockerAIModelConfigMediaTypes are the model-config schema versions this
|
||||||
|
// cataloger understands. Versions are enumerated explicitly rather than matched
|
||||||
|
// with a wildcard so that a future, potentially breaking, config schema is not
|
||||||
|
// silently consumed; add a new version here only after confirming the fields we
|
||||||
|
// parse still apply.
|
||||||
|
var dockerAIModelConfigMediaTypes = []string{
|
||||||
|
"application/vnd.docker.ai.model.config.v0.1+json",
|
||||||
|
"application/vnd.docker.ai.model.config.v0.2+json",
|
||||||
|
}
|
||||||
|
|
||||||
// dockerAIModelConfig mirrors the JSON shape of the vnd.docker.ai.model.config
|
// dockerAIModelConfig mirrors the JSON shape of the vnd.docker.ai.model.config
|
||||||
// blob written by Docker Model Runner for AI artifacts. Only fields we use are
|
// blob written by Docker Model Runner for AI artifacts. Only fields we use are
|
||||||
// declared; unknown fields are ignored.
|
// declared; unknown fields are ignored.
|
||||||
|
|||||||
@ -410,3 +410,26 @@ func TestModelNameFromPath(t *testing.T) {
|
|||||||
assert.Equal(t, "my-model", modelNameFromIndexPath("/models/my-model/model.safetensors.index.json"))
|
assert.Equal(t, "my-model", modelNameFromIndexPath("/models/my-model/model.safetensors.index.json"))
|
||||||
assert.Equal(t, "safetensors-model", modelNameFromIndexPath("model.safetensors.index.json"))
|
assert.Equal(t, "safetensors-model", modelNameFromIndexPath("model.safetensors.index.json"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDockerAIModelConfigMediaTypes(t *testing.T) {
|
||||||
|
// supported mirrors how the resolver matches: filepath.Match each registered
|
||||||
|
// media type against a layer's media type.
|
||||||
|
supported := func(mt string) bool {
|
||||||
|
for _, p := range dockerAIModelConfigMediaTypes {
|
||||||
|
if ok, err := filepath.Match(p, mt); err == nil && ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// the known, verified schema versions are consumed
|
||||||
|
assert.True(t, supported("application/vnd.docker.ai.model.config.v0.1+json"))
|
||||||
|
assert.True(t, supported("application/vnd.docker.ai.model.config.v0.2+json"))
|
||||||
|
// unknown/future schema versions are intentionally NOT consumed, to avoid
|
||||||
|
// silently ingesting a potentially breaking config change
|
||||||
|
assert.False(t, supported("application/vnd.docker.ai.model.config.v0.3+json"))
|
||||||
|
assert.False(t, supported("application/vnd.docker.ai.model.config.v9.9+json"))
|
||||||
|
// sibling layer media types are not matched either
|
||||||
|
assert.False(t, supported("application/vnd.docker.ai.model.file"))
|
||||||
|
assert.False(t, supported("application/vnd.docker.ai.gguf.v3"))
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user