github.com/anchore/syft@v1.38.2/internal/os/feature_detection.go (about) 1 package os 2 3 import ( 4 "context" 5 "fmt" 6 "regexp" 7 8 "github.com/anchore/syft/internal" 9 "github.com/anchore/syft/internal/log" 10 "github.com/anchore/syft/internal/sbomsync" 11 "github.com/anchore/syft/syft/file" 12 "github.com/anchore/syft/syft/linux" 13 "github.com/anchore/syft/syft/sbom" 14 ) 15 16 func DetectFeatures(_ context.Context, resolver file.Resolver, builder sbomsync.Builder) error { 17 builder.(sbomsync.Accessor).WriteToSBOM(func(s *sbom.SBOM) { 18 if s.Artifacts.LinuxDistribution == nil { 19 return 20 } 21 22 err := findRhelFeatures(resolver, s.Artifacts.LinuxDistribution) 23 if err != nil { 24 log.WithFields("error", err, "release", s.Artifacts.LinuxDistribution).Trace("error searching for extended support") 25 } 26 }) 27 28 return nil 29 } 30 31 func findRhelFeatures(resolver file.Resolver, release *linux.Release) error { 32 if release == nil || release.ID != "rhel" { 33 return nil 34 } 35 contentManifestFiles, err := resolver.FilesByGlob("/root/buildinfo/content_manifests/*.json") 36 if err != nil { 37 return fmt.Errorf("unable to find content manifests: %w", err) 38 } 39 for _, contentManifestFile := range contentManifestFiles { 40 found, err := hasRhelExtendedSupportInContentManifest(resolver, contentManifestFile) 41 if err != nil { 42 return fmt.Errorf("unable to read content manifest from %s: %w", contentManifestFile.String(), err) 43 } 44 if found { 45 release.ExtendedSupport = true 46 break 47 } 48 } 49 return nil 50 } 51 52 func hasRhelExtendedSupportInContentManifest(resolver file.Resolver, contentManifestFile file.Location) (bool, error) { 53 contents, err := resolver.FileContentsByLocation(contentManifestFile) 54 if err != nil { 55 return false, fmt.Errorf("unable to read content manifest from %s: %w", contentManifestFile.String(), err) 56 } 57 defer internal.CloseAndLogError(contents, "content-manifest") 58 59 patterns := []*regexp.Regexp{regexp.MustCompile(`baseos-eus`), regexp.MustCompile(`baseos-eus|appstream-eus`)} 60 return internal.MatchAnyFromReader(contents, patterns...) 61 }