mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 08:23:15 +01:00
initial take on distro identification
Signed-off-by: Alfredo Deza <adeza@anchore.com>
This commit is contained in:
parent
56c2318ea1
commit
dba5f0b197
@ -1,11 +1,104 @@
|
||||
package distro
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/imgbom/internal/log"
|
||||
"github.com/anchore/stereoscope/pkg/file"
|
||||
"github.com/anchore/stereoscope/pkg/image"
|
||||
)
|
||||
|
||||
func Identify(img *image.Image) (Distro, error) {
|
||||
// returns a distro or nil
|
||||
type parseFunc func(string) *Distro
|
||||
|
||||
// Identify parses distro-specific files to determine distro metadata like version and release
|
||||
func Identify(img *image.Image) *Distro {
|
||||
// TODO: implement me based off of https://github.com/anchore/anchore-engine/blob/78b23d7e8f007005c070673405b5e23730a660e0/anchore_engine/analyzers/utils.py#L131
|
||||
|
||||
return NewDistro(UnknownDistro, "0.0.0")
|
||||
identityFiles := map[file.Path]parseFunc{
|
||||
"/etc/os-release": parseOsRelease,
|
||||
// Debian and Debian-based distros have the same contents linked from this path
|
||||
"/usr/lib/os-release": parseOsRelease,
|
||||
// TODO: change this to /bin/busybox when stereoscope deals with hardlinks
|
||||
"/bin/[": parseBusyBox,
|
||||
}
|
||||
|
||||
for path, fn := range identityFiles {
|
||||
|
||||
contents, err := img.FileContentsFromSquash(path)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("unable to get contents from %s: %s", path, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if contents == "" {
|
||||
log.Debugf("no contents in file, skipping: %s", path)
|
||||
continue
|
||||
}
|
||||
distro := fn(contents)
|
||||
|
||||
if distro == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
return distro
|
||||
|
||||
}
|
||||
// TODO: is it useful to know partially detected distros? where the ID is known but not the version (and viceversa?)
|
||||
return nil
|
||||
}
|
||||
|
||||
func assembleDistro(name, version string) *Distro {
|
||||
distroType, ok := Mappings[name]
|
||||
|
||||
// Both distro and version must be present
|
||||
if len(name) == 0 || len(version) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if ok {
|
||||
distro, err := NewDistro(distroType, version)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return &distro
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseOsRelease(contents string) *Distro {
|
||||
id, vers := "", ""
|
||||
for _, line := range strings.Split(contents, "\n") {
|
||||
|
||||
parts := strings.Split(line, "=")
|
||||
prefix := parts[0]
|
||||
value := strings.ReplaceAll(parts[len(parts)-1], `"`, "")
|
||||
|
||||
switch prefix {
|
||||
case "ID":
|
||||
id = value
|
||||
case "VERSION_ID":
|
||||
vers = value
|
||||
}
|
||||
}
|
||||
|
||||
return assembleDistro(id, vers)
|
||||
}
|
||||
|
||||
var busyboxVersionMatcher = regexp.MustCompile(`BusyBox v[\d\.]+`)
|
||||
|
||||
func parseBusyBox(contents string) *Distro {
|
||||
matches := busyboxVersionMatcher.FindAllString(contents, -1)
|
||||
for _, match := range matches {
|
||||
parts := strings.Split(match, " ")
|
||||
version := strings.ReplaceAll(parts[1], "v", "")
|
||||
distro := assembleDistro("busybox", version)
|
||||
if distro != nil {
|
||||
return distro
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user