123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- // +build !windows
- // Package kernel provides helper function to get, parse and compare kernel
- // versions for different platforms.
- package kernel
- import (
- "bytes"
- "errors"
- "fmt"
- )
- // VersionInfo holds information about the kernel.
- type VersionInfo struct {
- Kernel int // Version of the kernel (e.g. 4.1.2-generic -> 4)
- Major int // Major part of the kernel version (e.g. 4.1.2-generic -> 1)
- Minor int // Minor part of the kernel version (e.g. 4.1.2-generic -> 2)
- Flavor string // Flavor of the kernel version (e.g. 4.1.2-generic -> generic)
- }
- func (k *VersionInfo) String() string {
- return fmt.Sprintf("%d.%d.%d%s", k.Kernel, k.Major, k.Minor, k.Flavor)
- }
- // CompareKernelVersion compares two kernel.VersionInfo structs.
- // Returns -1 if a < b, 0 if a == b, 1 it a > b
- func CompareKernelVersion(a, b VersionInfo) int {
- if a.Kernel < b.Kernel {
- return -1
- } else if a.Kernel > b.Kernel {
- return 1
- }
- if a.Major < b.Major {
- return -1
- } else if a.Major > b.Major {
- return 1
- }
- if a.Minor < b.Minor {
- return -1
- } else if a.Minor > b.Minor {
- return 1
- }
- return 0
- }
- // GetKernelVersion gets the current kernel version.
- func GetKernelVersion() (*VersionInfo, error) {
- var (
- err error
- )
- uts, err := uname()
- if err != nil {
- return nil, err
- }
- release := make([]byte, len(uts.Release))
- i := 0
- for _, c := range uts.Release {
- release[i] = byte(c)
- i++
- }
- // Remove the \x00 from the release for Atoi to parse correctly
- release = release[:bytes.IndexByte(release, 0)]
- return ParseRelease(string(release))
- }
- // ParseRelease parses a string and creates a VersionInfo based on it.
- func ParseRelease(release string) (*VersionInfo, error) {
- var (
- kernel, major, minor, parsed int
- flavor, partial string
- )
- // Ignore error from Sscanf to allow an empty flavor. Instead, just
- // make sure we got all the version numbers.
- parsed, _ = fmt.Sscanf(release, "%d.%d%s", &kernel, &major, &partial)
- if parsed < 2 {
- return nil, errors.New("Can't parse kernel version " + release)
- }
- // sometimes we have 3.12.25-gentoo, but sometimes we just have 3.12-1-amd64
- parsed, _ = fmt.Sscanf(partial, ".%d%s", &minor, &flavor)
- if parsed < 1 {
- flavor = partial
- }
- return &VersionInfo{
- Kernel: kernel,
- Major: major,
- Minor: minor,
- Flavor: flavor,
- }, nil
- }
|