go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/detector/os_release.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package detector 5 6 import ( 7 "io" 8 "regexp" 9 "strconv" 10 "strings" 11 12 "github.com/rs/zerolog/log" 13 "go.mondoo.com/cnquery/providers/os/connection/shared" 14 ) 15 16 func NewOSReleaseDetector(conn shared.Connection) *OSReleaseDetector { 17 return &OSReleaseDetector{ 18 provider: conn, 19 } 20 } 21 22 type OSReleaseDetector struct { 23 provider shared.Connection 24 } 25 26 func (d *OSReleaseDetector) command(command string) (string, error) { 27 cmd, err := d.provider.RunCommand(command) 28 if err != nil { 29 log.Debug().Err(err).Msg("could not execute os release detection command") 30 return "", err 31 } 32 33 content, err := io.ReadAll(cmd.Stdout) 34 if err != nil { 35 return "", err 36 } 37 38 return strings.TrimSpace(string(content)), nil 39 } 40 41 // UNIX helper methods 42 // operating system name 43 func (d *OSReleaseDetector) unames() (string, error) { 44 return d.command("uname -s") 45 } 46 47 // operating system release 48 func (d *OSReleaseDetector) unamer() (string, error) { 49 return d.command("uname -r") 50 } 51 52 // machine hardware name 53 func (d *OSReleaseDetector) unamem() (string, error) { 54 return d.command("uname -m") 55 } 56 57 // osrelease reads /etc/os/release and parses the file 58 // NAME="Ubuntu" 59 // VERSION="16.04.3 LTS (Xenial Xerus)" 60 // ID=ubuntu 61 // ID_LIKE=debian 62 // PRETTY_NAME="Ubuntu 16.04.3 LTS" 63 // VERSION_ID="16.04" 64 // HOME_URL="http://www.ubuntu.com/" 65 // SUPPORT_URL="http://help.ubuntu.com/" 66 // BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" 67 // VERSION_CODENAME=xenial 68 // UBUNTU_CODENAME=xenial 69 func (d *OSReleaseDetector) osrelease() (map[string]string, error) { 70 f, err := d.provider.FileSystem().Open("/etc/os-release") 71 if err != nil { 72 return nil, err 73 } 74 defer f.Close() 75 76 content, err := io.ReadAll(f) 77 if err != nil { 78 return nil, err 79 } 80 81 return ParseOsRelease(string(content)) 82 } 83 84 // lsbconfig reads /etc/lsb-release and parses the file 85 // DISTRIB_ID=Ubuntu 86 // DISTRIB_RELEASE=16.04 87 // DISTRIB_CODENAME=xenial 88 // DISTRIB_DESCRIPTION="Ubuntu 16.04.3 LTS" 89 // lsb release is not the default on newer systems, but can still be used 90 // as a fallback mechanism 91 func (d *OSReleaseDetector) lsbconfig() (map[string]string, error) { 92 f, err := d.provider.FileSystem().Open("/etc/lsb-release") 93 if err != nil { 94 return nil, err 95 } 96 defer f.Close() 97 98 content, err := io.ReadAll(f) 99 if err != nil { 100 return nil, err 101 } 102 103 return ParseLsbRelease(string(content)) 104 } 105 106 // darwin_swversion will call `/usr/bin/sw_vers` to identify the 107 // version of darwin. A common output would be: 108 // ``` 3d master[97c5c29] 109 // ProductName: Mac OS X 110 // ProductVersion: 10.13.2 111 // BuildVersion: 17C88 112 // ```` 113 func (d *OSReleaseDetector) darwin_swversion() (map[string]string, error) { 114 content, err := d.command("/usr/bin/sw_vers") 115 if err != nil { 116 return nil, err 117 } 118 return ParseDarwinRelease(content) 119 } 120 121 // macosSystemVersion is a specifc identifier for the operating system on macos 122 func (d *OSReleaseDetector) macosSystemVersion() (map[string]string, error) { 123 f, err := d.provider.FileSystem().Open("/System/Library/CoreServices/SystemVersion.plist") 124 if err != nil { 125 return nil, err 126 } 127 defer f.Close() 128 129 content, err := io.ReadAll(f) 130 if err != nil { 131 return nil, err 132 } 133 134 return ParseMacOSSystemVersion(string(content)) 135 } 136 137 var majorminor = regexp.MustCompile(`^(\d+)(?:.(\d*)){0,1}(?:.(.*)){0,1}`) 138 139 type ReleaseVersion struct { 140 Major string 141 Minor string 142 Other string 143 } 144 145 func (v ReleaseVersion) MajorAtoi() (int, error) { 146 return strconv.Atoi(v.Major) 147 } 148 149 func ParseOsVersion(v string) ReleaseVersion { 150 m := majorminor.FindStringSubmatch(v) 151 if len(m) == 0 { 152 return ReleaseVersion{Major: v} 153 } 154 155 return ReleaseVersion{Major: m[1], Minor: m[2], Other: m[3]} 156 }