git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/sysinfo/os.go (about) 1 // Copyright © 2016 Zlatko Čalušić 2 // 3 // Use of this source code is governed by an MIT-style license that can be found in the LICENSE file. 4 5 package sysinfo 6 7 import ( 8 "bufio" 9 "os" 10 "regexp" 11 "strings" 12 ) 13 14 // OS information. 15 type OS struct { 16 Name string `json:"name,omitempty"` 17 Vendor string `json:"vendor,omitempty"` 18 Version string `json:"version,omitempty"` 19 Release string `json:"release,omitempty"` 20 Architecture string `json:"architecture,omitempty"` 21 } 22 23 var ( 24 rePrettyName = regexp.MustCompile(`^PRETTY_NAME=(.*)$`) 25 reID = regexp.MustCompile(`^ID=(.*)$`) 26 reVersionID = regexp.MustCompile(`^VERSION_ID=(.*)$`) 27 reUbuntu = regexp.MustCompile(`[\( ]([\d\.]+)`) 28 reCentOS = regexp.MustCompile(`^CentOS( Linux)? release ([\d\.]+) `) 29 reRedHat = regexp.MustCompile(`[\( ]([\d\.]+)`) 30 ) 31 32 func (si *SysInfo) getOSInfo() { 33 // This seems to be the best and most portable way to detect OS architecture (NOT kernel!) 34 if _, err := os.Stat("/lib64/ld-linux-x86-64.so.2"); err == nil { 35 si.OS.Architecture = "amd64" 36 } else if _, err := os.Stat("/lib/ld-linux.so.2"); err == nil { 37 si.OS.Architecture = "i386" 38 } 39 40 f, err := os.Open("/etc/os-release") 41 if err != nil { 42 return 43 } 44 defer f.Close() 45 46 s := bufio.NewScanner(f) 47 for s.Scan() { 48 if m := rePrettyName.FindStringSubmatch(s.Text()); m != nil { 49 si.OS.Name = strings.Trim(m[1], `"`) 50 } else if m := reID.FindStringSubmatch(s.Text()); m != nil { 51 si.OS.Vendor = strings.Trim(m[1], `"`) 52 } else if m := reVersionID.FindStringSubmatch(s.Text()); m != nil { 53 si.OS.Version = strings.Trim(m[1], `"`) 54 } 55 } 56 57 switch si.OS.Vendor { 58 case "debian": 59 si.OS.Release = slurpFile("/etc/debian_version") 60 case "ubuntu": 61 if m := reUbuntu.FindStringSubmatch(si.OS.Name); m != nil { 62 si.OS.Release = m[1] 63 } 64 case "centos": 65 if release := slurpFile("/etc/centos-release"); release != "" { 66 if m := reCentOS.FindStringSubmatch(release); m != nil { 67 si.OS.Release = m[2] 68 } 69 } 70 case "rhel": 71 if release := slurpFile("/etc/redhat-release"); release != "" { 72 if m := reRedHat.FindStringSubmatch(release); m != nil { 73 si.OS.Release = m[1] 74 } 75 } 76 if si.OS.Release == "" { 77 if m := reRedHat.FindStringSubmatch(si.OS.Name); m != nil { 78 si.OS.Release = m[1] 79 } 80 } 81 } 82 }