syftutil

package
v0.3.241 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 22, 2026 License: Apache-2.0 Imports: 25 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrImageTooLarge = errors.New("image size exceeds maximum allowed size")
)
View Source
var HostExclusionPatterns = []string{
	"./var/lib/containerd/**",
	"./var/lib/docker/**",
	"./var/lib/containers/**",
	"./var/lib/rancher/**",
	"./run/containerd/**",
	"./run/docker/**",
	"./run/crio/**",
	"./proc/**",
	"./sys/**",
	"./dev/**",
}

HostExclusionPatterns are the Syft exclusion globs applied to every host root-filesystem scan.

They cover two distinct concerns:

  1. Container-runtime storage. Without these, a host scan walks every image layer and every container rootfs present on the node, which both explodes the SBOM's size and attributes container packages to the host. The list is deliberately not containerd-only: cri-o/podman store under /var/lib/containers, Docker under /var/lib/docker, and k3s/RKE2 ship an embedded containerd rooted at /var/lib/rancher.
  2. Pseudo-filesystems (/proc, /sys, /dev). These are not real files; walking them can block indefinitely on device nodes and yields nothing useful.

Syft's directory-source exclusion API (directorysource.GetDirectoryExclusionFunctions) requires every pattern to be relative to the scan root and to start with one of "./", "*/" or "**/" -- an absolute pattern such as "/var/lib/containerd/**" is rejected outright with "invalid exclusion pattern(s)". Hence the "./" prefix: these are the host-root-relative spellings of /var/lib/containerd/**, /var/lib/docker/**, /run/containerd/**, /proc/**, /sys/** and /dev/**.

Functions

func NewHostSource added in v0.3.241

func NewHostSource(path, name, version string) (source.Source, error)

NewHostSource builds a Syft directory source rooted at path, for scanning a node's root filesystem (as mounted into the agent via HOST_ROOT).

It is deliberately separate from NewSource: that constructor is entirely image-driven (it unmarshals a CRI imageStatus, validates layer diff-IDs and builds a layer resolver over overlayfs mounts), none of which a host has. The resulting source.Description carries source.DirectoryMetadata and explicitly no ImageMetadata.

The alias name/version is what Syft uses to derive a stable artifact ID, so the ID survives a change of mount point instead of being derived from the path.

func ParallelismFromCPULimitMillis added in v0.3.241

func ParallelismFromCPULimitMillis(raw string) (int, bool)

ParallelismFromCPULimitMillis converts a CPU_LIMIT_MILLIS value -- this container's own declared CPU limit in integer millicores, supplied by the chart via the Kubernetes downward API (resourceFieldRef: {resource: limits.cpu, divisor: "1m"}) -- into a Syft cataloger parallelism. The bool reports whether the raw value was usable; false means the caller must take its serial fallback, and is returned rather than silently folding the fallback in here so the fallback branch itself is directly testable.

The downward API is used deliberately in preference to reading the cgroup CPU quota directly: node-agent bind-mounts the HOST's /sys/fs/cgroup over its own (see pkg/metricsmanager/otel/resource_metrics.go, which had to build container-scope cgroup resolution for exactly this reason), so a naive root-level cgroup read inside that container returns the node's quota, not the container's -- and its failure direction is invisible: it falls back to runtime.NumCPU(), i.e. exactly the unbounded behaviour the cap exists to prevent. resourceFieldRef is resolved by kubelet at pod-admission time from the container's own spec and is immune to that trap entirely. The sbom- scanner sidecar's own cgroup topology would permit a direct read, but it uses the same mechanism so there is one quota-detection code path, not two.

Whole CPUs are used (integer division): 394m -> 0 -> clamped to 1, 1000m -> 1, 2500m -> 2. n==1 is passed to Syft as parallelism 1, which the vendored fork (github.com/kubescape/syft, see go.mod's replace directive) special- cases to mean fully serial, no cataloger goroutines at all -- stronger than "one goroutine". This matters because that fork's default (parallelism 0) is NOT runtime.NumCPU(): syft/create_sbom.go resolves 0 to runtime.NumCPU()*4, so on an 8-CPU node a 394m container would schedule cataloger work across 32 goroutines against a quota of well under half a CPU -- 4x worse than the naive "NumCPU()" story suggests -- and get CFS-throttled hard enough to starve the container's own liveness endpoint.

func ToSyftDocument

func ToSyftDocument(sbomSBOM *sbom.SBOM) v1beta1.SyftDocument

Types

type ImageInfo

type ImageInfo struct {
	ImageSpec imagespec.Image `json:"imageSpec"`
}

type NodeResolver

type NodeResolver struct {
	// contains filtered or unexported fields
}

func NewResolver

func NewResolver(scope source.Scope, layers []imagedigest.Digest, mounts []string) (*NodeResolver, error)

func (NodeResolver) AllLocations

func (n NodeResolver) AllLocations(ctx context.Context) <-chan file.Location

func (NodeResolver) FileContentsByLocation

func (n NodeResolver) FileContentsByLocation(location file.Location) (io.ReadCloser, error)

func (NodeResolver) FileMetadataByLocation

func (n NodeResolver) FileMetadataByLocation(location file.Location) (file.Metadata, error)

func (NodeResolver) FilesByGlob

func (n NodeResolver) FilesByGlob(patterns ...string) ([]file.Location, error)

func (NodeResolver) FilesByMIMEType

func (n NodeResolver) FilesByMIMEType(types ...string) ([]file.Location, error)

func (NodeResolver) FilesByPath

func (n NodeResolver) FilesByPath(paths ...string) ([]file.Location, error)

func (NodeResolver) HasPath

func (n NodeResolver) HasPath(s string) bool

func (NodeResolver) RelativeFileByPath

func (n NodeResolver) RelativeFileByPath(_ file.Location, path string) *file.Location

type NodeSource

type NodeSource struct {
	// contains filtered or unexported fields
}

func NewSource

func NewSource(imageName, imageDigest, imageID string, imageStatus *runtime.ImageStatusResponse, mounts []string, maxImageSize int64) (*NodeSource, error)

func (*NodeSource) Close

func (n *NodeSource) Close() error

func (*NodeSource) Describe

func (n *NodeSource) Describe() source.Description

func (*NodeSource) FileResolver

func (n *NodeSource) FileResolver(scope source.Scope) (file.Resolver, error)

func (*NodeSource) ID

func (n *NodeSource) ID() artifact.ID

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL