Open-Source Wikis

/

Grype

/

Systems

/

Distro detection

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.go

The 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 like alpine:3.20.
  • NewFromRelease(release, channels) — from a Syft linux.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 Type constant, register its os-release IDs in IDMapping, and ensure the matcher namespace mapping in grype/db/v6/name/ recognizes it.
  • Add a new fix channel — extend FixChannel and add an applyChannels rule that maps it from linux.Release data.
  • Change parsing — modify parseVersion and ParseDistroString. The opensuse-leap branch is the easiest place to introduce a regression; tests in distro_test.go cover the common cases.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Distro detection – Grype wiki | Factory