Skip to content

Commit

Permalink
linux: Enhance OS version parsing to handle SUSE SP notation (#248)
Browse files Browse the repository at this point in the history
For SUSE linux (any distro that uses ID_LIKE=suse), support parsing versions
that use `SP` notation for Service Packs, such as `15-SP5` meaning (major=15,
minor=5).

This change resolves issues where Minor was incorrectly set to `0` for `SP`-based
versions and ensures compatibility with both SUSE-specific and conventional
version formats.

Test cases added include for both `SLES 15-SP5` and `SLED 15-SP5` to validate
correct assignment of major, minor, and patch values.
  • Loading branch information
sidis-zafran authored Dec 2, 2024
1 parent 91959ac commit 43f710e
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 21 deletions.
3 changes: 3 additions & 0 deletions .changelog/248.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
linux: Support SLES/SLED OS version extraction.
```
51 changes: 30 additions & 21 deletions providers/linux/os.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ import (
)

const (
osRelease = "/etc/os-release"
lsbRelease = "/etc/lsb-release"
distribRelease = "/etc/*-release"
versionGrok = `(?P<version>(?P<major>[0-9]+)\.?(?P<minor>[0-9]+)?\.?(?P<patch>\w+)?)(?: \((?P<codename>[-\w ]+)\))?`
osRelease = "/etc/os-release"
lsbRelease = "/etc/lsb-release"
distribRelease = "/etc/*-release"
versionGrok = `(?P<version>(?P<major>[0-9]+)\.?(?P<minor>[0-9]+)?\.?(?P<patch>\w+)?)(?: \((?P<codename>[-\w ]+)\))?`
versionGrokSuse = `(?P<version>(?P<major>[0-9]+)(?:[.-]?(?:SP)?(?P<minor>[0-9]+))?(?:[.-](?P<patch>[0-9]+|\w+))?)(?: \((?P<codename>[-\w ]+)\))?`
)

var (
Expand All @@ -44,6 +45,9 @@ var (

// versionRegexp parses version numbers (e.g. 6 or 6.1 or 6.1.0 or 6.1.0_20150102).
versionRegexp = regexp.MustCompile(versionGrok)

// versionRegexpSuse parses version numbers for SUSE (e.g. 15-SP1).
versionRegexpSuse = regexp.MustCompile(versionGrokSuse)
)

// familyMap contains a mapping of family -> []platforms.
Expand Down Expand Up @@ -186,28 +190,33 @@ func makeOSInfo(osRelease map[string]string) (*types.OSInfo, error) {
}
}

if os.Version != "" {
// Try parsing info from the version.
keys := versionRegexp.SubexpNames()
for i, m := range versionRegexp.FindStringSubmatch(os.Version) {
switch keys[i] {
case "major":
os.Major, _ = strconv.Atoi(m)
case "minor":
os.Minor, _ = strconv.Atoi(m)
case "patch":
os.Patch, _ = strconv.Atoi(m)
case "codename":
if os.Codename == "" {
os.Codename = m
}
}
}
if osRelease["ID_LIKE"] == "suse" {
extractVersionDetails(os, os.Version, versionRegexpSuse)
} else if os.Version != "" {
extractVersionDetails(os, os.Version, versionRegexp)
}

return os, nil
}

func extractVersionDetails(os *types.OSInfo, version string, re *regexp.Regexp) {
keys := re.SubexpNames()
for i, match := range re.FindStringSubmatch(version) {
switch keys[i] {
case "major":
os.Major, _ = strconv.Atoi(match)
case "minor":
os.Minor, _ = strconv.Atoi(match)
case "patch":
os.Patch, _ = strconv.Atoi(match)
case "codename":
if os.Codename == "" {
os.Codename = match
}
}
}
}

func findDistribRelease(baseDir string) (*types.OSInfo, error) {
matches, err := filepath.Glob(filepath.Join(baseDir, distribRelease))
if err != nil {
Expand Down
32 changes: 32 additions & 0 deletions providers/linux/os_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,4 +418,36 @@ func TestOperatingSystem(t *testing.T) {
}, *os)
t.Logf("%#v", os)
})
t.Run("sles15sp5", func(t *testing.T) {
os, err := getOSInfo("testdata/sles15sp5")
if err != nil {
t.Fatal(err)
}
assert.Equal(t, types.OSInfo{
Type: "linux",
Family: "suse",
Platform: "sles",
Name: "SLES",
Version: "15-SP5",
Major: 15,
Minor: 5,
}, *os)
t.Logf("%#v", os)
})
t.Run("sled15sp5", func(t *testing.T) {
os, err := getOSInfo("testdata/sled15sp5")
if err != nil {
t.Fatal(err)
}
assert.Equal(t, types.OSInfo{
Type: "linux",
Family: "suse",
Platform: "sled",
Name: "SLED",
Version: "15-SP5",
Major: 15,
Minor: 5,
}, *os)
t.Logf("%#v", os)
})
}
9 changes: 9 additions & 0 deletions providers/linux/testdata/sled15sp5/etc/os-release
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
NAME="SLED"
VERSION="15-SP5"
VERSION_ID="15.5"
PRETTY_NAME="SUSE Linux Enterprise Desktop 15 SP5"
ID="sled"
ID_LIKE="suse"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:suse:sled:15:sp5"
DOCUMENTATION_URL="https://documentation.suse.com/"
9 changes: 9 additions & 0 deletions providers/linux/testdata/sles15sp5/etc/os-release
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
NAME="SLES"
VERSION="15-SP5"
VERSION_ID="15.5"
PRETTY_NAME="SUSE Linux Enterprise Server 15 SP5"
ID="sles"
ID_LIKE="suse"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:suse:sles:15:sp5"
DOCUMENTATION_URL="https://documentation.suse.com/"

0 comments on commit 43f710e

Please sign in to comment.