github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/version/osversion.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package version 5 6 import ( 7 "fmt" 8 "io/ioutil" 9 "strconv" 10 "strings" 11 12 "github.com/juju/errors" 13 "github.com/juju/loggo" 14 ) 15 16 var logger = loggo.GetLogger("juju.version") 17 18 // mustOSVersion will panic if the osVersion is "unknown" due 19 // to an error. 20 // 21 // If you want to avoid the panic, call osVersion and handle 22 // the error. 23 func mustOSVersion() string { 24 version, err := osVersion() 25 if err != nil { 26 panic("osVersion reported an error: " + err.Error()) 27 } 28 return version 29 } 30 31 // MustOSFromSeries will panic if the series represents an "unknown" 32 // operating system 33 func MustOSFromSeries(series string) OSType { 34 operatingSystem, err := GetOSFromSeries(series) 35 if err != nil { 36 panic("osVersion reported an error: " + err.Error()) 37 } 38 return operatingSystem 39 } 40 41 func readOSRelease() (map[string]string, error) { 42 values := map[string]string{} 43 44 contents, err := ioutil.ReadFile(osReleaseFile) 45 if err != nil { 46 return values, err 47 } 48 releaseDetails := strings.Split(string(contents), "\n") 49 for _, val := range releaseDetails { 50 c := strings.SplitN(val, "=", 2) 51 if len(c) != 2 { 52 continue 53 } 54 values[c[0]] = strings.Trim(c[1], "\t '\"") 55 } 56 _, ok := values["ID"] 57 if !ok { 58 return values, errors.New("OS release file is missing ID") 59 } 60 _, ok = values["VERSION_ID"] 61 if !ok { 62 return values, errors.New("OS release file is missing VERSION_ID") 63 } 64 return values, nil 65 } 66 67 func getValue(from map[string]string, val string) (string, error) { 68 for serie, ver := range from { 69 if ver == val { 70 return serie, nil 71 } 72 } 73 return "unknown", errors.New("Could not determine series") 74 } 75 76 func readSeries() (string, error) { 77 values, err := readOSRelease() 78 if err != nil { 79 return "unknown", err 80 } 81 updateSeriesVersions() 82 switch values["ID"] { 83 case strings.ToLower(Ubuntu.String()): 84 return getValue(ubuntuSeries, values["VERSION_ID"]) 85 case strings.ToLower(CentOS.String()): 86 codename := fmt.Sprintf("%s%s", values["ID"], values["VERSION_ID"]) 87 return getValue(centosSeries, codename) 88 default: 89 return "unknown", nil 90 } 91 } 92 93 // kernelToMajor takes a dotted version and returns just the Major portion 94 func kernelToMajor(getKernelVersion func() (string, error)) (int, error) { 95 fullVersion, err := getKernelVersion() 96 if err != nil { 97 return 0, err 98 } 99 parts := strings.SplitN(fullVersion, ".", 2) 100 majorVersion, err := strconv.ParseInt(parts[0], 10, 32) 101 if err != nil { 102 return 0, err 103 } 104 return int(majorVersion), nil 105 } 106 107 func macOSXSeriesFromKernelVersion(getKernelVersion func() (string, error)) (string, error) { 108 majorVersion, err := kernelToMajor(getKernelVersion) 109 if err != nil { 110 logger.Infof("unable to determine OS version: %v", err) 111 return "unknown", err 112 } 113 return macOSXSeriesFromMajorVersion(majorVersion) 114 } 115 116 // TODO(jam): 2014-05-06 https://launchpad.net/bugs/1316593 117 // we should have a system file that we can read so this can be updated without 118 // recompiling Juju. For now, this is a lot easier, and also solves the fact 119 // that we want to populate version.Current.Series during init() time, before 120 // we've potentially read that information from anywhere else 121 // macOSXSeries maps from the Darwin Kernel Major Version to the Mac OSX 122 // series. 123 var macOSXSeries = map[int]string{ 124 14: "yosemite", 125 13: "mavericks", 126 12: "mountainlion", 127 11: "lion", 128 10: "snowleopard", 129 9: "leopard", 130 8: "tiger", 131 7: "panther", 132 6: "jaguar", 133 5: "puma", 134 } 135 136 func macOSXSeriesFromMajorVersion(majorVersion int) (string, error) { 137 series, ok := macOSXSeries[majorVersion] 138 if !ok { 139 return "unknown", errors.Errorf("unknown series %q", series) 140 } 141 return series, nil 142 }