Support RPM distros with newer RPM db formats (#1018)

* Support RPM distros with newer db formats

Recent RPM distros (Fedora 33+, CBL-Mariner 2.0+, amazonlinux 2022+)
use an sqlite package database in /var/lib/rpm/rpmdb.sqlite, or
"ndb" format (SUSE).

Remove anchore's fork in favour of the upstream,
https://github.com/knqyf263/go-rpmdb, to gain support for
these formats.

Signed-off-by: Tom Fay <tomfay@microsoft.com>

* add exception for modernc.org repos

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* shorten rpmdb helper function

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

Co-authored-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Tom Fay
2022-05-31 17:25:22 -04:00
committed by GitHub
co-authored by Alex Goodman
parent 6ccd460e59
commit 3db3efacdc
7 changed files with 257 additions and 36 deletions
+47 -31
View File
@@ -6,13 +6,12 @@ import (
"io/ioutil"
"os"
"github.com/anchore/syft/syft/file"
rpmdb "github.com/anchore/go-rpmdb/pkg"
"github.com/anchore/syft/internal"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/source"
rpmdb "github.com/knqyf263/go-rpmdb/pkg"
)
// parseApkDb parses an "Packages" RPM DB and returns the Packages listed within it.
@@ -47,37 +46,49 @@ func parseRpmDB(resolver source.FilePathResolver, dbLocation source.Location, re
allPkgs := make([]pkg.Package, 0)
for _, entry := range pkgList {
metadata := pkg.RpmdbMetadata{
Name: entry.Name,
Version: entry.Version,
Epoch: entry.Epoch,
Arch: entry.Arch,
Release: entry.Release,
SourceRpm: entry.SourceRpm,
Vendor: entry.Vendor,
License: entry.License,
Size: entry.Size,
Files: extractRpmdbFileRecords(resolver, entry),
p, err := newPkg(resolver, dbLocation, entry)
if err != nil {
return nil, err
}
p := pkg.Package{
Name: entry.Name,
Version: toELVersion(metadata),
Locations: source.NewLocationSet(dbLocation),
FoundBy: catalogerName,
Type: pkg.RpmPkg,
MetadataType: pkg.RpmdbMetadataType,
Metadata: metadata,
}
p.SetID()
allPkgs = append(allPkgs, p)
allPkgs = append(allPkgs, *p)
}
return allPkgs, nil
}
func newPkg(resolver source.FilePathResolver, dbLocation source.Location, entry *rpmdb.PackageInfo) (*pkg.Package, error) {
fileRecords, err := extractRpmdbFileRecords(resolver, entry)
if err != nil {
return nil, err
}
metadata := pkg.RpmdbMetadata{
Name: entry.Name,
Version: entry.Version,
Epoch: entry.Epoch,
Arch: entry.Arch,
Release: entry.Release,
SourceRpm: entry.SourceRpm,
Vendor: entry.Vendor,
License: entry.License,
Size: entry.Size,
Files: fileRecords,
}
p := pkg.Package{
Name: entry.Name,
Version: toELVersion(metadata),
Locations: source.NewLocationSet(dbLocation),
FoundBy: catalogerName,
Type: pkg.RpmPkg,
MetadataType: pkg.RpmdbMetadataType,
Metadata: metadata,
}
p.SetID()
return &p, nil
}
// The RPM naming scheme is [name]-[version]-[release]-[arch], where version is implicitly expands to [epoch]:[version].
// RPM version comparison depends on comparing at least the version and release fields together as a subset of the
// naming scheme. This toELVersion function takes a RPM DB package information and converts it into a minimally comparable
@@ -91,10 +102,15 @@ func toELVersion(metadata pkg.RpmdbMetadata) string {
return fmt.Sprintf("%s-%s", metadata.Version, metadata.Release)
}
func extractRpmdbFileRecords(resolver source.FilePathResolver, entry *rpmdb.PackageInfo) []pkg.RpmdbFileRecord {
func extractRpmdbFileRecords(resolver source.FilePathResolver, entry *rpmdb.PackageInfo) ([]pkg.RpmdbFileRecord, error) {
var records = make([]pkg.RpmdbFileRecord, 0)
for _, record := range entry.Files {
files, err := entry.InstalledFiles()
if err != nil {
return nil, err
}
for _, record := range files {
// only persist RPMDB file records which exist in the image/directory, otherwise ignore them
if resolver.HasPath(record.Path) {
records = append(records, pkg.RpmdbFileRecord{
@@ -111,5 +127,5 @@ func extractRpmdbFileRecords(resolver source.FilePathResolver, entry *rpmdb.Pack
})
}
}
return records
return records, nil
}
+4 -1
View File
@@ -11,7 +11,10 @@ import (
"github.com/scylladb/go-set/strset"
)
const RpmDBGlob = "**/var/lib/rpm/Packages"
// Packages is the legacy Berkely db based format
// Packages.db is the "ndb" format used in SUSE
// rpmdb.sqlite is the sqlite format used in fedora + derivates
const RpmDBGlob = "**/var/lib/rpm/{Packages,Packages.db,rpmdb.sqlite}"
var (
_ FileOwner = (*RpmdbMetadata)(nil)