Skip to content

Commit

Permalink
Extract all dpkg packages regardless of the Status field and store th…
Browse files Browse the repository at this point in the history
…e value of Status in the metadata.

PiperOrigin-RevId: 630407306
  • Loading branch information
Yousef Alowayed authored and copybara-github committed May 6, 2024
1 parent b8652d0 commit 7ab2c1e
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 5 deletions.
1 change: 1 addition & 0 deletions binary/proto/proto.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ func setProtoMetadata(meta any, i *spb.Inventory) {
DpkgMetadata: &spb.DPKGPackageMetadata{
PackageName: m.PackageName,
SourceName: m.SourceName,
Status: m.Status,
SourceVersion: m.SourceVersion,
PackageVersion: m.PackageVersion,
OsId: m.OSID,
Expand Down
2 changes: 2 additions & 0 deletions binary/proto/scan_result.proto
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ message APKPackageMetadata {
}

// The additional data found in DPKG packages.
// Next ID: 11
message DPKGPackageMetadata {
string package_name = 1;
string source_name = 2;
Expand All @@ -210,6 +211,7 @@ message DPKGPackageMetadata {
string os_version_id = 7;
string maintainer = 8;
string architecture = 9;
string status = 10;
}

// The additional data found in RPM packages.
Expand Down
32 changes: 28 additions & 4 deletions extractor/os/dpkg/extractor.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,33 @@ const (
// defaultMaxFileSize is the maximum file size an extractor will unmarshal.
// If Extract gets a bigger file, it will return an error.
defaultMaxFileSize = 100 * units.MiB

// defaultIncludeNotInstalled is the default value for the IncludeNotInstalled option.
defaultIncludeNotInstalled = false
)

// Config is the configuration for the Extractor.
type Config struct {
// MaxFileSize is the maximum file size an extractor will unmarshal.
// If Extract gets a bigger file, it will return an error.
MaxFileSize int64
// IncludeNotInstalled includes packages that are not installed
// (e.g. `deinstall`, `purge`, and those missing a status field).
IncludeNotInstalled bool
}

// DefaultConfig returns the default configuration for the DPKG extractor.
func DefaultConfig() Config {
return Config{
MaxFileSize: defaultMaxFileSize,
MaxFileSize: defaultMaxFileSize,
IncludeNotInstalled: defaultIncludeNotInstalled,
}
}

// Extractor extracts packages from DPKG files.
type Extractor struct {
maxFileSize int64
maxFileSize int64
includeNotInstalled bool
}

// New returns a DPKG extractor.
Expand All @@ -69,7 +77,16 @@ type Extractor struct {
// ```
func New(cfg Config) *Extractor {
return &Extractor{
maxFileSize: cfg.MaxFileSize,
maxFileSize: cfg.MaxFileSize,
includeNotInstalled: cfg.IncludeNotInstalled,
}
}

// Config returns the configuration of the extractor.
func (e Extractor) Config() Config {
return Config{
MaxFileSize: e.maxFileSize,
IncludeNotInstalled: e.includeNotInstalled,
}
}

Expand Down Expand Up @@ -125,9 +142,14 @@ func (e Extractor) Extract(ctx context.Context, input *extractor.ScanInput) ([]*
return pkgs, err
}
}

// Distroless distributions have their packages in status.d, which does not contain the Status
// value.
if !strings.Contains(input.Path, "status.d") || h.Get("Status") != "" {
if !e.includeNotInstalled && (!strings.Contains(input.Path, "status.d") || h.Get("Status") != "") {
if h.Get("Status") == "" {
log.Warnf("Package %q has no status field", h.Get("Package"))
continue
}
installed, err := statusInstalled(h.Get("Status"))
if err != nil {
return pkgs, fmt.Errorf("statusInstalled(%q): %w", h.Get("Status"), err)
Expand All @@ -136,6 +158,7 @@ func (e Extractor) Extract(ctx context.Context, input *extractor.ScanInput) ([]*
continue
}
}

pkgName := h.Get("Package")
pkgVersion := h.Get("Version")
if pkgName == "" || pkgVersion == "" {
Expand All @@ -153,6 +176,7 @@ func (e Extractor) Extract(ctx context.Context, input *extractor.ScanInput) ([]*
Metadata: &Metadata{
PackageName: pkgName,
PackageVersion: pkgVersion,
Status: h.Get("Status"),
OSID: m["ID"],
OSVersionCodename: m["VERSION_CODENAME"],
OSVersionID: m["VERSION_ID"],
Expand Down
Loading

0 comments on commit 7ab2c1e

Please sign in to comment.