syft/syft/pkg/rpmdb_metadata.go
2022-02-09 14:11:20 -05:00

96 lines
2.6 KiB
Go

package pkg
import (
"fmt"
"sort"
"strconv"
"github.com/anchore/syft/syft/file"
"github.com/scylladb/go-set/strset"
"github.com/anchore/packageurl-go"
"github.com/anchore/syft/syft/linux"
)
const RpmDBGlob = "**/var/lib/rpm/Packages"
var (
_ FileOwner = (*RpmdbMetadata)(nil)
_ urlIdentifier = (*RpmdbMetadata)(nil)
)
// RpmdbMetadata represents all captured data for a RPM DB package entry.
type RpmdbMetadata struct {
Name string `json:"name"`
Version string `json:"version"`
Epoch *int `json:"epoch" cyclonedx:"epoch"`
Arch string `json:"architecture"`
Release string `json:"release" cyclonedx:"release"`
SourceRpm string `json:"sourceRpm" cyclonedx:"sourceRpm"`
Size int `json:"size" cyclonedx:"size"`
License string `json:"license"`
Vendor string `json:"vendor"`
Files []RpmdbFileRecord `json:"files"`
}
// RpmdbFileRecord represents the file metadata for a single file attributed to a RPM package.
type RpmdbFileRecord struct {
Path string `json:"path"`
Mode RpmdbFileMode `json:"mode"`
Size int `json:"size"`
Digest file.Digest `json:"digest"`
UserName string `json:"userName"`
GroupName string `json:"groupName"`
Flags string `json:"flags"`
}
// RpmdbFileMode is the raw file mode for a single file. This can be interpreted as the linux stat.h mode (see https://pubs.opengroup.org/onlinepubs/007908799/xsh/sysstat.h.html)
type RpmdbFileMode uint16
// PackageURL returns the PURL for the specific RHEL package (see https://github.com/package-url/purl-spec)
func (m RpmdbMetadata) PackageURL(distro *linux.Release) string {
var namespace string
if distro != nil {
namespace = distro.ID
}
qualifiers := map[string]string{
PURLQualifierArch: m.Arch,
}
if m.Epoch != nil {
qualifiers[PURLQualifierEpoch] = strconv.Itoa(*m.Epoch)
}
if m.SourceRpm != "" {
qualifiers[PURLQualifierUpstream] = m.SourceRpm
}
return packageurl.NewPackageURL(
packageurl.TypeRPM,
namespace,
m.Name,
// for purl the epoch is a qualifier, not part of the version
// see https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst under the RPM section
fmt.Sprintf("%s-%s", m.Version, m.Release),
purlQualifiers(
qualifiers,
distro,
),
"",
).ToString()
}
func (m RpmdbMetadata) OwnedFiles() (result []string) {
s := strset.New()
for _, f := range m.Files {
if f.Path != "" {
s.Add(f.Path)
}
}
result = s.List()
sort.Strings(result)
return result
}