From 64d55541442d43fd67b7c1ff76cf8e7821b0c11e Mon Sep 17 00:00:00 2001 From: Alfredo Deza Date: Tue, 10 Nov 2020 12:37:35 -0500 Subject: [PATCH 1/3] include ID_LIKE in distro detection Signed-off-by: Alfredo Deza --- syft/distro/distro.go | 4 +++- syft/distro/distro_test.go | 9 +++++++-- syft/distro/identify.go | 12 +++++++----- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/syft/distro/distro.go b/syft/distro/distro.go index 4de1fd332..7e01b2493 100644 --- a/syft/distro/distro.go +++ b/syft/distro/distro.go @@ -10,6 +10,7 @@ type Distro struct { Type Type Version *hashiVer.Version RawVersion string + IDLike string } // NewUnknownDistro creates a standardized Distro object for unidentifiable distros @@ -19,7 +20,7 @@ func NewUnknownDistro() Distro { } } -func NewDistro(t Type, ver string) (Distro, error) { +func NewDistro(t Type, ver, like string) (Distro, error) { if ver == "" { return Distro{Type: t}, nil } @@ -31,6 +32,7 @@ func NewDistro(t Type, ver string) (Distro, error) { Type: t, Version: verObj, RawVersion: ver, + IDLike: like, }, nil } diff --git a/syft/distro/distro_test.go b/syft/distro/distro_test.go index bf5b6e7c0..0c8320d6f 100644 --- a/syft/distro/distro_test.go +++ b/syft/distro/distro_test.go @@ -33,7 +33,7 @@ func TestDistro_FullVersion(t *testing.T) { for _, test := range tests { name := fmt.Sprintf("%s:%s", test.dist, test.version) t.Run(name, func(t *testing.T) { - d, err := NewDistro(test.dist, test.version) + d, err := NewDistro(test.dist, test.version, "") if err != nil { t.Errorf("could not create distro='%+v:%+v': %+v", test.dist, test.version, err) } @@ -53,29 +53,34 @@ func TestDistro_MajorVersion(t *testing.T) { dist Type version string expected string + like string }{ { version: "8", expected: "8", + like: "", }, { version: "18.04", expected: "18", + like: "debian", }, { version: "0", expected: "0", + like: "", }, { version: "18.1.2", expected: "18", + like: "debian", }, } for _, test := range tests { name := fmt.Sprintf("%s:%s", test.dist, test.version) t.Run(name, func(t *testing.T) { - d, err := NewDistro(test.dist, test.version) + d, err := NewDistro(test.dist, test.version, test.like) if err != nil { t.Errorf("could not create distro='%+v:%+v': %+v", test.dist, test.version, err) } diff --git a/syft/distro/identify.go b/syft/distro/identify.go index af7c7a224..ec7cbcb2a 100644 --- a/syft/distro/identify.go +++ b/syft/distro/identify.go @@ -81,7 +81,7 @@ identifyLoop: return distro } -func assemble(name, version string) *Distro { +func assemble(name, version, like string) *Distro { distroType, ok := IDMapping[name] // Both distro and version must be present @@ -90,7 +90,7 @@ func assemble(name, version string) *Distro { } if ok { - distro, err := NewDistro(distroType, version) + distro, err := NewDistro(distroType, version, like) if err != nil { return nil } @@ -101,7 +101,7 @@ func assemble(name, version string) *Distro { } func parseOsRelease(contents string) *Distro { - id, vers := "", "" + id, vers, like := "", "", "" for _, line := range strings.Split(contents, "\n") { parts := strings.Split(line, "=") prefix := parts[0] @@ -112,10 +112,12 @@ func parseOsRelease(contents string) *Distro { id = strings.TrimSpace(value) case "VERSION_ID": vers = strings.TrimSpace(value) + case "ID_LIKE": + like = strings.TrimSpace(value) } } - return assemble(id, vers) + return assemble(id, vers, like) } var busyboxVersionMatcher = regexp.MustCompile(`BusyBox v[\d\.]+`) @@ -125,7 +127,7 @@ func parseBusyBox(contents string) *Distro { for _, match := range matches { parts := strings.Split(match, " ") version := strings.ReplaceAll(parts[1], "v", "") - distro := assemble("busybox", version) + distro := assemble("busybox", version, "") if distro != nil { return distro } From 10b55311dfc62c20743d7b263c13e36900818ef1 Mon Sep 17 00:00:00 2001 From: Alfredo Deza Date: Tue, 10 Nov 2020 12:40:17 -0500 Subject: [PATCH 2/3] presenter: provide ID_LIKE information in json Signed-off-by: Alfredo Deza --- syft/presenter/json/document.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/syft/presenter/json/document.go b/syft/presenter/json/document.go index 0762e934f..713dc7d7a 100644 --- a/syft/presenter/json/document.go +++ b/syft/presenter/json/document.go @@ -16,6 +16,7 @@ type Document struct { type Distribution struct { Name string `json:"name"` Version string `json:"version"` + IDLike string `json:"idLike"` } func NewDocument(catalog *pkg.Catalog, s scope.Scope, d distro.Distro) (Document, error) { @@ -35,6 +36,7 @@ func NewDocument(catalog *pkg.Catalog, s scope.Scope, d distro.Distro) (Document doc.Distro = Distribution{ Name: distroName, Version: d.FullVersion(), + IDLike: d.IDLike, } for _, p := range catalog.Sorted() { From 6ae3b4795922af8f24114c05ff248f42932cd9ac Mon Sep 17 00:00:00 2001 From: Alfredo Deza Date: Tue, 10 Nov 2020 12:40:50 -0500 Subject: [PATCH 3/3] tests: update all tests to pass the IDLike value Signed-off-by: Alfredo Deza --- syft/presenter/cyclonedx/presenter_test.go | 4 ++-- .../json/test-fixtures/snapshot/TestJsonDirsPresenter.golden | 3 ++- .../json/test-fixtures/snapshot/TestJsonImgsPresenter.golden | 3 ++- test/integration/distro_test.go | 2 +- test/integration/json_schema_test.go | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/syft/presenter/cyclonedx/presenter_test.go b/syft/presenter/cyclonedx/presenter_test.go index d600d5309..39778d3c1 100644 --- a/syft/presenter/cyclonedx/presenter_test.go +++ b/syft/presenter/cyclonedx/presenter_test.go @@ -62,7 +62,7 @@ func TestCycloneDxDirsPresenter(t *testing.T) { t.Fatal(err) } - d, err := distro.NewDistro(distro.Ubuntu, "20.04") + d, err := distro.NewDistro(distro.Ubuntu, "20.04", "debian") if err != nil { t.Fatal(err) } @@ -152,7 +152,7 @@ func TestCycloneDxImgsPresenter(t *testing.T) { t.Fatal(err) } - d, err := distro.NewDistro(distro.RedHat, "8") + d, err := distro.NewDistro(distro.RedHat, "8", "") if err != nil { t.Fatal(err) } diff --git a/syft/presenter/json/test-fixtures/snapshot/TestJsonDirsPresenter.golden b/syft/presenter/json/test-fixtures/snapshot/TestJsonDirsPresenter.golden index a56d23169..548a5ba2b 100644 --- a/syft/presenter/json/test-fixtures/snapshot/TestJsonDirsPresenter.golden +++ b/syft/presenter/json/test-fixtures/snapshot/TestJsonDirsPresenter.golden @@ -29,6 +29,7 @@ }, "distro": { "name": "", - "version": "" + "version": "", + "idLike": "" } } diff --git a/syft/presenter/json/test-fixtures/snapshot/TestJsonImgsPresenter.golden b/syft/presenter/json/test-fixtures/snapshot/TestJsonImgsPresenter.golden index 85957c9ba..14031fc3c 100644 --- a/syft/presenter/json/test-fixtures/snapshot/TestJsonImgsPresenter.golden +++ b/syft/presenter/json/test-fixtures/snapshot/TestJsonImgsPresenter.golden @@ -59,6 +59,7 @@ }, "distro": { "name": "", - "version": "" + "version": "", + "idLike": "" } } diff --git a/test/integration/distro_test.go b/test/integration/distro_test.go index 11b92a90d..fdbb5a824 100644 --- a/test/integration/distro_test.go +++ b/test/integration/distro_test.go @@ -24,7 +24,7 @@ func TestDistroImage(t *testing.T) { t.Fatalf("could not find distro") } - expected, err := distro.NewDistro(distro.Busybox, "1.31.1") + expected, err := distro.NewDistro(distro.Busybox, "1.31.1", "") if err != nil { t.Fatalf("could not create distro: %+v", err) } diff --git a/test/integration/json_schema_test.go b/test/integration/json_schema_test.go index 6c49605b3..279b74337 100644 --- a/test/integration/json_schema_test.go +++ b/test/integration/json_schema_test.go @@ -62,7 +62,7 @@ func testJsonSchema(t *testing.T, catalog *pkg.Catalog, theScope *scope.Scope, p output := bytes.NewBufferString("") - d, err := distro.NewDistro(distro.CentOS, "5") + d, err := distro.NewDistro(distro.CentOS, "5", "rhel fedora") if err != nil { t.Fatalf("bad distro: %+v", err) }