github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/pkg/parsers/operatingsystem/operatingsystem_linux.go (about) 1 // Package operatingsystem provides helper function to get the operating system 2 // name for different platforms. 3 package operatingsystem // import "github.com/demonoid81/moby/pkg/parsers/operatingsystem" 4 5 import ( 6 "bufio" 7 "bytes" 8 "fmt" 9 "io/ioutil" 10 "os" 11 "strings" 12 13 shellwords "github.com/mattn/go-shellwords" 14 ) 15 16 var ( 17 // file to use to detect if the daemon is running in a container 18 proc1Cgroup = "/proc/1/cgroup" 19 20 // file to check to determine Operating System 21 etcOsRelease = "/etc/os-release" 22 23 // used by stateless systems like Clear Linux 24 altOsRelease = "/usr/lib/os-release" 25 ) 26 27 // GetOperatingSystem gets the name of the current operating system. 28 func GetOperatingSystem() (string, error) { 29 if prettyName, err := getValueFromOsRelease("PRETTY_NAME"); err != nil { 30 return "", err 31 } else if prettyName != "" { 32 return prettyName, nil 33 } 34 35 // If not set, defaults to PRETTY_NAME="Linux" 36 // c.f. http://www.freedesktop.org/software/systemd/man/os-release.html 37 return "Linux", nil 38 } 39 40 // GetOperatingSystemVersion gets the version of the current operating system, as a string. 41 func GetOperatingSystemVersion() (string, error) { 42 return getValueFromOsRelease("VERSION_ID") 43 } 44 45 // parses the os-release file and returns the value associated with `key` 46 func getValueFromOsRelease(key string) (string, error) { 47 osReleaseFile, err := os.Open(etcOsRelease) 48 if err != nil { 49 if !os.IsNotExist(err) { 50 return "", fmt.Errorf("Error opening %s: %v", etcOsRelease, err) 51 } 52 osReleaseFile, err = os.Open(altOsRelease) 53 if err != nil { 54 return "", fmt.Errorf("Error opening %s: %v", altOsRelease, err) 55 } 56 } 57 defer osReleaseFile.Close() 58 59 var value string 60 keyWithTrailingEqual := key + "=" 61 scanner := bufio.NewScanner(osReleaseFile) 62 for scanner.Scan() { 63 line := scanner.Text() 64 if strings.HasPrefix(line, keyWithTrailingEqual) { 65 data := strings.SplitN(line, "=", 2) 66 values, err := shellwords.Parse(data[1]) 67 if err != nil { 68 return "", fmt.Errorf("%s is invalid: %s", key, err.Error()) 69 } 70 if len(values) != 1 { 71 return "", fmt.Errorf("%s needs to be enclosed by quotes if they have spaces: %s", key, data[1]) 72 } 73 value = values[0] 74 } 75 } 76 77 return value, nil 78 } 79 80 // IsContainerized returns true if we are running inside a container. 81 func IsContainerized() (bool, error) { 82 b, err := ioutil.ReadFile(proc1Cgroup) 83 if err != nil { 84 return false, err 85 } 86 for _, line := range bytes.Split(b, []byte{'\n'}) { 87 if len(line) > 0 && !bytes.HasSuffix(line, []byte(":/")) && !bytes.HasSuffix(line, []byte(":/init.scope")) { 88 return true, nil 89 } 90 } 91 return false, nil 92 }