github.com/shiroyuki/docker@v1.9.0/pkg/parsers/kernel/kernel.go (about) 1 // +build !windows 2 3 // Package kernel provides helper function to get, parse and compare kernel 4 // versions for different platforms. 5 package kernel 6 7 import ( 8 "bytes" 9 "errors" 10 "fmt" 11 ) 12 13 // VersionInfo holds information about the kernel. 14 type VersionInfo struct { 15 Kernel int // Version of the kernel (e.g. 4.1.2-generic -> 4) 16 Major int // Major part of the kernel version (e.g. 4.1.2-generic -> 1) 17 Minor int // Minor part of the kernel version (e.g. 4.1.2-generic -> 2) 18 Flavor string // Flavor of the kernel version (e.g. 4.1.2-generic -> generic) 19 } 20 21 func (k *VersionInfo) String() string { 22 return fmt.Sprintf("%d.%d.%d%s", k.Kernel, k.Major, k.Minor, k.Flavor) 23 } 24 25 // CompareKernelVersion compares two kernel.VersionInfo structs. 26 // Returns -1 if a < b, 0 if a == b, 1 it a > b 27 func CompareKernelVersion(a, b VersionInfo) int { 28 if a.Kernel < b.Kernel { 29 return -1 30 } else if a.Kernel > b.Kernel { 31 return 1 32 } 33 34 if a.Major < b.Major { 35 return -1 36 } else if a.Major > b.Major { 37 return 1 38 } 39 40 if a.Minor < b.Minor { 41 return -1 42 } else if a.Minor > b.Minor { 43 return 1 44 } 45 46 return 0 47 } 48 49 // GetKernelVersion gets the current kernel version. 50 func GetKernelVersion() (*VersionInfo, error) { 51 var ( 52 err error 53 ) 54 55 uts, err := uname() 56 if err != nil { 57 return nil, err 58 } 59 60 release := make([]byte, len(uts.Release)) 61 62 i := 0 63 for _, c := range uts.Release { 64 release[i] = byte(c) 65 i++ 66 } 67 68 // Remove the \x00 from the release for Atoi to parse correctly 69 release = release[:bytes.IndexByte(release, 0)] 70 71 return ParseRelease(string(release)) 72 } 73 74 // ParseRelease parses a string and creates a VersionInfo based on it. 75 func ParseRelease(release string) (*VersionInfo, error) { 76 var ( 77 kernel, major, minor, parsed int 78 flavor, partial string 79 ) 80 81 // Ignore error from Sscanf to allow an empty flavor. Instead, just 82 // make sure we got all the version numbers. 83 parsed, _ = fmt.Sscanf(release, "%d.%d%s", &kernel, &major, &partial) 84 if parsed < 2 { 85 return nil, errors.New("Can't parse kernel version " + release) 86 } 87 88 // sometimes we have 3.12.25-gentoo, but sometimes we just have 3.12-1-amd64 89 parsed, _ = fmt.Sscanf(partial, ".%d%s", &minor, &flavor) 90 if parsed < 1 { 91 flavor = partial 92 } 93 94 return &VersionInfo{ 95 Kernel: kernel, 96 Major: major, 97 Minor: minor, 98 Flavor: flavor, 99 }, nil 100 }