syft/syft/pkg/cataloger/nix/cataloger.go
Alex Goodman d47a6c3a6d
Improve support for cataloging nix package relationships (#3837)
* add nix DB cataloger

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add derivation path to nix store pkg metadata

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* go mod tidy

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* allow for derivation path to be optional

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* repin build image and disable syscall filtering

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* bump storage capacity

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* track nix derivation details on packages

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* image fixture should have derivation examples

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* address comments

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2025-05-05 15:35:13 +00:00

58 lines
1.5 KiB
Go

package nix
import (
"context"
"fmt"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/pkg"
)
type Config struct {
CaptureOwnedFiles bool `json:"capture-owned-files" yaml:"capture-owned-files" mapstructure:"capture-owned-files"`
}
func (c Config) WithCaptureOwnedFiles(set bool) Config {
c.CaptureOwnedFiles = set
return c
}
func DefaultConfig() Config {
return Config{
CaptureOwnedFiles: false,
}
}
// cataloger finds package outputs installed in the Nix store location (/nix/store/*) or in the internal nix database (/nix/var/nix/db/db.sqlite).
type cataloger struct {
dbParser dbCataloger
storeCataloger storeCataloger
}
func NewCataloger(cfg Config) pkg.Cataloger {
name := "nix-cataloger"
return cataloger{
dbParser: newDBCataloger(cfg, name),
storeCataloger: newStoreCataloger(cfg, name),
}
}
func (c cataloger) Name() string {
return c.dbParser.catalogerName
}
func (c cataloger) Catalog(ctx context.Context, resolver file.Resolver) ([]pkg.Package, []artifact.Relationship, error) {
// always try the DB cataloger first (based off of information recorded by actions taken by nix tooling)
pkgs, rels, err := c.dbParser.catalog(resolver)
if err != nil {
return nil, nil, fmt.Errorf("failed to catalog nix packages from database: %w", err)
}
if len(pkgs) > 0 {
return pkgs, rels, nil
}
// there are no results from the DB cataloger, then use the store path cataloger (not as accurate / detailed in information)
return c.storeCataloger.Catalog(ctx, resolver)
}