feat: agent parses /etc/os-release for distro identification

This commit is contained in:
2026-08-06 11:55:45 +01:00
parent a22fdf197e
commit bd690c94c3
+63
View File
@@ -0,0 +1,63 @@
package packages
import (
"bufio"
"errors"
"io"
"os"
"runtime"
"strings"
)
// OSRelease identifies the distribution well enough to select an advisory
// feed. VersionID is not optional: Ubuntu 22.04 and 24.04 publish different
// fixed versions for the same CVE.
type OSRelease struct {
Family string
VersionID string
Arch string
}
// ParseOSRelease reads the os-release format: KEY=value, one per line, with
// values optionally quoted, and # comments.
//
// The quote stripping handles both ID=ubuntu and ID="rocky", which real
// distributions both emit.
func ParseOSRelease(r io.Reader) (OSRelease, error) {
out := OSRelease{Arch: runtime.GOARCH}
sc := bufio.NewScanner(r)
for sc.Scan() {
line := strings.TrimSpace(sc.Text())
if line == "" || strings.HasPrefix(line, "#") {
continue
}
key, val, ok := strings.Cut(line, "=")
if !ok {
continue
}
val = strings.Trim(strings.TrimSpace(val), `"'`)
switch strings.TrimSpace(key) {
case "ID":
out.Family = strings.ToLower(val)
case "VERSION_ID":
out.VersionID = val
}
}
if err := sc.Err(); err != nil {
return OSRelease{}, err
}
if out.Family == "" {
return OSRelease{}, errors.New("os-release has no ID")
}
return out, nil
}
// DetectOS reads /etc/os-release.
func DetectOS() (OSRelease, error) {
f, err := os.Open("/etc/os-release")
if err != nil {
return OSRelease{}, err
}
defer f.Close()
return ParseOSRelease(f)
}