diff --git a/.changelog/248.txt b/.changelog/248.txt new file mode 100644 index 0000000..5dd3c3d --- /dev/null +++ b/.changelog/248.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +linux: Support SLES/SLED OS version extraction. +``` diff --git a/providers/linux/os.go b/providers/linux/os.go index ece0f37..f2e366a 100644 --- a/providers/linux/os.go +++ b/providers/linux/os.go @@ -32,10 +32,11 @@ import ( ) const ( - osRelease = "/etc/os-release" - lsbRelease = "/etc/lsb-release" - distribRelease = "/etc/*-release" - versionGrok = `(?P(?P[0-9]+)\.?(?P[0-9]+)?\.?(?P\w+)?)(?: \((?P[-\w ]+)\))?` + osRelease = "/etc/os-release" + lsbRelease = "/etc/lsb-release" + distribRelease = "/etc/*-release" + versionGrok = `(?P(?P[0-9]+)\.?(?P[0-9]+)?\.?(?P\w+)?)(?: \((?P[-\w ]+)\))?` + versionGrokSuse = `(?P(?P[0-9]+)(?:[.-]?(?:SP)?(?P[0-9]+))?(?:[.-](?P[0-9]+|\w+))?)(?: \((?P[-\w ]+)\))?` ) var ( @@ -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. @@ -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 { diff --git a/providers/linux/os_test.go b/providers/linux/os_test.go index 7f3f677..e780886 100644 --- a/providers/linux/os_test.go +++ b/providers/linux/os_test.go @@ -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) + }) } diff --git a/providers/linux/testdata/sled15sp5/etc/os-release b/providers/linux/testdata/sled15sp5/etc/os-release new file mode 100644 index 0000000..84cea18 --- /dev/null +++ b/providers/linux/testdata/sled15sp5/etc/os-release @@ -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/" diff --git a/providers/linux/testdata/sles15sp5/etc/os-release b/providers/linux/testdata/sles15sp5/etc/os-release new file mode 100644 index 0000000..1d867e3 --- /dev/null +++ b/providers/linux/testdata/sles15sp5/etc/os-release @@ -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/"