mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-03 02:00:43 +00:00
Merge pull request #289 from weaveworks/fix-host-on-darwin
Fix host on darwin
This commit is contained in:
@@ -37,7 +37,8 @@ test:
|
||||
- cd $SRCDIR; ./bin/lint .
|
||||
- cd $SRCDIR; make client-test
|
||||
- cd $SRCDIR; make static
|
||||
- cd $SRCDIR; make
|
||||
- cd $SRCDIR; rm -f app/app probe/probe; GOOS=darwin make
|
||||
- cd $SRCDIR; rm -f app/app probe/probe; GOOS=linux make
|
||||
- cd $SRCDIR; ./bin/test -slow
|
||||
- cd $SRCDIR/experimental; make
|
||||
post:
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
package host
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -34,7 +31,6 @@ const (
|
||||
var (
|
||||
InterfaceAddrs = net.InterfaceAddrs
|
||||
Now = func() string { return time.Now().UTC().Format(time.RFC3339Nano) }
|
||||
ReadFile = ioutil.ReadFile
|
||||
)
|
||||
|
||||
type reporter struct {
|
||||
@@ -51,27 +47,6 @@ func NewReporter(hostID, hostName string) tag.Reporter {
|
||||
}
|
||||
}
|
||||
|
||||
func getUptime() (time.Duration, error) {
|
||||
var result time.Duration
|
||||
|
||||
buf, err := ReadFile(ProcUptime)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
fields := strings.Fields(string(buf))
|
||||
if len(fields) != 2 {
|
||||
return result, fmt.Errorf("invalid format: %s", string(buf))
|
||||
}
|
||||
|
||||
uptime, err := strconv.ParseFloat(fields[0], 64)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
return time.Duration(uptime) * time.Second, nil
|
||||
}
|
||||
|
||||
func (r *reporter) Report() (report.Report, error) {
|
||||
var (
|
||||
rep = report.MakeReport()
|
||||
@@ -89,12 +64,12 @@ func (r *reporter) Report() (report.Report, error) {
|
||||
}
|
||||
}
|
||||
|
||||
uptime, err := getUptime()
|
||||
uptime, err := GetUptime()
|
||||
if err != nil {
|
||||
return rep, err
|
||||
}
|
||||
|
||||
kernel, err := getKernelVersion()
|
||||
kernel, err := GetKernelVersion()
|
||||
if err != nil {
|
||||
return rep, err
|
||||
}
|
||||
@@ -104,7 +79,7 @@ func (r *reporter) Report() (report.Report, error) {
|
||||
HostName: r.hostName,
|
||||
LocalNetworks: strings.Join(localCIDRs, " "),
|
||||
OS: runtime.GOOS,
|
||||
Load: getLoad(),
|
||||
Load: GetLoad(),
|
||||
KernelVersion: kernel,
|
||||
Uptime: uptime.String(),
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"net"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/weaveworks/scope/probe/host"
|
||||
"github.com/weaveworks/scope/report"
|
||||
@@ -13,13 +13,10 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
procLoad = "0.59 0.36 0.29 1/200 12187"
|
||||
procUptime = "1004143.23 1263220.30"
|
||||
release = "release"
|
||||
version = "version"
|
||||
|
||||
release = "release"
|
||||
version = "version"
|
||||
network = "192.168.0.0/16"
|
||||
hostid = "hostid"
|
||||
hostID = "hostid"
|
||||
now = "now"
|
||||
hostname = "hostname"
|
||||
load = "0.59 0.36 0.29"
|
||||
@@ -27,48 +24,29 @@ const (
|
||||
kernel = "release version"
|
||||
)
|
||||
|
||||
func string2c(s string) [65]int8 {
|
||||
var result [65]int8
|
||||
for i, c := range s {
|
||||
result[i] = int8(c)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func TestReporter(t *testing.T) {
|
||||
oldInterfaceAddrs, oldNow, oldReadFile, oldUname := host.InterfaceAddrs, host.Now, host.ReadFile, host.Uname
|
||||
var (
|
||||
oldGetKernelVersion = host.GetKernelVersion
|
||||
oldGetLoad = host.GetLoad
|
||||
oldGetUptime = host.GetUptime
|
||||
oldInterfaceAddrs = host.InterfaceAddrs
|
||||
oldNow = host.Now
|
||||
)
|
||||
defer func() {
|
||||
host.InterfaceAddrs, host.Now, host.ReadFile, host.Uname = oldInterfaceAddrs, oldNow, oldReadFile, oldUname
|
||||
host.GetKernelVersion = oldGetKernelVersion
|
||||
host.GetLoad = oldGetLoad
|
||||
host.GetUptime = oldGetUptime
|
||||
host.InterfaceAddrs = oldInterfaceAddrs
|
||||
host.Now = oldNow
|
||||
}()
|
||||
|
||||
host.InterfaceAddrs = func() ([]net.Addr, error) {
|
||||
_, ipnet, _ := net.ParseCIDR(network)
|
||||
return []net.Addr{ipnet}, nil
|
||||
}
|
||||
|
||||
host.GetKernelVersion = func() (string, error) { return release + " " + version, nil }
|
||||
host.GetLoad = func() string { return load }
|
||||
host.GetUptime = func() (time.Duration, error) { return time.ParseDuration(uptime) }
|
||||
host.Now = func() string { return now }
|
||||
host.InterfaceAddrs = func() ([]net.Addr, error) { _, ipnet, _ := net.ParseCIDR(network); return []net.Addr{ipnet}, nil }
|
||||
|
||||
host.ReadFile = func(filename string) ([]byte, error) {
|
||||
switch filename {
|
||||
case host.ProcUptime:
|
||||
return []byte(procUptime), nil
|
||||
case host.ProcLoad:
|
||||
return []byte(procLoad), nil
|
||||
default:
|
||||
panic(filename)
|
||||
}
|
||||
}
|
||||
|
||||
host.Uname = func(uts *syscall.Utsname) error {
|
||||
uts.Release = string2c(release)
|
||||
uts.Version = string2c(version)
|
||||
return nil
|
||||
}
|
||||
|
||||
r := host.NewReporter(hostid, hostname)
|
||||
have, _ := r.Report()
|
||||
want := report.MakeReport()
|
||||
want.Host.NodeMetadatas[report.MakeHostNodeID(hostid)] = report.NodeMetadata{
|
||||
want.Host.NodeMetadatas[report.MakeHostNodeID(hostID)] = report.NodeMetadata{
|
||||
host.Timestamp: now,
|
||||
host.HostName: hostname,
|
||||
host.LocalNetworks: network,
|
||||
@@ -77,7 +55,8 @@ func TestReporter(t *testing.T) {
|
||||
host.Uptime: uptime,
|
||||
host.KernelVersion: kernel,
|
||||
}
|
||||
|
||||
r := host.NewReporter(hostID, hostname)
|
||||
have, _ := r.Report()
|
||||
if !reflect.DeepEqual(want, have) {
|
||||
t.Errorf("%s", test.Diff(want, have))
|
||||
}
|
||||
|
||||
@@ -4,15 +4,31 @@ import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
var loadRe = regexp.MustCompile(`load average\: ([0-9\.]+), ([0-9\.]+), ([0-9\.]+)`)
|
||||
var (
|
||||
unameRe = regexp.MustCompile(`Darwin Kernel Version ([0-9\.]+)\:`)
|
||||
loadRe = regexp.MustCompile(`load averages: ([0-9\.]+) ([0-9\.]+) ([0-9\.]+)`)
|
||||
uptimeRe = regexp.MustCompile(`up ([0-9]+) day[s]*,[ ]+([0-9]+)\:([0-9][0-9])`)
|
||||
)
|
||||
|
||||
func getKernelVersion() (string, error) {
|
||||
return "", nil
|
||||
// GetKernelVersion returns the kernel version as reported by uname.
|
||||
var GetKernelVersion = func() (string, error) {
|
||||
out, err := exec.Command("uname", "-v").CombinedOutput()
|
||||
if err != nil {
|
||||
return "Darwin unknown", err
|
||||
}
|
||||
matches := unameRe.FindAllStringSubmatch(string(out), -1)
|
||||
if matches == nil || len(matches) < 1 || len(matches[0]) < 1 {
|
||||
return "Darwin unknown", nil
|
||||
}
|
||||
return fmt.Sprintf("Darwin %s", matches[0][1]), nil
|
||||
}
|
||||
|
||||
func getLoad() string {
|
||||
// GetLoad returns the current load averages in standard form.
|
||||
var GetLoad = func() string {
|
||||
out, err := exec.Command("w").CombinedOutput()
|
||||
if err != nil {
|
||||
return "unknown"
|
||||
@@ -23,3 +39,28 @@ func getLoad() string {
|
||||
}
|
||||
return fmt.Sprintf("%s %s %s", matches[0][1], matches[0][2], matches[0][3])
|
||||
}
|
||||
|
||||
// GetUptime returns the uptime of the host.
|
||||
var GetUptime = func() (time.Duration, error) {
|
||||
out, err := exec.Command("w").CombinedOutput()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
matches := uptimeRe.FindAllStringSubmatch(string(out), -1)
|
||||
if matches == nil || len(matches) < 1 || len(matches[0]) < 4 {
|
||||
return 0, err
|
||||
}
|
||||
d, err := strconv.Atoi(matches[0][1])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
h, err := strconv.Atoi(matches[0][2])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
m, err := strconv.Atoi(matches[0][3])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return (time.Duration(d) * 24 * time.Hour) + (time.Duration(h) * time.Hour) + (time.Duration(m) * time.Minute), nil
|
||||
}
|
||||
|
||||
@@ -2,12 +2,14 @@ package host
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Uname exported for testing
|
||||
// Uname is swappable for mocking in tests.
|
||||
var Uname = syscall.Uname
|
||||
|
||||
func charsToString(ca [65]int8) string {
|
||||
@@ -22,16 +24,18 @@ func charsToString(ca [65]int8) string {
|
||||
return string(s[0:lens])
|
||||
}
|
||||
|
||||
func getKernelVersion() (string, error) {
|
||||
// GetKernelVersion returns the kernel version as reported by uname.
|
||||
var GetKernelVersion = func() (string, error) {
|
||||
var utsname syscall.Utsname
|
||||
if err := Uname(&utsname); err != nil {
|
||||
return "", err
|
||||
return "unknown", err
|
||||
}
|
||||
return fmt.Sprintf("%s %s", charsToString(utsname.Release), charsToString(utsname.Version)), nil
|
||||
}
|
||||
|
||||
func getLoad() string {
|
||||
buf, err := ReadFile(ProcLoad)
|
||||
// GetLoad returns the current load averages in standard form.
|
||||
var GetLoad = func() string {
|
||||
buf, err := ioutil.ReadFile("/proc/loadavg")
|
||||
if err != nil {
|
||||
return "unknown"
|
||||
}
|
||||
@@ -53,3 +57,23 @@ func getLoad() string {
|
||||
}
|
||||
return fmt.Sprintf("%.2f %.2f %.2f", one, five, fifteen)
|
||||
}
|
||||
|
||||
// GetUptime returns the uptime of the host.
|
||||
var GetUptime = func() (time.Duration, error) {
|
||||
buf, err := ioutil.ReadFile("/proc/uptime")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
fields := strings.Fields(string(buf))
|
||||
if len(fields) != 2 {
|
||||
return 0, fmt.Errorf("invalid format: %s", string(buf))
|
||||
}
|
||||
|
||||
uptime, err := strconv.ParseFloat(fields[0], 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return time.Duration(uptime) * time.Second, nil
|
||||
}
|
||||
|
||||
40
probe/host/system_linux_test.go
Normal file
40
probe/host/system_linux_test.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package host_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"github.com/weaveworks/scope/probe/host"
|
||||
)
|
||||
|
||||
func TestUname(t *testing.T) {
|
||||
oldUname := host.Uname
|
||||
defer func() { host.Uname = oldUname }()
|
||||
|
||||
const (
|
||||
release = "rls"
|
||||
version = "ver"
|
||||
)
|
||||
host.Uname = func(uts *syscall.Utsname) error {
|
||||
uts.Release = string2c(release)
|
||||
uts.Version = string2c(version)
|
||||
return nil
|
||||
}
|
||||
|
||||
have, err := host.GetKernelVersion()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if want := fmt.Sprintf("%s %s", release, version); want != have {
|
||||
t.Errorf("want %q, have %q", want, have)
|
||||
}
|
||||
}
|
||||
|
||||
func string2c(s string) [65]int8 {
|
||||
var result [65]int8
|
||||
for i, c := range s {
|
||||
result[i] = int8(c)
|
||||
}
|
||||
return result
|
||||
}
|
||||
38
probe/host/system_test.go
Normal file
38
probe/host/system_test.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package host_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/weaveworks/scope/probe/host"
|
||||
)
|
||||
|
||||
func TestGetKernelVersion(t *testing.T) {
|
||||
have, err := host.GetKernelVersion()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if strings.Contains(have, "unknown") {
|
||||
t.Fatal(have)
|
||||
}
|
||||
t.Log(have)
|
||||
}
|
||||
|
||||
func TestGetLoad(t *testing.T) {
|
||||
have := host.GetLoad()
|
||||
if strings.Contains(have, "unknown") {
|
||||
t.Fatal(have)
|
||||
}
|
||||
t.Log(have)
|
||||
}
|
||||
|
||||
func TestGetUptime(t *testing.T) {
|
||||
have, err := host.GetUptime()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if have == 0 {
|
||||
t.Fatal(have)
|
||||
}
|
||||
t.Log(have.String())
|
||||
}
|
||||
Reference in New Issue
Block a user