anchore/grype
Distro detection
Active contributors: Alex Goodman, Christopher Phillips
Purpose
Distro detection identifies the Linux distribution, version, and applicable fix channels (e.g. RHEL EUS) for a scanned target. The result drives which distro-specific vulnerability namespace the matchers consult and surfaces in the JSON output.
Directory layout
grype/distro/
├── distro.go # Distro struct + parsing
├── type.go # Type enum + IDMapping (alias of os-release IDs)
├── fix_channel.go # FixChannel + applyChannels
├── testdata/ # canonical os-release fixtures
└── *_test.goThe Distro struct
type Distro struct {
Type Type
Version string // major.minor.patch
Codename string // "fossa", "jammy", ...
Channels []string // e.g. "eus" for RHEL
IDLike []string
// private parts populated in the constructor
major, minor, remaining string
}How it's constructed
There are three constructors in grype/distro/distro.go:
New(t, version, label, idLikes...)— direct construction from a known type.NewFromNameVersion(name, version)— for user-typed strings likealpine:3.20.NewFromRelease(release, channels)— from a Syftlinux.Release(parsed/etc/os-release).
NewFromRelease is the path used during real scans. It picks the best version string from release.VersionID or release.Version, normalizes it through the semantic-format validator, then constructs the Distro with applied fix channels.
Type mapping
type.go::IDMapping is a normalization table from os-release IDs to canonical Grype types:
| os-release ID | Grype Type |
|---|---|
alpine |
Alpine |
debian |
Debian |
ubuntu |
Ubuntu |
rhel, redhat, redhatenterpriselinux |
RedHat |
centos |
CentOS |
oraclelinux |
OracleLinux |
amazonlinux, amzn |
AmazonLinux |
wolfi |
Wolfi |
chainguard |
Chainguard |
mariner, azurelinux |
Mariner / AzureLinux |
opensuse-leap, opensuse-tumbleweed |
OpenSuseLeap, OpenSuseTumbleweed |
| ... | ... (see type.go) |
opensuse-leap special case
ParseDistroString has explicit handling for opensuse-leap because it is the only common ID containing a hyphen. Without the special case, opensuse-leap-15 would be parsed as opensuse + leap-15. See Fun facts.
Fix channels
fix_channel.go::FixChannel represents a label like eus (RHEL Extended Update Support) that opens additional vulnerability data feeds. applyChannels checks the syft linux.Release against configured channels and appends matching channel labels to Distro.Channels.
The downstream effect: when matchers look up vulnerabilities for redhat:8+eus, they get the Extended Update Support feed in addition to the standard one.
Version parsing
parseVersion splits on + (channel separator) and on . to derive major, minor, remaining. The result is exposed via MajorVersion(), MinorVersion(), and RemainingVersion() for matchers that need to range-match against major-only or major+minor windows.
String() returns a human form like redhat 8.5+eus; VersionString() returns just the version-with-channels portion.
Failure mode
If os-release is missing or its ID is not in IDMapping, NewFromRelease returns an error and FromRelease logs a warning but returns nil. The matcher pipeline records this via pkg.Context.DistroDetectionFailed and emits a single warning rather than per-package noise.
Key abstractions
| Symbol | Where | Description |
|---|---|---|
distro.Distro |
grype/distro/distro.go |
The detected distribution. |
distro.Type |
grype/distro/type.go |
Canonical distro identifier enum. |
distro.IDMapping |
grype/distro/type.go |
os-release ID → Type table. |
distro.FixChannel |
grype/distro/fix_channel.go |
A named alternate fix feed (e.g. EUS). |
distro.NewFromRelease |
grype/distro/distro.go |
Construct from a Syft linux.Release. |
distro.ParseDistroString |
grype/distro/distro.go |
Parse user-typed distro:version strings. |
Key source files
| File | Purpose |
|---|---|
grype/distro/distro.go |
The Distro struct and parsing. |
grype/distro/type.go |
Type enum and ID alias mapping. |
grype/distro/fix_channel.go |
Fix-channel application. |
grype/distro/testdata/ |
Canonical os-release fixtures. |
Entry points for modification
- Add a new distro — add a
Typeconstant, register its os-release IDs inIDMapping, and ensure the matcher namespace mapping ingrype/db/v6/name/recognizes it. - Add a new fix channel — extend
FixChanneland add anapplyChannelsrule that maps it fromlinux.Releasedata. - Change parsing — modify
parseVersionandParseDistroString. The opensuse-leap branch is the easiest place to introduce a regression; tests indistro_test.gocover the common cases.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.