mirror of
https://github.com/anchore/syft.git
synced 2026-02-12 10:36:45 +01:00
feat: detect Debian version from /etc/debian_version (#4569)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
This commit is contained in:
parent
836f358cd4
commit
c65d023668
@ -54,6 +54,12 @@ var identityFiles = []parseEntry{
|
|||||||
// /////////////////////////////////////////////////////////////////////////////////////////////////////
|
// /////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// after a parser function returns a Release, it may have incomplete information; supplementers can be used to
|
||||||
|
// fill in missing details based on other files present in the filesystem
|
||||||
|
var supplementers = []func(file.Resolver, *Release){
|
||||||
|
supplementDebianVersion,
|
||||||
|
}
|
||||||
|
|
||||||
// IdentifyRelease parses distro-specific files to discover and raise linux distribution release details.
|
// IdentifyRelease parses distro-specific files to discover and raise linux distribution release details.
|
||||||
func IdentifyRelease(resolver file.Resolver) *Release {
|
func IdentifyRelease(resolver file.Resolver) *Release {
|
||||||
logger := log.Nested("operation", "identify-release")
|
logger := log.Nested("operation", "identify-release")
|
||||||
@ -67,6 +73,9 @@ func IdentifyRelease(resolver file.Resolver) *Release {
|
|||||||
for _, location := range locations {
|
for _, location := range locations {
|
||||||
release := tryParseReleaseInfo(resolver, location, logger, entry)
|
release := tryParseReleaseInfo(resolver, location, logger, entry)
|
||||||
if release != nil {
|
if release != nil {
|
||||||
|
for _, supplementer := range supplementers {
|
||||||
|
supplementer(resolver, release)
|
||||||
|
}
|
||||||
return release
|
return release
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -74,7 +74,7 @@ func TestIdentifyRelease(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fixture: "test-fixtures/os/debian",
|
fixture: "test-fixtures/os/debian/from-os-release",
|
||||||
release: &Release{
|
release: &Release{
|
||||||
PrettyName: "Debian GNU/Linux 8 (jessie)",
|
PrettyName: "Debian GNU/Linux 8 (jessie)",
|
||||||
Name: "Debian GNU/Linux",
|
Name: "Debian GNU/Linux",
|
||||||
@ -87,6 +87,20 @@ func TestIdentifyRelease(t *testing.T) {
|
|||||||
BugReportURL: "https://bugs.debian.org/",
|
BugReportURL: "https://bugs.debian.org/",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
fixture: "test-fixtures/os/debian/from-debian_version",
|
||||||
|
release: &Release{
|
||||||
|
PrettyName: "Distroless",
|
||||||
|
Name: "Debian GNU/Linux",
|
||||||
|
ID: "debian",
|
||||||
|
IDLike: nil,
|
||||||
|
Version: "10.8",
|
||||||
|
VersionID: "10.8",
|
||||||
|
HomeURL: "https://github.com/GoogleContainerTools/distroless",
|
||||||
|
SupportURL: "https://github.com/GoogleContainerTools/distroless/blob/master/README.md",
|
||||||
|
BugReportURL: "https://github.com/GoogleContainerTools/distroless/issues/new",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
fixture: "test-fixtures/os/fedora",
|
fixture: "test-fixtures/os/fedora",
|
||||||
release: &Release{
|
release: &Release{
|
||||||
|
|||||||
51
syft/linux/supplement_release.go
Normal file
51
syft/linux/supplement_release.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/anchore/syft/internal"
|
||||||
|
"github.com/anchore/syft/internal/log"
|
||||||
|
"github.com/anchore/syft/syft/file"
|
||||||
|
)
|
||||||
|
|
||||||
|
func supplementDebianVersion(resolver file.Resolver, release *Release) {
|
||||||
|
// we're only looking for version information for debian when none is present in /etc/os-release
|
||||||
|
if release.Version != "" || release.VersionID != "" || !strings.EqualFold(release.ID, "debian") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// if we have a debian release with no version, look for a debian_version
|
||||||
|
locations, err := resolver.FilesByGlob("/etc/debian_version")
|
||||||
|
if err != nil {
|
||||||
|
log.Debugf("error reading /etc/debian_version: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, location := range locations {
|
||||||
|
version := readDebianVersionFile(resolver, location)
|
||||||
|
if version != "" {
|
||||||
|
release.Version = version
|
||||||
|
release.VersionID = version
|
||||||
|
return // keep the first result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func readDebianVersionFile(resolver file.Resolver, location file.Location) string {
|
||||||
|
rdr, err := resolver.FileContentsByLocation(location)
|
||||||
|
if err != nil {
|
||||||
|
log.Debugf("error getting contents for %s: %v", location.RealPath, err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
defer internal.CloseAndLogError(rdr, location.RealPath)
|
||||||
|
contents, err := io.ReadAll(rdr)
|
||||||
|
if err != nil {
|
||||||
|
log.Debugf("error reading %s: %v", location.RealPath, err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
version := strings.TrimSpace(string(contents))
|
||||||
|
if regexp.MustCompile(`^\d+(?:\.\d+)?$`).MatchString(version) {
|
||||||
|
return version
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
10.8
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
PRETTY_NAME="Distroless"
|
||||||
|
NAME="Debian GNU/Linux"
|
||||||
|
ID="debian"
|
||||||
|
HOME_URL="https://github.com/GoogleContainerTools/distroless"
|
||||||
|
SUPPORT_URL="https://github.com/GoogleContainerTools/distroless/blob/master/README.md"
|
||||||
|
BUG_REPORT_URL="https://github.com/GoogleContainerTools/distroless/issues/new"
|
||||||
Loading…
x
Reference in New Issue
Block a user