add platform information to HostInfo and implements on Linux.

Detecting code is ported from Ohai.
This commit is contained in:
Shirou WAKAYAMA 2014-05-16 16:37:20 +09:00
parent e04ef118ca
commit 750b540121
4 changed files with 196 additions and 6 deletions

View File

@ -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
}

10
host.go
View File

@ -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 {

View File

@ -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
}

View File

@ -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)
}