From 750b540121f6d6b7b35ec5808ba2d21f83dae707 Mon Sep 17 00:00:00 2001 From: Shirou WAKAYAMA Date: Fri, 16 May 2014 16:37:20 +0900 Subject: [PATCH] add platform information to HostInfo and implements on Linux. Detecting code is ported from Ohai. --- common.go | 9 ++- host.go | 10 ++- host_linux.go | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++ host_test.go | 4 +- 4 files changed, 196 insertions(+), 6 deletions(-) diff --git a/common.go b/common.go index e0395c8..4c41064 100644 --- a/common.go +++ b/common.go @@ -75,8 +75,6 @@ func parseFloat64(val string) float64 { return vv } - - // Check the target string slice containes src or not func stringContains(target []string, src string) bool { for _, t := range target { @@ -109,3 +107,10 @@ func attributes(m interface{}) map[string]reflect.Type { return attrs } + +func pathExists(filename string) bool { + if _, err := os.Stat(filename); err == nil { + return true + } + return false +} diff --git a/host.go b/host.go index cc4be78..beec54a 100644 --- a/host.go +++ b/host.go @@ -7,9 +7,13 @@ import ( // A HostInfoStat describes the host status. // This is not in the psutil but it useful. type HostInfoStat struct { - Hostname string `json:"hostname"` - Uptime int64 `json:"uptime"` - Procs uint64 `json:"procs"` + Hostname string `json:"hostname"` + Uptime int64 `json:"uptime"` + Procs uint64 `json:"procs"` // number of processes + OS string `json:"os"` // ex: freebsd, linux + Platform string `json:"platform"` // ex: ubuntu, linuxmint + PlatformFamily string `json:"platformFamily"` // ex: debian, rhel + PlatformVersion string `json:"platformVersion"` } type UserStat struct { diff --git a/host_linux.go b/host_linux.go index 685e362..1b1a38d 100644 --- a/host_linux.go +++ b/host_linux.go @@ -7,10 +7,20 @@ import ( "encoding/binary" "io/ioutil" "os" + "os/exec" + "runtime" "syscall" "unsafe" + "strings" ) +type LSB struct { + ID string + Release string + Codename string + Description string +} + func HostInfo() (*HostInfoStat, error) { hostname, err := os.Hostname() if err != nil { @@ -19,7 +29,17 @@ func HostInfo() (*HostInfoStat, error) { ret := &HostInfoStat{ Hostname: hostname, + OS: runtime.GOOS, } + + platform, family, version, err := getPlatformInformation() + if err == nil{ + ret.Platform = platform + ret.PlatformFamily = family + ret.PlatformVersion = version + } + + return ret, nil } @@ -71,3 +91,162 @@ func Users() ([]UserStat, error) { return ret, nil } + +func getLSB() (*LSB, error) { + ret := &LSB{} + if pathExists("/etc/lsb-release") { + contents, err := readLines("/etc/lsb-release") + if err != nil { + return ret, err // return empty + } + for _, line := range contents { + field := strings.Split(line, "=") + if len(field) < 2 { + continue + } + switch field[0] { + case "DISTRIB_ID": + ret.ID = field[1] + case "DISTRIB_RELEASE": + ret.Release = field[1] + case "DISTRIB_CODENAME": + ret.Codename = field[1] + case "DISTRIB_DESCRIPTION": + ret.Description = field[1] + } + } + } else if pathExists("/usr/bin/lsb_release") { + out, err := exec.Command("/usr/bin/lsb_release").Output() + if err != nil { + return ret, err + } + for _, line := range strings.Split(string(out), "\n") { + field := strings.Split(line, ":") + if len(field) < 2 { + continue + } + switch field[0] { + case "Distributor ID": + ret.ID = field[1] + case "Release": + ret.Release = field[1] + case "Codename": + ret.Codename = field[1] + case "Description": + ret.Description = field[1] + } + } + + } + + return ret, nil +} + +func getPlatformInformation() (string, string, string, error) { + platform := "" + family := "" + version := "" + + lsb, _ := getLSB() + + if pathExists("/etc/oracle-release") { + platform = "oracle" + contents, err := readLines("/etc/oracle-release") + if err == nil { + version, _ = getRedhatishVersion(contents) + } + } else if pathExists("/etc/enterprise-release") { + platform = "oracle" + contents, err := readLines("/etc/enterprise-release") + if err == nil { + version, _ = getRedhatishVersion(contents) + } + } else if pathExists("/etc/debian_version") { + if lsb.ID == "Ubuntu"{ + platform = "ubuntu" + version = lsb.Release + }else if lsb.ID == "LinuxMint"{ + platform = "linuxmint" + version = lsb.Release + }else{ + if pathExists("/usr/bin/raspi-config"){ + platform = "raspbian" + }else{ + platform = "debian" + } + contents, err := readLines("/etc/debian_version") + if err == nil{ + version = contents[0] + } + } + } else if pathExists("/etc/redhat-release"){ + contents, err := readLines("/etc/redhat-release") + if err == nil { + version, _ = getRedhatishVersion(contents) + platform, _ = getRedhatishPlatform(contents) + } + } else if pathExists("/etc/system-release"){ + contents, err := readLines("/etc/system-release") + if err == nil { + version, _ = getRedhatishVersion(contents) + platform, _ = getRedhatishPlatform(contents) + } + } else if pathExists("/etc/gentoo-release"){ + platform = "gentoo" + contents, err := readLines("/etc/gentoo-release") + if err == nil { + version, _ = getRedhatishVersion(contents) + } + // TODO: suse detection + // TODO: slackware detecion + }else if pathExists("/etc/arch-release"){ + platform = "arch" + // TODO: exherbo detection + }else if lsb.ID == "RedHat"{ + platform = "redhat" + version = lsb.Release + }else if lsb.ID == "Amazon"{ + platform = "amazon" + version = lsb.Release + }else if lsb.ID == "ScientificSL"{ + platform = "scientific" + version = lsb.Release + }else if lsb.ID == "XenServer"{ + platform = "xenserver" + version = lsb.Release + }else if lsb.ID != ""{ + platform = strings.ToLower(lsb.ID) + version = lsb.Release + } + + + switch platform { + case "debian", "ubuntu", "linuxmint", "raspbian": + family = "debian" + case "fedora": + family = "fedora" + case "oracle", "centos", "redhat", "scientific", "enterpriseenterprise", "amazon", "xenserver", "cloudlinux", "ibm_powerkvm": + family = "rhel" + case "suse": + family = "suse" + case "gentoo": + family = "gentoo" + case "slackware": + family = "slackware" + case "arch": + family = "arch" + case "exherbo": + family = "exherbo" + } + + return platform, family, version, nil + +} + +func getRedhatishVersion(contents []string) (string, error) { + return "", nil +} + +func getRedhatishPlatform(contents []string) (string, error) { + return "", nil +} diff --git a/host_test.go b/host_test.go index 8cdf056..6244258 100644 --- a/host_test.go +++ b/host_test.go @@ -44,8 +44,10 @@ func TestHostInfoStat_String(t *testing.T) { Hostname: "test", Uptime: 3000, Procs: 100, + OS: "linux", + Platform: "ubuntu", } - e := `{"hostname":"test","uptime":3000,"procs":100}` + e := `{"hostname":"test","uptime":3000,"procs":100,"os":"linux","platform":"ubuntu","platformFamily":"","platformVersion":""}` if e != fmt.Sprintf("%v", v) { t.Errorf("HostInfoStat string is invalid: %v", v) } -- GitLab