Documentation
¶
Index ¶
- Variables
- func NewHostSource(path, name, version string) (source.Source, error)
- func ParallelismFromCPULimitMillis(raw string) (int, bool)
- func ToSyftDocument(sbomSBOM *sbom.SBOM) v1beta1.SyftDocument
- type ImageInfo
- type NodeResolver
- func (n NodeResolver) AllLocations(ctx context.Context) <-chan file.Location
- func (n NodeResolver) FileContentsByLocation(location file.Location) (io.ReadCloser, error)
- func (n NodeResolver) FileMetadataByLocation(location file.Location) (file.Metadata, error)
- func (n NodeResolver) FilesByGlob(patterns ...string) ([]file.Location, error)
- func (n NodeResolver) FilesByMIMEType(types ...string) ([]file.Location, error)
- func (n NodeResolver) FilesByPath(paths ...string) ([]file.Location, error)
- func (n NodeResolver) HasPath(s string) bool
- func (n NodeResolver) RelativeFileByPath(_ file.Location, path string) *file.Location
- type NodeSource
Constants ¶
This section is empty.
Variables ¶
var (
ErrImageTooLarge = errors.New("image size exceeds maximum allowed size")
)
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:
- 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.
- 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
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
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 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 (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 ¶
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 (*NodeSource) ID ¶
func (n *NodeSource) ID() artifact.ID