From 91baabe5a10b5a0d29ab3999072e9a6dc0c93a57 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Mon, 16 Nov 2020 08:19:57 -0500 Subject: [PATCH] add image metadata as catalogFromJSON return Signed-off-by: Alex Goodman --- internal/file/glob_match.go | 2 +- syft/lib.go | 24 +++++++++++------------ syft/presenter/cyclonedx/bom-extension.go | 2 +- syft/presenter/cyclonedx/document.go | 2 +- syft/source/source_test.go | 2 +- test/integration/document_import_test.go | 12 +++++++----- 6 files changed, 23 insertions(+), 21 deletions(-) diff --git a/internal/file/glob_match.go b/internal/file/glob_match.go index 07ca126b7..81575de24 100644 --- a/internal/file/glob_match.go +++ b/internal/file/glob_match.go @@ -1,6 +1,6 @@ package file -// Locations: https://research.swtch.com/glob.go +// Source: https://research.swtch.com/glob.go func GlobMatch(pattern, name string) bool { px := 0 nx := 0 diff --git a/syft/lib.go b/syft/lib.go index 9a1d81675..ea06a031f 100644 --- a/syft/lib.go +++ b/syft/lib.go @@ -7,8 +7,8 @@ Here is what the main execution path for syft does: 2. Invoke all catalogers to catalog the image, adding discovered packages to a single catalog object 3. Invoke a single presenter to show the contents of the catalog -A Locations object encapsulates the image object to be cataloged and the user options (catalog all layers vs. squashed layer), -providing a way to inspect paths and file content within the image. The Locations object, not the image object, is used +A Source object encapsulates the image object to be cataloged and the user options (catalog all layers vs. squashed layer), +providing a way to inspect paths and file content within the image. The Source object, not the image object, is used throughout the main execution path. This abstraction allows for decoupling of what is cataloged (a docker image, an OCI image, a filesystem, etc) and how it is cataloged (the individual catalogers). @@ -82,12 +82,12 @@ func CatalogFromScope(s source.Source) (*pkg.Catalog, error) { return cataloger.Catalog(s.Resolver, catalogers...) } -// TODO: we shouldn't return the jsonPresenter.Image object! this is leaky -func CatalogFromJSON(reader io.Reader) (*pkg.Catalog, *distro.Distro, error) { +// CatalogFromJSON takes an existing syft report and generates catalog primitives. +func CatalogFromJSON(reader io.Reader) (*pkg.Catalog, *distro.Distro, *source.ImageMetadata, error) { var doc jsonPresenter.Document decoder := json.NewDecoder(reader) if err := decoder.Decode(&doc); err != nil { - return nil, nil, err + return nil, nil, nil, err } var pkgs = make([]pkg.Package, len(doc.Artifacts)) @@ -106,16 +106,16 @@ func CatalogFromJSON(reader io.Reader) (*pkg.Catalog, *distro.Distro, error) { d, err := distro.NewDistro(distroType, doc.Distro.Version, doc.Distro.IDLike) if err != nil { - return nil, nil, err + return nil, nil, nil, err } - //var theImg *jsonPresenter.Image - //if doc.Locations.Type == "image" { - // img := doc.Locations.Target.(jsonPresenter.Image) - // theImg = &img - //} + var imageMetadata *source.ImageMetadata + if doc.Source.Type == "image" { + payload := doc.Source.Target.(source.ImageMetadata) + imageMetadata = &payload + } - return catalog, &d, nil + return catalog, &d, imageMetadata, nil } // SetLogger sets the logger object used for all syft logging calls. diff --git a/syft/presenter/cyclonedx/bom-extension.go b/syft/presenter/cyclonedx/bom-extension.go index 8e7ce850d..f25713734 100644 --- a/syft/presenter/cyclonedx/bom-extension.go +++ b/syft/presenter/cyclonedx/bom-extension.go @@ -8,7 +8,7 @@ import ( "github.com/anchore/syft/internal/version" ) -// Locations: https://cyclonedx.org/ext/bom-descriptor/ +// Source: https://cyclonedx.org/ext/bom-descriptor/ // BomDescriptor represents all metadata surrounding the BOM report (such as when the BOM was made, with which tool, and the item being cataloged). type BomDescriptor struct { diff --git a/syft/presenter/cyclonedx/document.go b/syft/presenter/cyclonedx/document.go index f2d2fb866..4539ab73e 100644 --- a/syft/presenter/cyclonedx/document.go +++ b/syft/presenter/cyclonedx/document.go @@ -9,7 +9,7 @@ import ( "github.com/google/uuid" ) -// Locations: https://github.com/CycloneDX/specification +// Source: https://github.com/CycloneDX/specification // Document represents a CycloneDX BOM Document. type Document struct { diff --git a/syft/source/source_test.go b/syft/source/source_test.go index 30913c91d..49946cf3b 100644 --- a/syft/source/source_test.go +++ b/syft/source/source_test.go @@ -35,7 +35,7 @@ func TestNewFromImage(t *testing.T) { Layers: []*image.Layer{layer}, } - t.Run("create a new Locations object from image", func(t *testing.T) { + t.Run("create a new source object from image", func(t *testing.T) { _, err := NewFromImage(&img, AllLayersScope, "") if err != nil { t.Errorf("unexpected error when creating a new Locations from img: %+v", err) diff --git a/test/integration/document_import_test.go b/test/integration/document_import_test.go index 50be36c9c..432bd78d3 100644 --- a/test/integration/document_import_test.go +++ b/test/integration/document_import_test.go @@ -31,24 +31,26 @@ func TestCatalogFromJSON(t *testing.T) { tarPath := imagetest.GetFixtureImageTarPath(t, test.fixture) defer cleanup() - expectedCatalog, s, expectedDistro, err := syft.Catalog("docker-archive:"+tarPath, source.AllLayersScope) + expectedCatalog, expectedSource, expectedDistro, err := syft.Catalog("docker-archive:"+tarPath, source.AllLayersScope) if err != nil { t.Fatalf("failed to catalog image: %+v", err) } var buf bytes.Buffer - jsonPres := json.NewPresenter(expectedCatalog, s.Metadata, *expectedDistro) + jsonPres := json.NewPresenter(expectedCatalog, expectedSource.Metadata, *expectedDistro) if err = jsonPres.Present(&buf); err != nil { t.Fatalf("failed to write to presenter: %+v", err) } - // TODO: test img - - actualCatalog, actualDistro, err := syft.CatalogFromJSON(&buf) + actualCatalog, actualDistro, imageMetadata, err := syft.CatalogFromJSON(&buf) if err != nil { t.Fatalf("failed to import document: %+v", err) } + for _, d := range deep.Equal(*imageMetadata, expectedSource.Metadata.ImageMetadata) { + t.Errorf(" image metadata diff: %+v", d) + } + for _, d := range deep.Equal(actualDistro, expectedDistro) { t.Errorf(" distro diff: %+v", d) }