mirror of
https://github.com/anchore/syft.git
synced 2025-11-18 00:43:20 +01:00
Add support for older CentOS versions (6 & 5) by checking additional release files for information
Signed-off-by: Samuel Dacanay <sam.dacanay@anchore.com>
This commit is contained in:
parent
5de1a0a236
commit
0799fd9d46
@ -35,6 +35,16 @@ var identityFiles = []parseEntry{
|
||||
path: "/bin/busybox",
|
||||
fn: parseBusyBox,
|
||||
},
|
||||
{
|
||||
// check for centos:6
|
||||
path: "/etc/system-release-cpe",
|
||||
fn: parseSystemReleaseCPE,
|
||||
},
|
||||
{
|
||||
// last ditch effort for determining older centos version distro information
|
||||
path: "/etc/redhat-release",
|
||||
fn: parseRedhatRelease,
|
||||
},
|
||||
}
|
||||
|
||||
// Identify parses distro-specific files to determine distro metadata like version and release.
|
||||
@ -145,3 +155,48 @@ func parseBusyBox(contents string) *Distro {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: we should update parseSystemReleaseCPE to use the CPE struct, pkg.CPE, which requires a refactor to avoid a circular import:
|
||||
// TODO: pkg depends on distro to support pURLs. To avoid the circular import, either try to make pkg to not depend on distro (medium lift-ish)
|
||||
// TODO: or migrate the cpe code out of the pkg package (small lift).
|
||||
// example CPE: cpe:/o:centos:linux:6:GA
|
||||
var systemReleaseCpeMatcher = regexp.MustCompile(`cpe:\/o:(.*?):.*?:(.*?):.*?$`)
|
||||
|
||||
// parseSystemReleaseCPE parses the older centos (6) file to determine distro metadata
|
||||
func parseSystemReleaseCPE(contents string) *Distro {
|
||||
matches := systemReleaseCpeMatcher.FindAllStringSubmatch(contents, -1)
|
||||
for _, match := range matches {
|
||||
if len(match) < 3 {
|
||||
log.Warnf("system release cpe does not match expected format")
|
||||
return nil
|
||||
}
|
||||
// note: in SubMatches (capture groups), the 0th index is the full match string
|
||||
// see https://pkg.go.dev/regexp#pkg-overview for more info
|
||||
distro := assemble(match[1], match[2], "")
|
||||
if distro != nil {
|
||||
return distro
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// example: "CentOS release 6.10 (Final)"
|
||||
var redhatReleaseMatcher = regexp.MustCompile(`(.*?)\srelease\s(\d\.\d+)`)
|
||||
|
||||
// parseRedhatRelease is a fallback parsing method for determining distro information in older redhat versions
|
||||
func parseRedhatRelease(contents string) *Distro {
|
||||
matches := redhatReleaseMatcher.FindAllStringSubmatch(contents, -1)
|
||||
for _, match := range matches {
|
||||
if len(match) < 3 {
|
||||
log.Warnf("failed to parse redhat-release file, unexpected format")
|
||||
return nil
|
||||
}
|
||||
// note: in SubMatches (capture groups), the 0th index is the full match string
|
||||
// see https://pkg.go.dev/regexp#pkg-overview for more info
|
||||
distro := assemble(strings.ToLower(match[1]), match[2], "")
|
||||
if distro != nil {
|
||||
return distro
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package distro
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
hashiVer "github.com/hashicorp/go-version"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
@ -103,6 +104,16 @@ func TestIdentifyDistro(t *testing.T) {
|
||||
fixture: "test-fixtures/partial-fields/missing-version",
|
||||
Type: UnknownDistroType,
|
||||
},
|
||||
{
|
||||
fixture: "test-fixtures/os/centos6",
|
||||
Type: CentOS,
|
||||
Version: "6.0.0",
|
||||
},
|
||||
{
|
||||
fixture: "test-fixtures/os/centos5",
|
||||
Type: CentOS,
|
||||
Version: "5.7.0",
|
||||
},
|
||||
}
|
||||
|
||||
observedDistros := internal.NewStringSet()
|
||||
@ -205,18 +216,7 @@ func TestParseOsRelease(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
name := fmt.Sprintf("%s:%s", test.name, test.RawVersion)
|
||||
fixture, err := os.Open(test.fixture)
|
||||
if err != nil {
|
||||
t.Fatalf("could not open test fixture=%s: %+v", test.fixture, err)
|
||||
}
|
||||
defer fixture.Close()
|
||||
|
||||
b, err := ioutil.ReadAll(fixture)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to read fixture file: %+v", err)
|
||||
}
|
||||
|
||||
contents := string(b)
|
||||
contents := retrieveFixtureContentsAsString(test.fixture, t)
|
||||
|
||||
t.Run(name, func(t *testing.T) {
|
||||
distro := parseOsRelease(contents)
|
||||
@ -245,18 +245,7 @@ func TestParseOsReleaseFailures(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
name := fmt.Sprintf("%s:%s", test.name, test.fixture)
|
||||
fixture, err := os.Open(test.fixture)
|
||||
if err != nil {
|
||||
t.Fatalf("could not open test fixture=%s: %+v", test.fixture, err)
|
||||
}
|
||||
defer fixture.Close()
|
||||
|
||||
b, err := ioutil.ReadAll(fixture)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to read fixture file: %+v", err)
|
||||
}
|
||||
|
||||
contents := string(b)
|
||||
contents := retrieveFixtureContentsAsString(test.fixture, t)
|
||||
|
||||
t.Run(name, func(t *testing.T) {
|
||||
distro := parseOsRelease(contents)
|
||||
@ -265,5 +254,101 @@ func TestParseOsReleaseFailures(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestParseSystemReleaseCPE(t *testing.T) {
|
||||
centos6Version, _ := hashiVer.NewVersion("6")
|
||||
tests := []struct {
|
||||
fixture string
|
||||
name string
|
||||
expected *Distro
|
||||
}{
|
||||
{
|
||||
fixture: "test-fixtures/os/centos6/etc/system-release-cpe",
|
||||
name: "Centos 6",
|
||||
expected: &Distro{
|
||||
Type: CentOS,
|
||||
Version: centos6Version,
|
||||
RawVersion: "6",
|
||||
},
|
||||
},
|
||||
{
|
||||
fixture: "test-fixtures/bad-system-release-cpe",
|
||||
name: "Centos 6 Bad CPE",
|
||||
expected: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
contents := retrieveFixtureContentsAsString(test.fixture, t)
|
||||
actual := parseSystemReleaseCPE(contents)
|
||||
|
||||
if test.expected == nil {
|
||||
assert.Nil(t, actual)
|
||||
return
|
||||
}
|
||||
|
||||
// not comparing the full distro object because the hashiVer is a pointer
|
||||
assert.Equal(t, test.expected.Type, actual.Type)
|
||||
assert.Equal(t, &test.expected.Version, &actual.Version)
|
||||
assert.Equal(t, test.expected.RawVersion, actual.RawVersion)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseRedhatRelease(t *testing.T) {
|
||||
centos5Version, _ := hashiVer.NewVersion("5.7")
|
||||
tests := []struct {
|
||||
fixture string
|
||||
name string
|
||||
expected *Distro
|
||||
}{
|
||||
{
|
||||
fixture: "test-fixtures/os/centos5/etc/redhat-release",
|
||||
name: "Centos 5",
|
||||
expected: &Distro{
|
||||
Type: CentOS,
|
||||
Version: centos5Version,
|
||||
RawVersion: "5.7",
|
||||
},
|
||||
},
|
||||
{
|
||||
fixture: "test-fixtures/bad-redhat-release",
|
||||
name: "Centos 5 Bad Redhat Release",
|
||||
expected: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
contents := retrieveFixtureContentsAsString(test.fixture, t)
|
||||
actual := parseRedhatRelease(contents)
|
||||
|
||||
if test.expected == nil {
|
||||
assert.Nil(t, actual)
|
||||
return
|
||||
}
|
||||
|
||||
// not comparing the full distro object because the hashiVer is a pointer
|
||||
assert.Equal(t, test.expected.Type, actual.Type)
|
||||
assert.Equal(t, &test.expected.Version, &actual.Version)
|
||||
assert.Equal(t, test.expected.RawVersion, actual.RawVersion)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func retrieveFixtureContentsAsString(fixturePath string, t *testing.T) string {
|
||||
fixture, err := os.Open(fixturePath)
|
||||
if err != nil {
|
||||
t.Fatalf("could not open test fixture=%s: %+v", fixturePath, err)
|
||||
}
|
||||
defer fixture.Close()
|
||||
|
||||
b, err := ioutil.ReadAll(fixture)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to read fixture file: %+v", err)
|
||||
}
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
1
syft/distro/test-fixtures/bad-redhat-release
Normal file
1
syft/distro/test-fixtures/bad-redhat-release
Normal file
@ -0,0 +1 @@
|
||||
CentOS release 5 (Final)
|
||||
1
syft/distro/test-fixtures/bad-system-release-cpe
Normal file
1
syft/distro/test-fixtures/bad-system-release-cpe
Normal file
@ -0,0 +1 @@
|
||||
cpe:/o:centos:6:GA
|
||||
1
syft/distro/test-fixtures/os/centos5/etc/redhat-release
Normal file
1
syft/distro/test-fixtures/os/centos5/etc/redhat-release
Normal file
@ -0,0 +1 @@
|
||||
CentOS release 5.7 (Final)
|
||||
@ -0,0 +1 @@
|
||||
cpe:/o:centos:linux:6:GA
|
||||
Loading…
x
Reference in New Issue
Block a user