mirror of https://github.com/status-im/consul.git
Merge pull request #2691 from hashicorp/f-gopsutil
Adds gopsutil in the loop when trying to make the node ID.
This commit is contained in:
commit
631e99ca2c
|
@ -27,6 +27,7 @@ import (
|
||||||
"github.com/hashicorp/go-uuid"
|
"github.com/hashicorp/go-uuid"
|
||||||
"github.com/hashicorp/serf/coordinate"
|
"github.com/hashicorp/serf/coordinate"
|
||||||
"github.com/hashicorp/serf/serf"
|
"github.com/hashicorp/serf/serf"
|
||||||
|
"github.com/shirou/gopsutil/host"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -593,7 +594,45 @@ func (a *Agent) setupClient() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// setupNodeID will pull the persisted node ID, if any, or create a random one
|
// makeRandomID will generate a random UUID for a node.
|
||||||
|
func (a *Agent) makeRandomID() (string, error) {
|
||||||
|
id, err := uuid.GenerateUUID()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
a.logger.Printf("[DEBUG] Using random ID %q as node ID", id)
|
||||||
|
return id, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// makeNodeID will try to find a host-specific ID, or else will generate a
|
||||||
|
// random ID. The returned ID will always be formatted as a GUID. We don't
|
||||||
|
// tell the caller whether this ID is random or stable since the consequences
|
||||||
|
// are high for us if this changes, so we will persist it either way. This will
|
||||||
|
// let gopsutil change implementations without affecting in-place upgrades of
|
||||||
|
// nodes.
|
||||||
|
func (a *Agent) makeNodeID() (string, error) {
|
||||||
|
// Try to get a stable ID associated with the host itself.
|
||||||
|
info, err := host.Info()
|
||||||
|
if err != nil {
|
||||||
|
a.logger.Printf("[DEBUG] Couldn't get a unique ID from the host: %v", err)
|
||||||
|
return a.makeRandomID()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the host ID parses as a UUID, since we don't have complete
|
||||||
|
// control over this process.
|
||||||
|
id := strings.ToLower(info.HostID)
|
||||||
|
if _, err := uuid.ParseUUID(id); err != nil {
|
||||||
|
a.logger.Printf("[DEBUG] Unique ID %q from host isn't formatted as a UUID: %v",
|
||||||
|
id, err)
|
||||||
|
return a.makeRandomID()
|
||||||
|
}
|
||||||
|
|
||||||
|
a.logger.Printf("[DEBUG] Using unique ID %q from host as node ID", id)
|
||||||
|
return id, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// setupNodeID will pull the persisted node ID, if any, or create one
|
||||||
// and persist it.
|
// and persist it.
|
||||||
func (a *Agent) setupNodeID(config *Config) error {
|
func (a *Agent) setupNodeID(config *Config) error {
|
||||||
// If they've configured a node ID manually then just use that, as
|
// If they've configured a node ID manually then just use that, as
|
||||||
|
@ -606,15 +645,14 @@ func (a *Agent) setupNodeID(config *Config) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// For dev mode we have no filesystem access so just make a GUID.
|
// For dev mode we have no filesystem access so just make one.
|
||||||
if a.config.DevMode {
|
if a.config.DevMode {
|
||||||
id, err := uuid.GenerateUUID()
|
id, err := a.makeNodeID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
config.NodeID = types.NodeID(id)
|
config.NodeID = types.NodeID(id)
|
||||||
a.logger.Printf("[INFO] agent: Generated unique node ID %q for this agent (will not be persisted in dev mode)", config.NodeID)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,7 +675,7 @@ func (a *Agent) setupNodeID(config *Config) error {
|
||||||
|
|
||||||
// If we still don't have a valid node ID, make one.
|
// If we still don't have a valid node ID, make one.
|
||||||
if config.NodeID == "" {
|
if config.NodeID == "" {
|
||||||
id, err := uuid.GenerateUUID()
|
id, err := a.makeNodeID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -649,7 +687,6 @@ func (a *Agent) setupNodeID(config *Config) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
config.NodeID = types.NodeID(id)
|
config.NodeID = types.NodeID(id)
|
||||||
a.logger.Printf("[INFO] agent: Generated unique node ID %q for this agent (persisted)", config.NodeID)
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
gopsutil is distributed under BSD license reproduced below.
|
||||||
|
|
||||||
|
Copyright (c) 2014, WAKAYAMA Shirou
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the gopsutil authors nor the names of its contributors
|
||||||
|
may be used to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
-------
|
||||||
|
internal/common/binary.go in the gopsutil is copied and modifid from golang/encoding/binary.go.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,26 @@
|
||||||
|
.PHONY: help check
|
||||||
|
.DEFAULT_GOAL := help
|
||||||
|
|
||||||
|
SUBPKGS=cpu disk docker host internal load mem net process
|
||||||
|
|
||||||
|
help: ## Show help
|
||||||
|
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||||
|
|
||||||
|
check: ## Check
|
||||||
|
errcheck -ignore="Close|Run|Write" ./...
|
||||||
|
golint ./... | egrep -v 'underscores|HttpOnly|should have comment|comment on exported|CamelCase|VM|UID' && exit 1 || exit 0
|
||||||
|
|
||||||
|
BUILD_FAIL_PATTERN=grep -v "exec format error" | grep "build failed" && exit 1 || exit 0
|
||||||
|
build_test: ## test only buildable
|
||||||
|
# Supported operating systems
|
||||||
|
GOOS=linux go test ./... | $(BUILD_FAIL_PATTERN)
|
||||||
|
GOOS=freebsd go test ./... | $(BUILD_FAIL_PATTERN)
|
||||||
|
GOOS=openbsd go test ./... | $(BUILD_FAIL_PATTERN)
|
||||||
|
CGO_ENABLED=0 GOOS=darwin go test ./... | $(BUILD_FAIL_PATTERN)
|
||||||
|
CGO_ENABLED=1 GOOS=darwin go test ./... | $(BUILD_FAIL_PATTERN)
|
||||||
|
GOOS=windows go test ./... | $(BUILD_FAIL_PATTERN)
|
||||||
|
# Operating systems supported for building only (not implemented error if used)
|
||||||
|
GOOS=dragonfly go test ./... | $(BUILD_FAIL_PATTERN)
|
||||||
|
GOOS=netbsd go test ./... | $(BUILD_FAIL_PATTERN)
|
||||||
|
GOOS=solaris go test ./... | $(BUILD_FAIL_PATTERN)
|
||||||
|
@echo 'Successfully built on all known operating systems'
|
|
@ -0,0 +1,318 @@
|
||||||
|
gopsutil: psutil for golang
|
||||||
|
==============================
|
||||||
|
|
||||||
|
.. image:: https://circleci.com/gh/shirou/gopsutil.svg?&style=shield
|
||||||
|
:target: https://circleci.com/gh/shirou/gopsutil
|
||||||
|
|
||||||
|
.. image:: https://coveralls.io/repos/shirou/gopsutil/badge.svg?branch=master
|
||||||
|
:target: https://coveralls.io/r/shirou/gopsutil?branch=master
|
||||||
|
|
||||||
|
.. image:: https://godoc.org/github.com/shirou/gopsutil?status.svg
|
||||||
|
:target: http://godoc.org/github.com/shirou/gopsutil
|
||||||
|
|
||||||
|
This is a port of psutil (http://pythonhosted.org/psutil/). The challenge is porting all
|
||||||
|
psutil functions on some architectures.
|
||||||
|
|
||||||
|
|
||||||
|
.. highlights:: Breaking Changes!
|
||||||
|
|
||||||
|
Breaking changes is introduced at v2. See `issue 174 <https://github.com/shirou/gopsutil/issues/174>`_ .
|
||||||
|
|
||||||
|
|
||||||
|
Migrating to v2
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
On gopsutil itself, `v2migration.sh <https://github.com/shirou/gopsutil/blob/v2/v2migration.sh>`_ is used for migration. It can not be commonly used, but it may help you with migration.
|
||||||
|
|
||||||
|
|
||||||
|
Tag semantics
|
||||||
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
gopsutil tag policy is almost same as Semantic Versioning, but automatically increase like Ubuntu versioning.
|
||||||
|
|
||||||
|
for example, `v2.16.10` means
|
||||||
|
|
||||||
|
- v2: major version
|
||||||
|
- 16: release year, 2016
|
||||||
|
- 10: release month
|
||||||
|
|
||||||
|
gopsutil aims to keep backwards-compatiblity until major version change.
|
||||||
|
|
||||||
|
Taged at every end of month, but there are only a few commits, it can be skipped.
|
||||||
|
|
||||||
|
|
||||||
|
Available Architectures
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
- FreeBSD i386/amd64
|
||||||
|
- Linux i386/amd64/arm(raspberry pi)
|
||||||
|
- Windows/amd64
|
||||||
|
- Darwin/amd64
|
||||||
|
- OpenBDS amd64 (Thank you @mpfz0r!)
|
||||||
|
|
||||||
|
All works are implemented without cgo by porting c struct to golang struct.
|
||||||
|
|
||||||
|
|
||||||
|
Usage
|
||||||
|
---------
|
||||||
|
|
||||||
|
Note: gopsutil v2 breaks compatibility. If you want to stay with compatibility, please use v1 branch and vendoring.
|
||||||
|
|
||||||
|
.. code:: go
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/shirou/gopsutil/mem"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
v, _ := mem.VirtualMemory()
|
||||||
|
|
||||||
|
// almost every return value is a struct
|
||||||
|
fmt.Printf("Total: %v, Free:%v, UsedPercent:%f%%\n", v.Total, v.Free, v.UsedPercent)
|
||||||
|
|
||||||
|
// convert to JSON. String() is also implemented
|
||||||
|
fmt.Println(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
The output is below.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
Total: 3179569152, Free:284233728, UsedPercent:84.508194%
|
||||||
|
{"total":3179569152,"available":492572672,"used":2895335424,"usedPercent":84.50819439828305, (snip...)}
|
||||||
|
|
||||||
|
You can set an alternative location to :code:`/proc` by setting the :code:`HOST_PROC` environment variable.
|
||||||
|
|
||||||
|
You can set an alternative location to :code:`/sys` by setting the :code:`HOST_SYS` environment variable.
|
||||||
|
|
||||||
|
You can set an alternative location to :code:`/etc` by setting the :code:`HOST_ETC` environment variable.
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
see http://godoc.org/github.com/shirou/gopsutil
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
- go1.5 or above is required.
|
||||||
|
|
||||||
|
|
||||||
|
More Info
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Several methods have been added which are not present in psutil, but will provide useful information.
|
||||||
|
|
||||||
|
- host/HostInfo() (linux)
|
||||||
|
|
||||||
|
- Hostname
|
||||||
|
- Uptime
|
||||||
|
- Procs
|
||||||
|
- OS (ex: "linux")
|
||||||
|
- Platform (ex: "ubuntu", "arch")
|
||||||
|
- PlatformFamily (ex: "debian")
|
||||||
|
- PlatformVersion (ex: "Ubuntu 13.10")
|
||||||
|
- VirtualizationSystem (ex: "LXC")
|
||||||
|
- VirtualizationRole (ex: "guest"/"host")
|
||||||
|
|
||||||
|
- cpu/CPUInfo() (linux, freebsd)
|
||||||
|
|
||||||
|
- CPU (ex: 0, 1, ...)
|
||||||
|
- VendorID (ex: "GenuineIntel")
|
||||||
|
- Family
|
||||||
|
- Model
|
||||||
|
- Stepping
|
||||||
|
- PhysicalID
|
||||||
|
- CoreID
|
||||||
|
- Cores (ex: 2)
|
||||||
|
- ModelName (ex: "Intel(R) Core(TM) i7-2640M CPU @ 2.80GHz")
|
||||||
|
- Mhz
|
||||||
|
- CacheSize
|
||||||
|
- Flags (ex: "fpu vme de pse tsc msr pae mce cx8 ...")
|
||||||
|
|
||||||
|
- load/LoadAvg() (linux, freebsd)
|
||||||
|
|
||||||
|
- Load1
|
||||||
|
- Load5
|
||||||
|
- Load15
|
||||||
|
|
||||||
|
- docker/GetDockerIDList() (linux only)
|
||||||
|
|
||||||
|
- container id list ([]string)
|
||||||
|
|
||||||
|
- docker/CgroupCPU() (linux only)
|
||||||
|
|
||||||
|
- user
|
||||||
|
- system
|
||||||
|
|
||||||
|
- docker/CgroupMem() (linux only)
|
||||||
|
|
||||||
|
- various status
|
||||||
|
|
||||||
|
- net_protocols (linux only)
|
||||||
|
|
||||||
|
- system wide stats on network protocols (i.e IP, TCP, UDP, etc.)
|
||||||
|
- sourced from /proc/net/snmp
|
||||||
|
|
||||||
|
- iptables nf_conntrack (linux only)
|
||||||
|
|
||||||
|
- system wide stats on netfilter conntrack module
|
||||||
|
- sourced from /proc/sys/net/netfilter/nf_conntrack_count
|
||||||
|
|
||||||
|
Some codes are ported from Ohai. many thanks.
|
||||||
|
|
||||||
|
|
||||||
|
Current Status
|
||||||
|
------------------
|
||||||
|
|
||||||
|
- x: work
|
||||||
|
- b: almost works, but something is broken
|
||||||
|
|
||||||
|
=================== ====== ======= ======= ====== =======
|
||||||
|
name Linux FreeBSD OpenBSD MacOSX Windows
|
||||||
|
cpu_times x x x x x
|
||||||
|
cpu_count x x x x x
|
||||||
|
cpu_percent x x x x x
|
||||||
|
cpu_times_percent x x x x x
|
||||||
|
virtual_memory x x x x x
|
||||||
|
swap_memory x x x x
|
||||||
|
disk_partitions x x x x x
|
||||||
|
disk_io_counters x x x
|
||||||
|
disk_usage x x x x x
|
||||||
|
net_io_counters x x x b x
|
||||||
|
boot_time x x x x x
|
||||||
|
users x x x x x
|
||||||
|
pids x x x x x
|
||||||
|
pid_exists x x x x x
|
||||||
|
net_connections x x
|
||||||
|
net_protocols x
|
||||||
|
net_if_addrs
|
||||||
|
net_if_stats
|
||||||
|
netfilter_conntrack x
|
||||||
|
=================== ====== ======= ======= ====== =======
|
||||||
|
|
||||||
|
Process class
|
||||||
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
================ ===== ======= ======= ====== =======
|
||||||
|
name Linux FreeBSD OpenBSD MacOSX Windows
|
||||||
|
pid x x x x x
|
||||||
|
ppid x x x x x
|
||||||
|
name x x x x x
|
||||||
|
cmdline x x x
|
||||||
|
create_time x
|
||||||
|
status x x x x
|
||||||
|
cwd x
|
||||||
|
exe x x x x
|
||||||
|
uids x x x x
|
||||||
|
gids x x x x
|
||||||
|
terminal x x x x
|
||||||
|
io_counters x x x x
|
||||||
|
nice x x x x x
|
||||||
|
num_fds x
|
||||||
|
num_ctx_switches x
|
||||||
|
num_threads x x x x x
|
||||||
|
cpu_times x
|
||||||
|
memory_info x x x x x
|
||||||
|
memory_info_ex x
|
||||||
|
memory_maps x
|
||||||
|
open_files x
|
||||||
|
send_signal x x x x
|
||||||
|
suspend x x x x
|
||||||
|
resume x x x x
|
||||||
|
terminate x x x x x
|
||||||
|
kill x x x x
|
||||||
|
username x
|
||||||
|
ionice
|
||||||
|
rlimit
|
||||||
|
num_handlres
|
||||||
|
threads
|
||||||
|
cpu_percent x x x
|
||||||
|
cpu_affinity
|
||||||
|
memory_percent
|
||||||
|
parent x x x
|
||||||
|
children x x x x
|
||||||
|
connections x x x
|
||||||
|
is_running
|
||||||
|
================ ===== ======= ======= ====== =======
|
||||||
|
|
||||||
|
Original Metrics
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
================== ===== ======= ======= ====== =======
|
||||||
|
item Linux FreeBSD OpenBSD MacOSX Windows
|
||||||
|
**HostInfo**
|
||||||
|
hostname x x x x x
|
||||||
|
uptime x x x x
|
||||||
|
proces x x x
|
||||||
|
os x x x x x
|
||||||
|
platform x x x x
|
||||||
|
platformfamily x x x x
|
||||||
|
virtualization x
|
||||||
|
**CPU**
|
||||||
|
VendorID x x x x x
|
||||||
|
Family x x x x x
|
||||||
|
Model x x x x x
|
||||||
|
Stepping x x x x x
|
||||||
|
PhysicalID x
|
||||||
|
CoreID x
|
||||||
|
Cores x x
|
||||||
|
ModelName x x x x x
|
||||||
|
**LoadAvg**
|
||||||
|
Load1 x x x x
|
||||||
|
Load5 x x x x
|
||||||
|
Load15 x x x x
|
||||||
|
**GetDockerID**
|
||||||
|
container id x no no no no
|
||||||
|
**CgroupsCPU**
|
||||||
|
user x no no no no
|
||||||
|
system x no no no no
|
||||||
|
**CgroupsMem**
|
||||||
|
various x no no no no
|
||||||
|
================== ===== ======= ======= ====== =======
|
||||||
|
|
||||||
|
- future work
|
||||||
|
|
||||||
|
- process_iter
|
||||||
|
- wait_procs
|
||||||
|
- Process class
|
||||||
|
|
||||||
|
- as_dict
|
||||||
|
- wait
|
||||||
|
|
||||||
|
|
||||||
|
License
|
||||||
|
------------
|
||||||
|
|
||||||
|
New BSD License (same as psutil)
|
||||||
|
|
||||||
|
|
||||||
|
Related Works
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
I have been influenced by the following great works:
|
||||||
|
|
||||||
|
- psutil: http://pythonhosted.org/psutil/
|
||||||
|
- dstat: https://github.com/dagwieers/dstat
|
||||||
|
- gosigar: https://github.com/cloudfoundry/gosigar/
|
||||||
|
- goprocinfo: https://github.com/c9s/goprocinfo
|
||||||
|
- go-ps: https://github.com/mitchellh/go-ps
|
||||||
|
- ohai: https://github.com/opscode/ohai/
|
||||||
|
- bosun: https://github.com/bosun-monitor/bosun/tree/master/cmd/scollector/collectors
|
||||||
|
- mackerel: https://github.com/mackerelio/mackerel-agent/tree/master/metrics
|
||||||
|
|
||||||
|
How to Contribute
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
1. Fork it
|
||||||
|
2. Create your feature branch (git checkout -b my-new-feature)
|
||||||
|
3. Commit your changes (git commit -am 'Add some feature')
|
||||||
|
4. Push to the branch (git push origin my-new-feature)
|
||||||
|
5. Create new Pull Request
|
||||||
|
|
||||||
|
My English is terrible, so documentation or correcting comments are also
|
||||||
|
welcome.
|
|
@ -0,0 +1,11 @@
|
||||||
|
machine:
|
||||||
|
timezone:
|
||||||
|
Asia/Tokyo
|
||||||
|
test:
|
||||||
|
override:
|
||||||
|
- GOOS=linux GOARCH=amd64 go test -v ./...
|
||||||
|
- GOOS=linux GOARCH=386 go get -v ./...
|
||||||
|
- GOOS=linux GOARCH=arm GOARM=7 go get -v ./...
|
||||||
|
- GOOS=freebsd GOARCH=amd64 go get -v ./...
|
||||||
|
- GOOS=windows GOARCH=amd64 go get -v ./...
|
||||||
|
- GOOS=darwin GOARCH=amd64 go get -v ./...
|
|
@ -0,0 +1,26 @@
|
||||||
|
#/bin/sh
|
||||||
|
|
||||||
|
# see http://www.songmu.jp/riji/entry/2015-01-15-goveralls-multi-package.html
|
||||||
|
|
||||||
|
set -e
|
||||||
|
# cleanup
|
||||||
|
cleanup() {
|
||||||
|
if [ $tmpprof != "" ] && [ -f $tmpprof ]; then
|
||||||
|
rm -f $tmpprof
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
trap cleanup INT QUIT TERM EXIT
|
||||||
|
|
||||||
|
# メインの処理
|
||||||
|
prof=${1:-".profile.cov"}
|
||||||
|
echo "mode: count" > $prof
|
||||||
|
gopath1=$(echo $GOPATH | cut -d: -f1)
|
||||||
|
for pkg in $(go list ./...); do
|
||||||
|
tmpprof=$gopath1/src/$pkg/profile.tmp
|
||||||
|
go test -covermode=count -coverprofile=$tmpprof $pkg
|
||||||
|
if [ -f $tmpprof ]; then
|
||||||
|
cat $tmpprof | tail -n +2 >> $prof
|
||||||
|
rm $tmpprof
|
||||||
|
fi
|
||||||
|
done
|
|
@ -0,0 +1 @@
|
||||||
|
package gopsutil
|
|
@ -0,0 +1,50 @@
|
||||||
|
package host
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/shirou/gopsutil/internal/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
invoke common.Invoker
|
||||||
|
cachedBootTime = uint64(0)
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
invoke = common.Invoke{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A HostInfoStat describes the host status.
|
||||||
|
// This is not in the psutil but it useful.
|
||||||
|
type InfoStat struct {
|
||||||
|
Hostname string `json:"hostname"`
|
||||||
|
Uptime uint64 `json:"uptime"`
|
||||||
|
BootTime uint64 `json:"bootTime"`
|
||||||
|
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"` // version of the complete OS
|
||||||
|
KernelVersion string `json:"kernelVersion"` // version of the OS kernel (if available)
|
||||||
|
VirtualizationSystem string `json:"virtualizationSystem"`
|
||||||
|
VirtualizationRole string `json:"virtualizationRole"` // guest or host
|
||||||
|
HostID string `json:"hostid"` // ex: uuid
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserStat struct {
|
||||||
|
User string `json:"user"`
|
||||||
|
Terminal string `json:"terminal"`
|
||||||
|
Host string `json:"host"`
|
||||||
|
Started int `json:"started"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h InfoStat) String() string {
|
||||||
|
s, _ := json.Marshal(h)
|
||||||
|
return string(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UserStat) String() string {
|
||||||
|
s, _ := json.Marshal(u)
|
||||||
|
return string(s)
|
||||||
|
}
|
|
@ -0,0 +1,180 @@
|
||||||
|
// +build darwin
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/shirou/gopsutil/internal/common"
|
||||||
|
"github.com/shirou/gopsutil/process"
|
||||||
|
)
|
||||||
|
|
||||||
|
// from utmpx.h
|
||||||
|
const USER_PROCESS = 7
|
||||||
|
|
||||||
|
func Info() (*InfoStat, error) {
|
||||||
|
ret := &InfoStat{
|
||||||
|
OS: runtime.GOOS,
|
||||||
|
PlatformFamily: "darwin",
|
||||||
|
}
|
||||||
|
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err == nil {
|
||||||
|
ret.Hostname = hostname
|
||||||
|
}
|
||||||
|
|
||||||
|
platform, family, pver, version, err := PlatformInformation()
|
||||||
|
if err == nil {
|
||||||
|
ret.Platform = platform
|
||||||
|
ret.PlatformFamily = family
|
||||||
|
ret.PlatformVersion = pver
|
||||||
|
ret.KernelVersion = version
|
||||||
|
}
|
||||||
|
|
||||||
|
system, role, err := Virtualization()
|
||||||
|
if err == nil {
|
||||||
|
ret.VirtualizationSystem = system
|
||||||
|
ret.VirtualizationRole = role
|
||||||
|
}
|
||||||
|
|
||||||
|
boot, err := BootTime()
|
||||||
|
if err == nil {
|
||||||
|
ret.BootTime = boot
|
||||||
|
ret.Uptime = uptime(boot)
|
||||||
|
}
|
||||||
|
|
||||||
|
procs, err := process.Pids()
|
||||||
|
if err == nil {
|
||||||
|
ret.Procs = uint64(len(procs))
|
||||||
|
}
|
||||||
|
|
||||||
|
values, err := common.DoSysctrl("kern.uuid")
|
||||||
|
if err == nil && len(values) == 1 && values[0] != "" {
|
||||||
|
ret.HostID = values[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func BootTime() (uint64, error) {
|
||||||
|
if cachedBootTime != 0 {
|
||||||
|
return cachedBootTime, nil
|
||||||
|
}
|
||||||
|
values, err := common.DoSysctrl("kern.boottime")
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
// ex: { sec = 1392261637, usec = 627534 } Thu Feb 13 12:20:37 2014
|
||||||
|
v := strings.Replace(values[2], ",", "", 1)
|
||||||
|
boottime, err := strconv.ParseInt(v, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
cachedBootTime = uint64(boottime)
|
||||||
|
|
||||||
|
return cachedBootTime, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func uptime(boot uint64) uint64 {
|
||||||
|
return uint64(time.Now().Unix()) - boot
|
||||||
|
}
|
||||||
|
|
||||||
|
func Uptime() (uint64, error) {
|
||||||
|
boot, err := BootTime()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return uptime(boot), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Users() ([]UserStat, error) {
|
||||||
|
utmpfile := "/var/run/utmpx"
|
||||||
|
var ret []UserStat
|
||||||
|
|
||||||
|
file, err := os.Open(utmpfile)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := ioutil.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
u := Utmpx{}
|
||||||
|
entrySize := int(unsafe.Sizeof(u))
|
||||||
|
count := len(buf) / entrySize
|
||||||
|
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
b := buf[i*entrySize : i*entrySize+entrySize]
|
||||||
|
|
||||||
|
var u Utmpx
|
||||||
|
br := bytes.NewReader(b)
|
||||||
|
err := binary.Read(br, binary.LittleEndian, &u)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if u.Type != USER_PROCESS {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
user := UserStat{
|
||||||
|
User: common.IntToString(u.User[:]),
|
||||||
|
Terminal: common.IntToString(u.Line[:]),
|
||||||
|
Host: common.IntToString(u.Host[:]),
|
||||||
|
Started: int(u.Tv.Sec),
|
||||||
|
}
|
||||||
|
ret = append(ret, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func PlatformInformation() (string, string, string, string, error) {
|
||||||
|
platform := ""
|
||||||
|
family := ""
|
||||||
|
version := ""
|
||||||
|
pver := ""
|
||||||
|
|
||||||
|
sw_vers, err := exec.LookPath("sw_vers")
|
||||||
|
if err != nil {
|
||||||
|
return "", "", "", "", err
|
||||||
|
}
|
||||||
|
uname, err := exec.LookPath("uname")
|
||||||
|
if err != nil {
|
||||||
|
return "", "", "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := invoke.Command(uname, "-s")
|
||||||
|
if err == nil {
|
||||||
|
platform = strings.ToLower(strings.TrimSpace(string(out)))
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err = invoke.Command(sw_vers, "-productVersion")
|
||||||
|
if err == nil {
|
||||||
|
pver = strings.ToLower(strings.TrimSpace(string(out)))
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err = invoke.Command(uname, "-r")
|
||||||
|
if err == nil {
|
||||||
|
version = strings.ToLower(strings.TrimSpace(string(out)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return platform, family, pver, version, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Virtualization() (string, string, error) {
|
||||||
|
system := ""
|
||||||
|
role := ""
|
||||||
|
|
||||||
|
return system, role, nil
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
// Created by cgo -godefs - DO NOT EDIT
|
||||||
|
// cgo -godefs types_darwin.go
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
type Utmpx struct {
|
||||||
|
User [256]int8
|
||||||
|
ID [4]int8
|
||||||
|
Line [32]int8
|
||||||
|
Pid int32
|
||||||
|
Type int16
|
||||||
|
Pad_cgo_0 [6]byte
|
||||||
|
Tv Timeval
|
||||||
|
Host [256]int8
|
||||||
|
Pad [16]uint32
|
||||||
|
}
|
||||||
|
type Timeval struct {
|
||||||
|
Sec int32
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
// +build !darwin,!linux,!freebsd,!openbsd,!windows
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
import "github.com/shirou/gopsutil/internal/common"
|
||||||
|
|
||||||
|
func Info() (*InfoStat, error) {
|
||||||
|
return nil, common.ErrNotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func BootTime() (uint64, error) {
|
||||||
|
return 0, common.ErrNotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func Uptime() (uint64, error) {
|
||||||
|
return 0, common.ErrNotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func Users() ([]UserStat, error) {
|
||||||
|
return []UserStat{}, common.ErrNotImplementedError
|
||||||
|
}
|
|
@ -0,0 +1,211 @@
|
||||||
|
// +build freebsd
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/shirou/gopsutil/internal/common"
|
||||||
|
"github.com/shirou/gopsutil/process"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
UTNameSize = 16 /* see MAXLOGNAME in <sys/param.h> */
|
||||||
|
UTLineSize = 8
|
||||||
|
UTHostSize = 16
|
||||||
|
)
|
||||||
|
|
||||||
|
func Info() (*InfoStat, error) {
|
||||||
|
ret := &InfoStat{
|
||||||
|
OS: runtime.GOOS,
|
||||||
|
PlatformFamily: "freebsd",
|
||||||
|
}
|
||||||
|
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err == nil {
|
||||||
|
ret.Hostname = hostname
|
||||||
|
}
|
||||||
|
|
||||||
|
platform, family, version, err := PlatformInformation()
|
||||||
|
if err == nil {
|
||||||
|
ret.Platform = platform
|
||||||
|
ret.PlatformFamily = family
|
||||||
|
ret.PlatformVersion = version
|
||||||
|
ret.KernelVersion = version
|
||||||
|
}
|
||||||
|
|
||||||
|
system, role, err := Virtualization()
|
||||||
|
if err == nil {
|
||||||
|
ret.VirtualizationSystem = system
|
||||||
|
ret.VirtualizationRole = role
|
||||||
|
}
|
||||||
|
|
||||||
|
boot, err := BootTime()
|
||||||
|
if err == nil {
|
||||||
|
ret.BootTime = boot
|
||||||
|
ret.Uptime = uptime(boot)
|
||||||
|
}
|
||||||
|
|
||||||
|
procs, err := process.Pids()
|
||||||
|
if err == nil {
|
||||||
|
ret.Procs = uint64(len(procs))
|
||||||
|
}
|
||||||
|
|
||||||
|
values, err := common.DoSysctrl("kern.hostuuid")
|
||||||
|
if err == nil && len(values) == 1 && values[0] != "" {
|
||||||
|
ret.HostID = values[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func BootTime() (uint64, error) {
|
||||||
|
if cachedBootTime != 0 {
|
||||||
|
return cachedBootTime, nil
|
||||||
|
}
|
||||||
|
values, err := common.DoSysctrl("kern.boottime")
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
// ex: { sec = 1392261637, usec = 627534 } Thu Feb 13 12:20:37 2014
|
||||||
|
v := strings.Replace(values[2], ",", "", 1)
|
||||||
|
|
||||||
|
boottime, err := strconv.ParseUint(v, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
cachedBootTime = boottime
|
||||||
|
|
||||||
|
return boottime, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func uptime(boot uint64) uint64 {
|
||||||
|
return uint64(time.Now().Unix()) - boot
|
||||||
|
}
|
||||||
|
|
||||||
|
func Uptime() (uint64, error) {
|
||||||
|
boot, err := BootTime()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return uptime(boot), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Users() ([]UserStat, error) {
|
||||||
|
utmpfile := "/var/run/utx.active"
|
||||||
|
if !common.PathExists(utmpfile) {
|
||||||
|
utmpfile = "/var/run/utmp" // before 9.0
|
||||||
|
return getUsersFromUtmp(utmpfile)
|
||||||
|
}
|
||||||
|
|
||||||
|
var ret []UserStat
|
||||||
|
file, err := os.Open(utmpfile)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := ioutil.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
entrySize := sizeOfUtmpx
|
||||||
|
count := len(buf) / entrySize
|
||||||
|
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
b := buf[i*sizeOfUtmpx : (i+1)*sizeOfUtmpx]
|
||||||
|
var u Utmpx
|
||||||
|
br := bytes.NewReader(b)
|
||||||
|
err := binary.Read(br, binary.LittleEndian, &u)
|
||||||
|
if err != nil || u.Type != 4 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sec := (binary.LittleEndian.Uint32(u.Tv.Sec[:])) / 2 // TODO:
|
||||||
|
user := UserStat{
|
||||||
|
User: common.IntToString(u.User[:]),
|
||||||
|
Terminal: common.IntToString(u.Line[:]),
|
||||||
|
Host: common.IntToString(u.Host[:]),
|
||||||
|
Started: int(sec),
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = append(ret, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func PlatformInformation() (string, string, string, error) {
|
||||||
|
platform := ""
|
||||||
|
family := ""
|
||||||
|
version := ""
|
||||||
|
uname, err := exec.LookPath("uname")
|
||||||
|
if err != nil {
|
||||||
|
return "", "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := invoke.Command(uname, "-s")
|
||||||
|
if err == nil {
|
||||||
|
platform = strings.ToLower(strings.TrimSpace(string(out)))
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err = invoke.Command(uname, "-r")
|
||||||
|
if err == nil {
|
||||||
|
version = strings.ToLower(strings.TrimSpace(string(out)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return platform, family, version, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Virtualization() (string, string, error) {
|
||||||
|
system := ""
|
||||||
|
role := ""
|
||||||
|
|
||||||
|
return system, role, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// before 9.0
|
||||||
|
func getUsersFromUtmp(utmpfile string) ([]UserStat, error) {
|
||||||
|
var ret []UserStat
|
||||||
|
file, err := os.Open(utmpfile)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
buf, err := ioutil.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
u := Utmp{}
|
||||||
|
entrySize := int(unsafe.Sizeof(u))
|
||||||
|
count := len(buf) / entrySize
|
||||||
|
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
b := buf[i*entrySize : i*entrySize+entrySize]
|
||||||
|
var u Utmp
|
||||||
|
br := bytes.NewReader(b)
|
||||||
|
err := binary.Read(br, binary.LittleEndian, &u)
|
||||||
|
if err != nil || u.Time == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
user := UserStat{
|
||||||
|
User: common.IntToString(u.Name[:]),
|
||||||
|
Terminal: common.IntToString(u.Line[:]),
|
||||||
|
Host: common.IntToString(u.Host[:]),
|
||||||
|
Started: int(u.Time),
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = append(ret, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
// Created by cgo -godefs - DO NOT EDIT
|
||||||
|
// cgo -godefs types_freebsd.go
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofPtr = 0x4
|
||||||
|
sizeofShort = 0x2
|
||||||
|
sizeofInt = 0x4
|
||||||
|
sizeofLong = 0x4
|
||||||
|
sizeofLongLong = 0x8
|
||||||
|
sizeOfUtmpx = 197 // TODO why should 197
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
_C_short int16
|
||||||
|
_C_int int32
|
||||||
|
_C_long int32
|
||||||
|
_C_long_long int64
|
||||||
|
)
|
||||||
|
|
||||||
|
type Utmp struct {
|
||||||
|
Line [8]int8
|
||||||
|
Name [16]int8
|
||||||
|
Host [16]int8
|
||||||
|
Time int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type Utmpx struct {
|
||||||
|
Type int16
|
||||||
|
Tv Timeval
|
||||||
|
Id [8]int8
|
||||||
|
Pid int32
|
||||||
|
User [32]int8
|
||||||
|
Line [16]int8
|
||||||
|
Host [125]int8
|
||||||
|
// X__ut_spare [64]int8
|
||||||
|
}
|
||||||
|
|
||||||
|
type Timeval struct {
|
||||||
|
Sec [4]byte
|
||||||
|
Usec [3]byte
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Created by cgo -godefs - DO NOT EDIT
|
||||||
|
// cgo -godefs types_freebsd.go
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofPtr = 0x8
|
||||||
|
sizeofShort = 0x2
|
||||||
|
sizeofInt = 0x4
|
||||||
|
sizeofLong = 0x8
|
||||||
|
sizeofLongLong = 0x8
|
||||||
|
sizeOfUtmpx = 197 // TODO: why should 197, not 0x118
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
_C_short int16
|
||||||
|
_C_int int32
|
||||||
|
_C_long int64
|
||||||
|
_C_long_long int64
|
||||||
|
)
|
||||||
|
|
||||||
|
type Utmp struct {
|
||||||
|
Line [8]int8
|
||||||
|
Name [16]int8
|
||||||
|
Host [16]int8
|
||||||
|
Time int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type Utmpx struct {
|
||||||
|
Type int16
|
||||||
|
Tv Timeval
|
||||||
|
Id [8]int8
|
||||||
|
Pid int32
|
||||||
|
User [32]int8
|
||||||
|
Line [16]int8
|
||||||
|
Host [125]int8
|
||||||
|
// Host [128]int8
|
||||||
|
// X__ut_spare [64]int8
|
||||||
|
}
|
||||||
|
|
||||||
|
type Timeval struct {
|
||||||
|
Sec [4]byte
|
||||||
|
Usec [3]byte
|
||||||
|
}
|
|
@ -0,0 +1,522 @@
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"regexp"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/shirou/gopsutil/internal/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LSB struct {
|
||||||
|
ID string
|
||||||
|
Release string
|
||||||
|
Codename string
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
// from utmp.h
|
||||||
|
const USER_PROCESS = 7
|
||||||
|
|
||||||
|
func Info() (*InfoStat, error) {
|
||||||
|
ret := &InfoStat{
|
||||||
|
OS: runtime.GOOS,
|
||||||
|
}
|
||||||
|
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err == nil {
|
||||||
|
ret.Hostname = hostname
|
||||||
|
}
|
||||||
|
|
||||||
|
platform, family, version, err := PlatformInformation()
|
||||||
|
if err == nil {
|
||||||
|
ret.Platform = platform
|
||||||
|
ret.PlatformFamily = family
|
||||||
|
ret.PlatformVersion = version
|
||||||
|
}
|
||||||
|
kernelVersion, err := KernelVersion()
|
||||||
|
if err == nil {
|
||||||
|
ret.KernelVersion = kernelVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
system, role, err := Virtualization()
|
||||||
|
if err == nil {
|
||||||
|
ret.VirtualizationSystem = system
|
||||||
|
ret.VirtualizationRole = role
|
||||||
|
}
|
||||||
|
|
||||||
|
boot, err := BootTime()
|
||||||
|
if err == nil {
|
||||||
|
ret.BootTime = boot
|
||||||
|
ret.Uptime = uptime(boot)
|
||||||
|
}
|
||||||
|
|
||||||
|
if numProcs, err := common.NumProcs(); err == nil {
|
||||||
|
ret.Procs = numProcs
|
||||||
|
}
|
||||||
|
|
||||||
|
sysProductUUID := common.HostSys("class/dmi/id/product_uuid")
|
||||||
|
switch {
|
||||||
|
case common.PathExists(sysProductUUID):
|
||||||
|
lines, err := common.ReadLines(sysProductUUID)
|
||||||
|
if err == nil && len(lines) > 0 && lines[0] != "" {
|
||||||
|
ret.HostID = lines[0]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
values, err := common.DoSysctrl("kernel.random.boot_id")
|
||||||
|
if err == nil && len(values) == 1 && values[0] != "" {
|
||||||
|
ret.HostID = values[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BootTime returns the system boot time expressed in seconds since the epoch.
|
||||||
|
func BootTime() (uint64, error) {
|
||||||
|
if cachedBootTime != 0 {
|
||||||
|
return cachedBootTime, nil
|
||||||
|
}
|
||||||
|
filename := common.HostProc("stat")
|
||||||
|
lines, err := common.ReadLines(filename)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
for _, line := range lines {
|
||||||
|
if strings.HasPrefix(line, "btime") {
|
||||||
|
f := strings.Fields(line)
|
||||||
|
if len(f) != 2 {
|
||||||
|
return 0, fmt.Errorf("wrong btime format")
|
||||||
|
}
|
||||||
|
b, err := strconv.ParseInt(f[1], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
cachedBootTime = uint64(b)
|
||||||
|
return cachedBootTime, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, fmt.Errorf("could not find btime")
|
||||||
|
}
|
||||||
|
|
||||||
|
func uptime(boot uint64) uint64 {
|
||||||
|
return uint64(time.Now().Unix()) - boot
|
||||||
|
}
|
||||||
|
|
||||||
|
func Uptime() (uint64, error) {
|
||||||
|
boot, err := BootTime()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return uptime(boot), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Users() ([]UserStat, error) {
|
||||||
|
utmpfile := "/var/run/utmp"
|
||||||
|
|
||||||
|
file, err := os.Open(utmpfile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := ioutil.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
count := len(buf) / sizeOfUtmp
|
||||||
|
|
||||||
|
ret := make([]UserStat, 0, count)
|
||||||
|
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
b := buf[i*sizeOfUtmp : (i+1)*sizeOfUtmp]
|
||||||
|
|
||||||
|
var u utmp
|
||||||
|
br := bytes.NewReader(b)
|
||||||
|
err := binary.Read(br, binary.LittleEndian, &u)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if u.Type != USER_PROCESS {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
user := UserStat{
|
||||||
|
User: common.IntToString(u.User[:]),
|
||||||
|
Terminal: common.IntToString(u.Line[:]),
|
||||||
|
Host: common.IntToString(u.Host[:]),
|
||||||
|
Started: int(u.Tv.Sec),
|
||||||
|
}
|
||||||
|
ret = append(ret, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getOSRelease() (platform string, version string, err error) {
|
||||||
|
contents, err := common.ReadLines(common.HostEtc("os-release"))
|
||||||
|
if err != nil {
|
||||||
|
return "", "", nil // return empty
|
||||||
|
}
|
||||||
|
for _, line := range contents {
|
||||||
|
field := strings.Split(line, "=")
|
||||||
|
if len(field) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch field[0] {
|
||||||
|
case "ID": // use ID for lowercase
|
||||||
|
platform = field[1]
|
||||||
|
case "VERSION":
|
||||||
|
version = field[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return platform, version, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLSB() (*LSB, error) {
|
||||||
|
ret := &LSB{}
|
||||||
|
if common.PathExists(common.HostEtc("lsb-release")) {
|
||||||
|
contents, err := common.ReadLines(common.HostEtc("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 common.PathExists("/usr/bin/lsb_release") {
|
||||||
|
lsb_release, err := exec.LookPath("/usr/bin/lsb_release")
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
out, err := invoke.Command(lsb_release)
|
||||||
|
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 PlatformInformation() (platform string, family string, version string, err error) {
|
||||||
|
|
||||||
|
lsb, err := getLSB()
|
||||||
|
if err != nil {
|
||||||
|
lsb = &LSB{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if common.PathExists(common.HostEtc("oracle-release")) {
|
||||||
|
platform = "oracle"
|
||||||
|
contents, err := common.ReadLines(common.HostEtc("oracle-release"))
|
||||||
|
if err == nil {
|
||||||
|
version = getRedhatishVersion(contents)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if common.PathExists(common.HostEtc("enterprise-release")) {
|
||||||
|
platform = "oracle"
|
||||||
|
contents, err := common.ReadLines(common.HostEtc("enterprise-release"))
|
||||||
|
if err == nil {
|
||||||
|
version = getRedhatishVersion(contents)
|
||||||
|
}
|
||||||
|
} else if common.PathExists(common.HostEtc("debian_version")) {
|
||||||
|
if lsb.ID == "Ubuntu" {
|
||||||
|
platform = "ubuntu"
|
||||||
|
version = lsb.Release
|
||||||
|
} else if lsb.ID == "LinuxMint" {
|
||||||
|
platform = "linuxmint"
|
||||||
|
version = lsb.Release
|
||||||
|
} else {
|
||||||
|
if common.PathExists("/usr/bin/raspi-config") {
|
||||||
|
platform = "raspbian"
|
||||||
|
} else {
|
||||||
|
platform = "debian"
|
||||||
|
}
|
||||||
|
contents, err := common.ReadLines(common.HostEtc("debian_version"))
|
||||||
|
if err == nil {
|
||||||
|
version = contents[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if common.PathExists(common.HostEtc("redhat-release")) {
|
||||||
|
contents, err := common.ReadLines(common.HostEtc("redhat-release"))
|
||||||
|
if err == nil {
|
||||||
|
version = getRedhatishVersion(contents)
|
||||||
|
platform = getRedhatishPlatform(contents)
|
||||||
|
}
|
||||||
|
} else if common.PathExists(common.HostEtc("system-release")) {
|
||||||
|
contents, err := common.ReadLines(common.HostEtc("system-release"))
|
||||||
|
if err == nil {
|
||||||
|
version = getRedhatishVersion(contents)
|
||||||
|
platform = getRedhatishPlatform(contents)
|
||||||
|
}
|
||||||
|
} else if common.PathExists(common.HostEtc("gentoo-release")) {
|
||||||
|
platform = "gentoo"
|
||||||
|
contents, err := common.ReadLines(common.HostEtc("gentoo-release"))
|
||||||
|
if err == nil {
|
||||||
|
version = getRedhatishVersion(contents)
|
||||||
|
}
|
||||||
|
} else if common.PathExists(common.HostEtc("SuSE-release")) {
|
||||||
|
contents, err := common.ReadLines(common.HostEtc("SuSE-release"))
|
||||||
|
if err == nil {
|
||||||
|
version = getSuseVersion(contents)
|
||||||
|
platform = getSusePlatform(contents)
|
||||||
|
}
|
||||||
|
// TODO: slackware detecion
|
||||||
|
} else if common.PathExists(common.HostEtc("arch-release")) {
|
||||||
|
platform = "arch"
|
||||||
|
version = lsb.Release
|
||||||
|
} else if common.PathExists(common.HostEtc("alpine-release")) {
|
||||||
|
platform = "alpine"
|
||||||
|
contents, err := common.ReadLines(common.HostEtc("alpine-release"))
|
||||||
|
if err == nil && len(contents) > 0 {
|
||||||
|
version = contents[0]
|
||||||
|
}
|
||||||
|
} else if common.PathExists(common.HostEtc("os-release")) {
|
||||||
|
p, v, err := getOSRelease()
|
||||||
|
if err == nil {
|
||||||
|
platform = p
|
||||||
|
version = v
|
||||||
|
}
|
||||||
|
} 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", "opensuse":
|
||||||
|
family = "suse"
|
||||||
|
case "gentoo":
|
||||||
|
family = "gentoo"
|
||||||
|
case "slackware":
|
||||||
|
family = "slackware"
|
||||||
|
case "arch":
|
||||||
|
family = "arch"
|
||||||
|
case "exherbo":
|
||||||
|
family = "exherbo"
|
||||||
|
case "alpine":
|
||||||
|
family = "alpine"
|
||||||
|
case "coreos":
|
||||||
|
family = "coreos"
|
||||||
|
}
|
||||||
|
|
||||||
|
return platform, family, version, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func KernelVersion() (version string, err error) {
|
||||||
|
filename := common.HostProc("sys/kernel/osrelease")
|
||||||
|
if common.PathExists(filename) {
|
||||||
|
contents, err := common.ReadLines(filename)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(contents) > 0 {
|
||||||
|
version = contents[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return version, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRedhatishVersion(contents []string) string {
|
||||||
|
c := strings.ToLower(strings.Join(contents, ""))
|
||||||
|
|
||||||
|
if strings.Contains(c, "rawhide") {
|
||||||
|
return "rawhide"
|
||||||
|
}
|
||||||
|
if matches := regexp.MustCompile(`release (\d[\d.]*)`).FindStringSubmatch(c); matches != nil {
|
||||||
|
return matches[1]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRedhatishPlatform(contents []string) string {
|
||||||
|
c := strings.ToLower(strings.Join(contents, ""))
|
||||||
|
|
||||||
|
if strings.Contains(c, "red hat") {
|
||||||
|
return "redhat"
|
||||||
|
}
|
||||||
|
f := strings.Split(c, " ")
|
||||||
|
|
||||||
|
return f[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSuseVersion(contents []string) string {
|
||||||
|
version := ""
|
||||||
|
for _, line := range contents {
|
||||||
|
if matches := regexp.MustCompile(`VERSION = ([\d.]+)`).FindStringSubmatch(line); matches != nil {
|
||||||
|
version = matches[1]
|
||||||
|
} else if matches := regexp.MustCompile(`PATCHLEVEL = ([\d]+)`).FindStringSubmatch(line); matches != nil {
|
||||||
|
version = version + "." + matches[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return version
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSusePlatform(contents []string) string {
|
||||||
|
c := strings.ToLower(strings.Join(contents, ""))
|
||||||
|
if strings.Contains(c, "opensuse") {
|
||||||
|
return "opensuse"
|
||||||
|
}
|
||||||
|
return "suse"
|
||||||
|
}
|
||||||
|
|
||||||
|
func Virtualization() (string, string, error) {
|
||||||
|
var system string
|
||||||
|
var role string
|
||||||
|
|
||||||
|
filename := common.HostProc("xen")
|
||||||
|
if common.PathExists(filename) {
|
||||||
|
system = "xen"
|
||||||
|
role = "guest" // assume guest
|
||||||
|
|
||||||
|
if common.PathExists(filename + "/capabilities") {
|
||||||
|
contents, err := common.ReadLines(filename + "/capabilities")
|
||||||
|
if err == nil {
|
||||||
|
if common.StringsContains(contents, "control_d") {
|
||||||
|
role = "host"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filename = common.HostProc("modules")
|
||||||
|
if common.PathExists(filename) {
|
||||||
|
contents, err := common.ReadLines(filename)
|
||||||
|
if err == nil {
|
||||||
|
if common.StringsContains(contents, "kvm") {
|
||||||
|
system = "kvm"
|
||||||
|
role = "host"
|
||||||
|
} else if common.StringsContains(contents, "vboxdrv") {
|
||||||
|
system = "vbox"
|
||||||
|
role = "host"
|
||||||
|
} else if common.StringsContains(contents, "vboxguest") {
|
||||||
|
system = "vbox"
|
||||||
|
role = "guest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filename = common.HostProc("cpuinfo")
|
||||||
|
if common.PathExists(filename) {
|
||||||
|
contents, err := common.ReadLines(filename)
|
||||||
|
if err == nil {
|
||||||
|
if common.StringsContains(contents, "QEMU Virtual CPU") ||
|
||||||
|
common.StringsContains(contents, "Common KVM processor") ||
|
||||||
|
common.StringsContains(contents, "Common 32-bit KVM processor") {
|
||||||
|
system = "kvm"
|
||||||
|
role = "guest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filename = common.HostProc()
|
||||||
|
if common.PathExists(filename + "/bc/0") {
|
||||||
|
system = "openvz"
|
||||||
|
role = "host"
|
||||||
|
} else if common.PathExists(filename + "/vz") {
|
||||||
|
system = "openvz"
|
||||||
|
role = "guest"
|
||||||
|
}
|
||||||
|
|
||||||
|
// not use dmidecode because it requires root
|
||||||
|
if common.PathExists(filename + "/self/status") {
|
||||||
|
contents, err := common.ReadLines(filename + "/self/status")
|
||||||
|
if err == nil {
|
||||||
|
|
||||||
|
if common.StringsContains(contents, "s_context:") ||
|
||||||
|
common.StringsContains(contents, "VxID:") {
|
||||||
|
system = "linux-vserver"
|
||||||
|
}
|
||||||
|
// TODO: guest or host
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if common.PathExists(filename + "/self/cgroup") {
|
||||||
|
contents, err := common.ReadLines(filename + "/self/cgroup")
|
||||||
|
if err == nil {
|
||||||
|
if common.StringsContains(contents, "lxc") {
|
||||||
|
system = "lxc"
|
||||||
|
role = "guest"
|
||||||
|
} else if common.StringsContains(contents, "docker") {
|
||||||
|
system = "docker"
|
||||||
|
role = "guest"
|
||||||
|
} else if common.StringsContains(contents, "machine-rkt") {
|
||||||
|
system = "rkt"
|
||||||
|
role = "guest"
|
||||||
|
} else if common.PathExists("/usr/bin/lxc-version") {
|
||||||
|
system = "lxc"
|
||||||
|
role = "host"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if common.PathExists(common.HostEtc("os-release")) {
|
||||||
|
p, _, err := getOSRelease()
|
||||||
|
if err == nil && p == "coreos" {
|
||||||
|
system = "rkt" // Is it true?
|
||||||
|
role = "host"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return system, role, nil
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
// ATTENTION - FILE MANUAL FIXED AFTER CGO.
|
||||||
|
// Fixed line: Tv _Ctype_struct_timeval -> Tv UtTv
|
||||||
|
// Created by cgo -godefs, MANUAL FIXED
|
||||||
|
// cgo -godefs types_linux.go
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofPtr = 0x4
|
||||||
|
sizeofShort = 0x2
|
||||||
|
sizeofInt = 0x4
|
||||||
|
sizeofLong = 0x4
|
||||||
|
sizeofLongLong = 0x8
|
||||||
|
sizeOfUtmp = 0x180
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
_C_short int16
|
||||||
|
_C_int int32
|
||||||
|
_C_long int32
|
||||||
|
_C_long_long int64
|
||||||
|
)
|
||||||
|
|
||||||
|
type utmp struct {
|
||||||
|
Type int16
|
||||||
|
Pad_cgo_0 [2]byte
|
||||||
|
Pid int32
|
||||||
|
Line [32]int8
|
||||||
|
ID [4]int8
|
||||||
|
User [32]int8
|
||||||
|
Host [256]int8
|
||||||
|
Exit exit_status
|
||||||
|
Session int32
|
||||||
|
Tv UtTv
|
||||||
|
Addr_v6 [4]int32
|
||||||
|
X__unused [20]int8
|
||||||
|
}
|
||||||
|
type exit_status struct {
|
||||||
|
Termination int16
|
||||||
|
Exit int16
|
||||||
|
}
|
||||||
|
type UtTv struct {
|
||||||
|
Sec int32
|
||||||
|
Usec int32
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Created by cgo -godefs - DO NOT EDIT
|
||||||
|
// cgo -godefs types_linux.go
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofPtr = 0x8
|
||||||
|
sizeofShort = 0x2
|
||||||
|
sizeofInt = 0x4
|
||||||
|
sizeofLong = 0x8
|
||||||
|
sizeofLongLong = 0x8
|
||||||
|
sizeOfUtmp = 0x180
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
_C_short int16
|
||||||
|
_C_int int32
|
||||||
|
_C_long int64
|
||||||
|
_C_long_long int64
|
||||||
|
)
|
||||||
|
|
||||||
|
type utmp struct {
|
||||||
|
Type int16
|
||||||
|
Pad_cgo_0 [2]byte
|
||||||
|
Pid int32
|
||||||
|
Line [32]int8
|
||||||
|
Id [4]int8
|
||||||
|
User [32]int8
|
||||||
|
Host [256]int8
|
||||||
|
Exit exit_status
|
||||||
|
Session int32
|
||||||
|
Tv _Ctype_struct___0
|
||||||
|
Addr_v6 [4]int32
|
||||||
|
X__glibc_reserved [20]int8
|
||||||
|
}
|
||||||
|
type exit_status struct {
|
||||||
|
Termination int16
|
||||||
|
Exit int16
|
||||||
|
}
|
||||||
|
type timeval struct {
|
||||||
|
Sec int64
|
||||||
|
Usec int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type _Ctype_struct___0 struct {
|
||||||
|
Sec int32
|
||||||
|
Usec int32
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
// Created by cgo -godefs - DO NOT EDIT
|
||||||
|
// cgo -godefs types_linux.go | sed "s/uint8/int8/g"
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofPtr = 0x4
|
||||||
|
sizeofShort = 0x2
|
||||||
|
sizeofInt = 0x4
|
||||||
|
sizeofLong = 0x4
|
||||||
|
sizeofLongLong = 0x8
|
||||||
|
sizeOfUtmp = 0x180
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
_C_short int16
|
||||||
|
_C_int int32
|
||||||
|
_C_long int32
|
||||||
|
_C_long_long int64
|
||||||
|
)
|
||||||
|
|
||||||
|
type utmp struct {
|
||||||
|
Type int16
|
||||||
|
Pad_cgo_0 [2]byte
|
||||||
|
Pid int32
|
||||||
|
Line [32]int8
|
||||||
|
Id [4]int8
|
||||||
|
User [32]int8
|
||||||
|
Host [256]int8
|
||||||
|
Exit exit_status
|
||||||
|
Session int32
|
||||||
|
Tv timeval
|
||||||
|
Addr_v6 [4]int32
|
||||||
|
X__glibc_reserved [20]int8
|
||||||
|
}
|
||||||
|
type exit_status struct {
|
||||||
|
Termination int16
|
||||||
|
Exit int16
|
||||||
|
}
|
||||||
|
type timeval struct {
|
||||||
|
Sec int32
|
||||||
|
Usec int32
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
// Created by cgo -godefs - DO NOT EDIT
|
||||||
|
// cgo -godefs types_linux.go
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofPtr = 0x8
|
||||||
|
sizeofShort = 0x2
|
||||||
|
sizeofInt = 0x4
|
||||||
|
sizeofLong = 0x8
|
||||||
|
sizeofLongLong = 0x8
|
||||||
|
sizeOfUtmp = 0x180
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
_C_short int16
|
||||||
|
_C_int int32
|
||||||
|
_C_long int64
|
||||||
|
_C_long_long int64
|
||||||
|
)
|
||||||
|
|
||||||
|
type utmp struct {
|
||||||
|
Type int16
|
||||||
|
Pad_cgo_0 [2]byte
|
||||||
|
Pid int32
|
||||||
|
Line [32]int8
|
||||||
|
Id [4]int8
|
||||||
|
User [32]int8
|
||||||
|
Host [256]int8
|
||||||
|
Exit exit_status
|
||||||
|
Session int32
|
||||||
|
Tv timeval
|
||||||
|
Addr_v6 [4]int32
|
||||||
|
X__glibc_reserved [20]int8
|
||||||
|
}
|
||||||
|
type exit_status struct {
|
||||||
|
Termination int16
|
||||||
|
Exit int16
|
||||||
|
}
|
||||||
|
type timeval struct {
|
||||||
|
Sec int64
|
||||||
|
Usec int64
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
// +build linux
|
||||||
|
// +build ppc64le
|
||||||
|
// Created by cgo -godefs - DO NOT EDIT
|
||||||
|
// cgo -godefs types_linux.go
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofPtr = 0x8
|
||||||
|
sizeofShort = 0x2
|
||||||
|
sizeofInt = 0x4
|
||||||
|
sizeofLong = 0x8
|
||||||
|
sizeofLongLong = 0x8
|
||||||
|
sizeOfUtmp = 0x180
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
_C_short int16
|
||||||
|
_C_int int32
|
||||||
|
_C_long int64
|
||||||
|
_C_long_long int64
|
||||||
|
)
|
||||||
|
|
||||||
|
type utmp struct {
|
||||||
|
Type int16
|
||||||
|
Pad_cgo_0 [2]byte
|
||||||
|
Pid int32
|
||||||
|
Line [32]int8
|
||||||
|
Id [4]int8
|
||||||
|
User [32]int8
|
||||||
|
Host [256]int8
|
||||||
|
Exit exit_status
|
||||||
|
Session int32
|
||||||
|
Tv timeval
|
||||||
|
Addr_v6 [4]int32
|
||||||
|
X__glibc_reserved [20]int8
|
||||||
|
}
|
||||||
|
type exit_status struct {
|
||||||
|
Termination int16
|
||||||
|
Exit int16
|
||||||
|
}
|
||||||
|
type timeval struct {
|
||||||
|
Sec int64
|
||||||
|
Usec int64
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
// +build linux
|
||||||
|
// +build s390x
|
||||||
|
// Created by cgo -godefs - DO NOT EDIT
|
||||||
|
// cgo -godefs types_linux.go
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofPtr = 0x8
|
||||||
|
sizeofShort = 0x2
|
||||||
|
sizeofInt = 0x4
|
||||||
|
sizeofLong = 0x8
|
||||||
|
sizeofLongLong = 0x8
|
||||||
|
sizeOfUtmp = 0x180
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
_C_short int16
|
||||||
|
_C_int int32
|
||||||
|
_C_long int64
|
||||||
|
_C_long_long int64
|
||||||
|
)
|
||||||
|
|
||||||
|
type utmp struct {
|
||||||
|
Type int16
|
||||||
|
Pad_cgo_0 [2]byte
|
||||||
|
Pid int32
|
||||||
|
Line [32]int8
|
||||||
|
Id [4]int8
|
||||||
|
User [32]int8
|
||||||
|
Host [256]int8
|
||||||
|
Exit exit_status
|
||||||
|
Session int32
|
||||||
|
Tv timeval
|
||||||
|
Addr_v6 [4]int32
|
||||||
|
X__glibc_reserved [20]int8
|
||||||
|
}
|
||||||
|
type exit_status struct {
|
||||||
|
Termination int16
|
||||||
|
Exit int16
|
||||||
|
}
|
||||||
|
type timeval struct {
|
||||||
|
Sec int64
|
||||||
|
Usec int64
|
||||||
|
}
|
|
@ -0,0 +1,154 @@
|
||||||
|
// +build openbsd
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/shirou/gopsutil/internal/common"
|
||||||
|
"github.com/shirou/gopsutil/process"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
UTNameSize = 32 /* see MAXLOGNAME in <sys/param.h> */
|
||||||
|
UTLineSize = 8
|
||||||
|
UTHostSize = 16
|
||||||
|
)
|
||||||
|
|
||||||
|
func Info() (*InfoStat, error) {
|
||||||
|
ret := &InfoStat{
|
||||||
|
OS: runtime.GOOS,
|
||||||
|
PlatformFamily: "openbsd",
|
||||||
|
}
|
||||||
|
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err == nil {
|
||||||
|
ret.Hostname = hostname
|
||||||
|
}
|
||||||
|
|
||||||
|
platform, family, version, err := PlatformInformation()
|
||||||
|
if err == nil {
|
||||||
|
ret.Platform = platform
|
||||||
|
ret.PlatformFamily = family
|
||||||
|
ret.PlatformVersion = version
|
||||||
|
}
|
||||||
|
system, role, err := Virtualization()
|
||||||
|
if err == nil {
|
||||||
|
ret.VirtualizationSystem = system
|
||||||
|
ret.VirtualizationRole = role
|
||||||
|
}
|
||||||
|
|
||||||
|
procs, err := process.Pids()
|
||||||
|
if err == nil {
|
||||||
|
ret.Procs = uint64(len(procs))
|
||||||
|
}
|
||||||
|
|
||||||
|
boot, err := BootTime()
|
||||||
|
if err == nil {
|
||||||
|
ret.BootTime = boot
|
||||||
|
ret.Uptime = uptime(boot)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func BootTime() (uint64, error) {
|
||||||
|
val, err := common.DoSysctrl("kern.boottime")
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
boottime, err := strconv.ParseUint(val[0], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return boottime, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func uptime(boot uint64) uint64 {
|
||||||
|
return uint64(time.Now().Unix()) - boot
|
||||||
|
}
|
||||||
|
|
||||||
|
func Uptime() (uint64, error) {
|
||||||
|
boot, err := BootTime()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return uptime(boot), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func PlatformInformation() (string, string, string, error) {
|
||||||
|
platform := ""
|
||||||
|
family := ""
|
||||||
|
version := ""
|
||||||
|
uname, err := exec.LookPath("uname")
|
||||||
|
if err != nil {
|
||||||
|
return "", "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := invoke.Command(uname, "-s")
|
||||||
|
if err == nil {
|
||||||
|
platform = strings.ToLower(strings.TrimSpace(string(out)))
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err = invoke.Command(uname, "-r")
|
||||||
|
if err == nil {
|
||||||
|
version = strings.ToLower(strings.TrimSpace(string(out)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return platform, family, version, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Virtualization() (string, string, error) {
|
||||||
|
system := ""
|
||||||
|
role := ""
|
||||||
|
|
||||||
|
return system, role, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Users() ([]UserStat, error) {
|
||||||
|
var ret []UserStat
|
||||||
|
utmpfile := "/var/run/utmp"
|
||||||
|
file, err := os.Open(utmpfile)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
buf, err := ioutil.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
u := Utmp{}
|
||||||
|
entrySize := int(unsafe.Sizeof(u))
|
||||||
|
count := len(buf) / entrySize
|
||||||
|
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
b := buf[i*entrySize : i*entrySize+entrySize]
|
||||||
|
var u Utmp
|
||||||
|
br := bytes.NewReader(b)
|
||||||
|
err := binary.Read(br, binary.LittleEndian, &u)
|
||||||
|
if err != nil || u.Time == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
user := UserStat{
|
||||||
|
User: common.IntToString(u.Name[:]),
|
||||||
|
Terminal: common.IntToString(u.Line[:]),
|
||||||
|
Host: common.IntToString(u.Host[:]),
|
||||||
|
Started: int(u.Time),
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = append(ret, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
// Created by cgo -godefs - DO NOT EDIT
|
||||||
|
// cgo -godefs types_openbsd.go
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofPtr = 0x8
|
||||||
|
sizeofShort = 0x2
|
||||||
|
sizeofInt = 0x4
|
||||||
|
sizeofLong = 0x8
|
||||||
|
sizeofLongLong = 0x8
|
||||||
|
sizeOfUtmp = 0x130
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
_C_short int16
|
||||||
|
_C_int int32
|
||||||
|
_C_long int64
|
||||||
|
_C_long_long int64
|
||||||
|
)
|
||||||
|
|
||||||
|
type Utmp struct {
|
||||||
|
Line [8]int8
|
||||||
|
Name [32]int8
|
||||||
|
Host [256]int8
|
||||||
|
Time int64
|
||||||
|
}
|
||||||
|
type Timeval struct {
|
||||||
|
Sec int64
|
||||||
|
Usec int64
|
||||||
|
}
|
|
@ -0,0 +1,137 @@
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/StackExchange/wmi"
|
||||||
|
|
||||||
|
"github.com/shirou/gopsutil/internal/common"
|
||||||
|
process "github.com/shirou/gopsutil/process"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
procGetSystemTimeAsFileTime = common.Modkernel32.NewProc("GetSystemTimeAsFileTime")
|
||||||
|
osInfo *Win32_OperatingSystem
|
||||||
|
)
|
||||||
|
|
||||||
|
type Win32_OperatingSystem struct {
|
||||||
|
Version string
|
||||||
|
Caption string
|
||||||
|
ProductType uint32
|
||||||
|
BuildNumber string
|
||||||
|
LastBootUpTime time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func Info() (*InfoStat, error) {
|
||||||
|
ret := &InfoStat{
|
||||||
|
OS: runtime.GOOS,
|
||||||
|
}
|
||||||
|
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err == nil {
|
||||||
|
ret.Hostname = hostname
|
||||||
|
}
|
||||||
|
|
||||||
|
platform, family, version, err := PlatformInformation()
|
||||||
|
if err == nil {
|
||||||
|
ret.Platform = platform
|
||||||
|
ret.PlatformFamily = family
|
||||||
|
ret.PlatformVersion = version
|
||||||
|
} else {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
boot, err := BootTime()
|
||||||
|
if err == nil {
|
||||||
|
ret.BootTime = boot
|
||||||
|
ret.Uptime, _ = Uptime()
|
||||||
|
}
|
||||||
|
|
||||||
|
procs, err := process.Pids()
|
||||||
|
if err == nil {
|
||||||
|
ret.Procs = uint64(len(procs))
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetOSInfo() (Win32_OperatingSystem, error) {
|
||||||
|
var dst []Win32_OperatingSystem
|
||||||
|
q := wmi.CreateQuery(&dst, "")
|
||||||
|
err := wmi.Query(q, &dst)
|
||||||
|
if err != nil {
|
||||||
|
return Win32_OperatingSystem{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
osInfo = &dst[0]
|
||||||
|
|
||||||
|
return dst[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Uptime() (uint64, error) {
|
||||||
|
if osInfo == nil {
|
||||||
|
_, err := GetOSInfo()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
now := time.Now()
|
||||||
|
t := osInfo.LastBootUpTime.Local()
|
||||||
|
return uint64(now.Sub(t).Seconds()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func bootTime(up uint64) uint64 {
|
||||||
|
return uint64(time.Now().Unix()) - up
|
||||||
|
}
|
||||||
|
|
||||||
|
func BootTime() (uint64, error) {
|
||||||
|
if cachedBootTime != 0 {
|
||||||
|
return cachedBootTime, nil
|
||||||
|
}
|
||||||
|
up, err := Uptime()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
cachedBootTime = bootTime(up)
|
||||||
|
return cachedBootTime, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func PlatformInformation() (platform string, family string, version string, err error) {
|
||||||
|
if osInfo == nil {
|
||||||
|
_, err = GetOSInfo()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Platform
|
||||||
|
platform = strings.Trim(osInfo.Caption, " ")
|
||||||
|
|
||||||
|
// PlatformFamily
|
||||||
|
switch osInfo.ProductType {
|
||||||
|
case 1:
|
||||||
|
family = "Standalone Workstation"
|
||||||
|
case 2:
|
||||||
|
family = "Server (Domain Controller)"
|
||||||
|
case 3:
|
||||||
|
family = "Server"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Platform Version
|
||||||
|
version = fmt.Sprintf("%s Build %s", osInfo.Version, osInfo.BuildNumber)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Users() ([]UserStat, error) {
|
||||||
|
|
||||||
|
var ret []UserStat
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
// +build ignore
|
||||||
|
// plus hand editing about timeval
|
||||||
|
|
||||||
|
/*
|
||||||
|
Input to cgo -godefs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <utmpx.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
type Utmpx C.struct_utmpx
|
||||||
|
type Timeval C.struct_timeval
|
|
@ -0,0 +1,44 @@
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
/*
|
||||||
|
Input to cgo -godefs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define KERNEL
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <utmpx.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
sizeofPtr = sizeof(void*),
|
||||||
|
};
|
||||||
|
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
// Machine characteristics; for internal use.
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofPtr = C.sizeofPtr
|
||||||
|
sizeofShort = C.sizeof_short
|
||||||
|
sizeofInt = C.sizeof_int
|
||||||
|
sizeofLong = C.sizeof_long
|
||||||
|
sizeofLongLong = C.sizeof_longlong
|
||||||
|
sizeOfUtmpx = C.sizeof_struct_utmpx
|
||||||
|
)
|
||||||
|
|
||||||
|
// Basic types
|
||||||
|
|
||||||
|
type (
|
||||||
|
_C_short C.short
|
||||||
|
_C_int C.int
|
||||||
|
_C_long C.long
|
||||||
|
_C_long_long C.longlong
|
||||||
|
)
|
||||||
|
|
||||||
|
type Utmp C.struct_utmp
|
||||||
|
type Utmpx C.struct_utmpx
|
||||||
|
type Timeval C.struct_timeval
|
|
@ -0,0 +1,42 @@
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
/*
|
||||||
|
Input to cgo -godefs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <utmp.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
sizeofPtr = sizeof(void*),
|
||||||
|
};
|
||||||
|
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
// Machine characteristics; for internal use.
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofPtr = C.sizeofPtr
|
||||||
|
sizeofShort = C.sizeof_short
|
||||||
|
sizeofInt = C.sizeof_int
|
||||||
|
sizeofLong = C.sizeof_long
|
||||||
|
sizeofLongLong = C.sizeof_longlong
|
||||||
|
sizeOfUtmp = C.sizeof_struct_utmp
|
||||||
|
)
|
||||||
|
|
||||||
|
// Basic types
|
||||||
|
|
||||||
|
type (
|
||||||
|
_C_short C.short
|
||||||
|
_C_int C.int
|
||||||
|
_C_long C.long
|
||||||
|
_C_long_long C.longlong
|
||||||
|
)
|
||||||
|
|
||||||
|
type utmp C.struct_utmp
|
||||||
|
type exit_status C.struct_exit_status
|
||||||
|
type timeval C.struct_timeval
|
|
@ -0,0 +1,43 @@
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
/*
|
||||||
|
Input to cgo -godefs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define KERNEL
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <utmp.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
sizeofPtr = sizeof(void*),
|
||||||
|
};
|
||||||
|
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
// Machine characteristics; for internal use.
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofPtr = C.sizeofPtr
|
||||||
|
sizeofShort = C.sizeof_short
|
||||||
|
sizeofInt = C.sizeof_int
|
||||||
|
sizeofLong = C.sizeof_long
|
||||||
|
sizeofLongLong = C.sizeof_longlong
|
||||||
|
sizeOfUtmp = C.sizeof_struct_utmp
|
||||||
|
)
|
||||||
|
|
||||||
|
// Basic types
|
||||||
|
|
||||||
|
type (
|
||||||
|
_C_short C.short
|
||||||
|
_C_int C.int
|
||||||
|
_C_long C.long
|
||||||
|
_C_long_long C.longlong
|
||||||
|
)
|
||||||
|
|
||||||
|
type Utmp C.struct_utmp
|
||||||
|
type Timeval C.struct_timeval
|
|
@ -0,0 +1,634 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package binary implements simple translation between numbers and byte
|
||||||
|
// sequences and encoding and decoding of varints.
|
||||||
|
//
|
||||||
|
// Numbers are translated by reading and writing fixed-size values.
|
||||||
|
// A fixed-size value is either a fixed-size arithmetic
|
||||||
|
// type (int8, uint8, int16, float32, complex64, ...)
|
||||||
|
// or an array or struct containing only fixed-size values.
|
||||||
|
//
|
||||||
|
// The varint functions encode and decode single integer values using
|
||||||
|
// a variable-length encoding; smaller values require fewer bytes.
|
||||||
|
// For a specification, see
|
||||||
|
// http://code.google.com/apis/protocolbuffers/docs/encoding.html.
|
||||||
|
//
|
||||||
|
// This package favors simplicity over efficiency. Clients that require
|
||||||
|
// high-performance serialization, especially for large data structures,
|
||||||
|
// should look at more advanced solutions such as the encoding/gob
|
||||||
|
// package or protocol buffers.
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"math"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A ByteOrder specifies how to convert byte sequences into
|
||||||
|
// 16-, 32-, or 64-bit unsigned integers.
|
||||||
|
type ByteOrder interface {
|
||||||
|
Uint16([]byte) uint16
|
||||||
|
Uint32([]byte) uint32
|
||||||
|
Uint64([]byte) uint64
|
||||||
|
PutUint16([]byte, uint16)
|
||||||
|
PutUint32([]byte, uint32)
|
||||||
|
PutUint64([]byte, uint64)
|
||||||
|
String() string
|
||||||
|
}
|
||||||
|
|
||||||
|
// LittleEndian is the little-endian implementation of ByteOrder.
|
||||||
|
var LittleEndian littleEndian
|
||||||
|
|
||||||
|
// BigEndian is the big-endian implementation of ByteOrder.
|
||||||
|
var BigEndian bigEndian
|
||||||
|
|
||||||
|
type littleEndian struct{}
|
||||||
|
|
||||||
|
func (littleEndian) Uint16(b []byte) uint16 { return uint16(b[0]) | uint16(b[1])<<8 }
|
||||||
|
|
||||||
|
func (littleEndian) PutUint16(b []byte, v uint16) {
|
||||||
|
b[0] = byte(v)
|
||||||
|
b[1] = byte(v >> 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (littleEndian) Uint32(b []byte) uint32 {
|
||||||
|
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
|
||||||
|
}
|
||||||
|
|
||||||
|
func (littleEndian) PutUint32(b []byte, v uint32) {
|
||||||
|
b[0] = byte(v)
|
||||||
|
b[1] = byte(v >> 8)
|
||||||
|
b[2] = byte(v >> 16)
|
||||||
|
b[3] = byte(v >> 24)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (littleEndian) Uint64(b []byte) uint64 {
|
||||||
|
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
|
||||||
|
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
|
||||||
|
}
|
||||||
|
|
||||||
|
func (littleEndian) PutUint64(b []byte, v uint64) {
|
||||||
|
b[0] = byte(v)
|
||||||
|
b[1] = byte(v >> 8)
|
||||||
|
b[2] = byte(v >> 16)
|
||||||
|
b[3] = byte(v >> 24)
|
||||||
|
b[4] = byte(v >> 32)
|
||||||
|
b[5] = byte(v >> 40)
|
||||||
|
b[6] = byte(v >> 48)
|
||||||
|
b[7] = byte(v >> 56)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (littleEndian) String() string { return "LittleEndian" }
|
||||||
|
|
||||||
|
func (littleEndian) GoString() string { return "binary.LittleEndian" }
|
||||||
|
|
||||||
|
type bigEndian struct{}
|
||||||
|
|
||||||
|
func (bigEndian) Uint16(b []byte) uint16 { return uint16(b[1]) | uint16(b[0])<<8 }
|
||||||
|
|
||||||
|
func (bigEndian) PutUint16(b []byte, v uint16) {
|
||||||
|
b[0] = byte(v >> 8)
|
||||||
|
b[1] = byte(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bigEndian) Uint32(b []byte) uint32 {
|
||||||
|
return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bigEndian) PutUint32(b []byte, v uint32) {
|
||||||
|
b[0] = byte(v >> 24)
|
||||||
|
b[1] = byte(v >> 16)
|
||||||
|
b[2] = byte(v >> 8)
|
||||||
|
b[3] = byte(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bigEndian) Uint64(b []byte) uint64 {
|
||||||
|
return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
|
||||||
|
uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bigEndian) PutUint64(b []byte, v uint64) {
|
||||||
|
b[0] = byte(v >> 56)
|
||||||
|
b[1] = byte(v >> 48)
|
||||||
|
b[2] = byte(v >> 40)
|
||||||
|
b[3] = byte(v >> 32)
|
||||||
|
b[4] = byte(v >> 24)
|
||||||
|
b[5] = byte(v >> 16)
|
||||||
|
b[6] = byte(v >> 8)
|
||||||
|
b[7] = byte(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bigEndian) String() string { return "BigEndian" }
|
||||||
|
|
||||||
|
func (bigEndian) GoString() string { return "binary.BigEndian" }
|
||||||
|
|
||||||
|
// Read reads structured binary data from r into data.
|
||||||
|
// Data must be a pointer to a fixed-size value or a slice
|
||||||
|
// of fixed-size values.
|
||||||
|
// Bytes read from r are decoded using the specified byte order
|
||||||
|
// and written to successive fields of the data.
|
||||||
|
// When reading into structs, the field data for fields with
|
||||||
|
// blank (_) field names is skipped; i.e., blank field names
|
||||||
|
// may be used for padding.
|
||||||
|
// When reading into a struct, all non-blank fields must be exported.
|
||||||
|
func Read(r io.Reader, order ByteOrder, data interface{}) error {
|
||||||
|
// Fast path for basic types and slices.
|
||||||
|
if n := intDataSize(data); n != 0 {
|
||||||
|
var b [8]byte
|
||||||
|
var bs []byte
|
||||||
|
if n > len(b) {
|
||||||
|
bs = make([]byte, n)
|
||||||
|
} else {
|
||||||
|
bs = b[:n]
|
||||||
|
}
|
||||||
|
if _, err := io.ReadFull(r, bs); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch data := data.(type) {
|
||||||
|
case *int8:
|
||||||
|
*data = int8(b[0])
|
||||||
|
case *uint8:
|
||||||
|
*data = b[0]
|
||||||
|
case *int16:
|
||||||
|
*data = int16(order.Uint16(bs))
|
||||||
|
case *uint16:
|
||||||
|
*data = order.Uint16(bs)
|
||||||
|
case *int32:
|
||||||
|
*data = int32(order.Uint32(bs))
|
||||||
|
case *uint32:
|
||||||
|
*data = order.Uint32(bs)
|
||||||
|
case *int64:
|
||||||
|
*data = int64(order.Uint64(bs))
|
||||||
|
case *uint64:
|
||||||
|
*data = order.Uint64(bs)
|
||||||
|
case []int8:
|
||||||
|
for i, x := range bs { // Easier to loop over the input for 8-bit values.
|
||||||
|
data[i] = int8(x)
|
||||||
|
}
|
||||||
|
case []uint8:
|
||||||
|
copy(data, bs)
|
||||||
|
case []int16:
|
||||||
|
for i := range data {
|
||||||
|
data[i] = int16(order.Uint16(bs[2*i:]))
|
||||||
|
}
|
||||||
|
case []uint16:
|
||||||
|
for i := range data {
|
||||||
|
data[i] = order.Uint16(bs[2*i:])
|
||||||
|
}
|
||||||
|
case []int32:
|
||||||
|
for i := range data {
|
||||||
|
data[i] = int32(order.Uint32(bs[4*i:]))
|
||||||
|
}
|
||||||
|
case []uint32:
|
||||||
|
for i := range data {
|
||||||
|
data[i] = order.Uint32(bs[4*i:])
|
||||||
|
}
|
||||||
|
case []int64:
|
||||||
|
for i := range data {
|
||||||
|
data[i] = int64(order.Uint64(bs[8*i:]))
|
||||||
|
}
|
||||||
|
case []uint64:
|
||||||
|
for i := range data {
|
||||||
|
data[i] = order.Uint64(bs[8*i:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to reflect-based decoding.
|
||||||
|
v := reflect.ValueOf(data)
|
||||||
|
size := -1
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
v = v.Elem()
|
||||||
|
size = dataSize(v)
|
||||||
|
case reflect.Slice:
|
||||||
|
size = dataSize(v)
|
||||||
|
}
|
||||||
|
if size < 0 {
|
||||||
|
return errors.New("binary.Read: invalid type " + reflect.TypeOf(data).String())
|
||||||
|
}
|
||||||
|
d := &decoder{order: order, buf: make([]byte, size)}
|
||||||
|
if _, err := io.ReadFull(r, d.buf); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
d.value(v)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write writes the binary representation of data into w.
|
||||||
|
// Data must be a fixed-size value or a slice of fixed-size
|
||||||
|
// values, or a pointer to such data.
|
||||||
|
// Bytes written to w are encoded using the specified byte order
|
||||||
|
// and read from successive fields of the data.
|
||||||
|
// When writing structs, zero values are written for fields
|
||||||
|
// with blank (_) field names.
|
||||||
|
func Write(w io.Writer, order ByteOrder, data interface{}) error {
|
||||||
|
// Fast path for basic types and slices.
|
||||||
|
if n := intDataSize(data); n != 0 {
|
||||||
|
var b [8]byte
|
||||||
|
var bs []byte
|
||||||
|
if n > len(b) {
|
||||||
|
bs = make([]byte, n)
|
||||||
|
} else {
|
||||||
|
bs = b[:n]
|
||||||
|
}
|
||||||
|
switch v := data.(type) {
|
||||||
|
case *int8:
|
||||||
|
bs = b[:1]
|
||||||
|
b[0] = byte(*v)
|
||||||
|
case int8:
|
||||||
|
bs = b[:1]
|
||||||
|
b[0] = byte(v)
|
||||||
|
case []int8:
|
||||||
|
for i, x := range v {
|
||||||
|
bs[i] = byte(x)
|
||||||
|
}
|
||||||
|
case *uint8:
|
||||||
|
bs = b[:1]
|
||||||
|
b[0] = *v
|
||||||
|
case uint8:
|
||||||
|
bs = b[:1]
|
||||||
|
b[0] = byte(v)
|
||||||
|
case []uint8:
|
||||||
|
bs = v
|
||||||
|
case *int16:
|
||||||
|
bs = b[:2]
|
||||||
|
order.PutUint16(bs, uint16(*v))
|
||||||
|
case int16:
|
||||||
|
bs = b[:2]
|
||||||
|
order.PutUint16(bs, uint16(v))
|
||||||
|
case []int16:
|
||||||
|
for i, x := range v {
|
||||||
|
order.PutUint16(bs[2*i:], uint16(x))
|
||||||
|
}
|
||||||
|
case *uint16:
|
||||||
|
bs = b[:2]
|
||||||
|
order.PutUint16(bs, *v)
|
||||||
|
case uint16:
|
||||||
|
bs = b[:2]
|
||||||
|
order.PutUint16(bs, v)
|
||||||
|
case []uint16:
|
||||||
|
for i, x := range v {
|
||||||
|
order.PutUint16(bs[2*i:], x)
|
||||||
|
}
|
||||||
|
case *int32:
|
||||||
|
bs = b[:4]
|
||||||
|
order.PutUint32(bs, uint32(*v))
|
||||||
|
case int32:
|
||||||
|
bs = b[:4]
|
||||||
|
order.PutUint32(bs, uint32(v))
|
||||||
|
case []int32:
|
||||||
|
for i, x := range v {
|
||||||
|
order.PutUint32(bs[4*i:], uint32(x))
|
||||||
|
}
|
||||||
|
case *uint32:
|
||||||
|
bs = b[:4]
|
||||||
|
order.PutUint32(bs, *v)
|
||||||
|
case uint32:
|
||||||
|
bs = b[:4]
|
||||||
|
order.PutUint32(bs, v)
|
||||||
|
case []uint32:
|
||||||
|
for i, x := range v {
|
||||||
|
order.PutUint32(bs[4*i:], x)
|
||||||
|
}
|
||||||
|
case *int64:
|
||||||
|
bs = b[:8]
|
||||||
|
order.PutUint64(bs, uint64(*v))
|
||||||
|
case int64:
|
||||||
|
bs = b[:8]
|
||||||
|
order.PutUint64(bs, uint64(v))
|
||||||
|
case []int64:
|
||||||
|
for i, x := range v {
|
||||||
|
order.PutUint64(bs[8*i:], uint64(x))
|
||||||
|
}
|
||||||
|
case *uint64:
|
||||||
|
bs = b[:8]
|
||||||
|
order.PutUint64(bs, *v)
|
||||||
|
case uint64:
|
||||||
|
bs = b[:8]
|
||||||
|
order.PutUint64(bs, v)
|
||||||
|
case []uint64:
|
||||||
|
for i, x := range v {
|
||||||
|
order.PutUint64(bs[8*i:], x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err := w.Write(bs)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to reflect-based encoding.
|
||||||
|
v := reflect.Indirect(reflect.ValueOf(data))
|
||||||
|
size := dataSize(v)
|
||||||
|
if size < 0 {
|
||||||
|
return errors.New("binary.Write: invalid type " + reflect.TypeOf(data).String())
|
||||||
|
}
|
||||||
|
buf := make([]byte, size)
|
||||||
|
e := &encoder{order: order, buf: buf}
|
||||||
|
e.value(v)
|
||||||
|
_, err := w.Write(buf)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size returns how many bytes Write would generate to encode the value v, which
|
||||||
|
// must be a fixed-size value or a slice of fixed-size values, or a pointer to such data.
|
||||||
|
// If v is neither of these, Size returns -1.
|
||||||
|
func Size(v interface{}) int {
|
||||||
|
return dataSize(reflect.Indirect(reflect.ValueOf(v)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// dataSize returns the number of bytes the actual data represented by v occupies in memory.
|
||||||
|
// For compound structures, it sums the sizes of the elements. Thus, for instance, for a slice
|
||||||
|
// it returns the length of the slice times the element size and does not count the memory
|
||||||
|
// occupied by the header. If the type of v is not acceptable, dataSize returns -1.
|
||||||
|
func dataSize(v reflect.Value) int {
|
||||||
|
if v.Kind() == reflect.Slice {
|
||||||
|
if s := sizeof(v.Type().Elem()); s >= 0 {
|
||||||
|
return s * v.Len()
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return sizeof(v.Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
// sizeof returns the size >= 0 of variables for the given type or -1 if the type is not acceptable.
|
||||||
|
func sizeof(t reflect.Type) int {
|
||||||
|
switch t.Kind() {
|
||||||
|
case reflect.Array:
|
||||||
|
if s := sizeof(t.Elem()); s >= 0 {
|
||||||
|
return s * t.Len()
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Struct:
|
||||||
|
sum := 0
|
||||||
|
for i, n := 0, t.NumField(); i < n; i++ {
|
||||||
|
s := sizeof(t.Field(i).Type)
|
||||||
|
if s < 0 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
sum += s
|
||||||
|
}
|
||||||
|
return sum
|
||||||
|
|
||||||
|
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
|
||||||
|
reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||||
|
reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.Ptr:
|
||||||
|
return int(t.Size())
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
type coder struct {
|
||||||
|
order ByteOrder
|
||||||
|
buf []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type decoder coder
|
||||||
|
type encoder coder
|
||||||
|
|
||||||
|
func (d *decoder) uint8() uint8 {
|
||||||
|
x := d.buf[0]
|
||||||
|
d.buf = d.buf[1:]
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *encoder) uint8(x uint8) {
|
||||||
|
e.buf[0] = x
|
||||||
|
e.buf = e.buf[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *decoder) uint16() uint16 {
|
||||||
|
x := d.order.Uint16(d.buf[0:2])
|
||||||
|
d.buf = d.buf[2:]
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *encoder) uint16(x uint16) {
|
||||||
|
e.order.PutUint16(e.buf[0:2], x)
|
||||||
|
e.buf = e.buf[2:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *decoder) uint32() uint32 {
|
||||||
|
x := d.order.Uint32(d.buf[0:4])
|
||||||
|
d.buf = d.buf[4:]
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *encoder) uint32(x uint32) {
|
||||||
|
e.order.PutUint32(e.buf[0:4], x)
|
||||||
|
e.buf = e.buf[4:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *decoder) uint64() uint64 {
|
||||||
|
x := d.order.Uint64(d.buf[0:8])
|
||||||
|
d.buf = d.buf[8:]
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *encoder) uint64(x uint64) {
|
||||||
|
e.order.PutUint64(e.buf[0:8], x)
|
||||||
|
e.buf = e.buf[8:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *decoder) int8() int8 { return int8(d.uint8()) }
|
||||||
|
|
||||||
|
func (e *encoder) int8(x int8) { e.uint8(uint8(x)) }
|
||||||
|
|
||||||
|
func (d *decoder) int16() int16 { return int16(d.uint16()) }
|
||||||
|
|
||||||
|
func (e *encoder) int16(x int16) { e.uint16(uint16(x)) }
|
||||||
|
|
||||||
|
func (d *decoder) int32() int32 { return int32(d.uint32()) }
|
||||||
|
|
||||||
|
func (e *encoder) int32(x int32) { e.uint32(uint32(x)) }
|
||||||
|
|
||||||
|
func (d *decoder) int64() int64 { return int64(d.uint64()) }
|
||||||
|
|
||||||
|
func (e *encoder) int64(x int64) { e.uint64(uint64(x)) }
|
||||||
|
|
||||||
|
func (d *decoder) value(v reflect.Value) {
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Array:
|
||||||
|
l := v.Len()
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
d.value(v.Index(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Struct:
|
||||||
|
t := v.Type()
|
||||||
|
l := v.NumField()
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
// Note: Calling v.CanSet() below is an optimization.
|
||||||
|
// It would be sufficient to check the field name,
|
||||||
|
// but creating the StructField info for each field is
|
||||||
|
// costly (run "go test -bench=ReadStruct" and compare
|
||||||
|
// results when making changes to this code).
|
||||||
|
if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
|
||||||
|
d.value(v)
|
||||||
|
} else {
|
||||||
|
d.skip(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Slice:
|
||||||
|
l := v.Len()
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
d.value(v.Index(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Int8:
|
||||||
|
v.SetInt(int64(d.int8()))
|
||||||
|
case reflect.Int16:
|
||||||
|
v.SetInt(int64(d.int16()))
|
||||||
|
case reflect.Int32:
|
||||||
|
v.SetInt(int64(d.int32()))
|
||||||
|
case reflect.Int64:
|
||||||
|
v.SetInt(d.int64())
|
||||||
|
|
||||||
|
case reflect.Uint8:
|
||||||
|
v.SetUint(uint64(d.uint8()))
|
||||||
|
case reflect.Uint16:
|
||||||
|
v.SetUint(uint64(d.uint16()))
|
||||||
|
case reflect.Uint32:
|
||||||
|
v.SetUint(uint64(d.uint32()))
|
||||||
|
case reflect.Uint64:
|
||||||
|
v.SetUint(d.uint64())
|
||||||
|
|
||||||
|
case reflect.Float32:
|
||||||
|
v.SetFloat(float64(math.Float32frombits(d.uint32())))
|
||||||
|
case reflect.Float64:
|
||||||
|
v.SetFloat(math.Float64frombits(d.uint64()))
|
||||||
|
|
||||||
|
case reflect.Complex64:
|
||||||
|
v.SetComplex(complex(
|
||||||
|
float64(math.Float32frombits(d.uint32())),
|
||||||
|
float64(math.Float32frombits(d.uint32())),
|
||||||
|
))
|
||||||
|
case reflect.Complex128:
|
||||||
|
v.SetComplex(complex(
|
||||||
|
math.Float64frombits(d.uint64()),
|
||||||
|
math.Float64frombits(d.uint64()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *encoder) value(v reflect.Value) {
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Array:
|
||||||
|
l := v.Len()
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
e.value(v.Index(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Struct:
|
||||||
|
t := v.Type()
|
||||||
|
l := v.NumField()
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
// see comment for corresponding code in decoder.value()
|
||||||
|
if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
|
||||||
|
e.value(v)
|
||||||
|
} else {
|
||||||
|
e.skip(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Slice:
|
||||||
|
l := v.Len()
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
e.value(v.Index(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
switch v.Type().Kind() {
|
||||||
|
case reflect.Int8:
|
||||||
|
e.int8(int8(v.Int()))
|
||||||
|
case reflect.Int16:
|
||||||
|
e.int16(int16(v.Int()))
|
||||||
|
case reflect.Int32:
|
||||||
|
e.int32(int32(v.Int()))
|
||||||
|
case reflect.Int64:
|
||||||
|
e.int64(v.Int())
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
switch v.Type().Kind() {
|
||||||
|
case reflect.Uint8:
|
||||||
|
e.uint8(uint8(v.Uint()))
|
||||||
|
case reflect.Uint16:
|
||||||
|
e.uint16(uint16(v.Uint()))
|
||||||
|
case reflect.Uint32:
|
||||||
|
e.uint32(uint32(v.Uint()))
|
||||||
|
case reflect.Uint64:
|
||||||
|
e.uint64(v.Uint())
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
switch v.Type().Kind() {
|
||||||
|
case reflect.Float32:
|
||||||
|
e.uint32(math.Float32bits(float32(v.Float())))
|
||||||
|
case reflect.Float64:
|
||||||
|
e.uint64(math.Float64bits(v.Float()))
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Complex64, reflect.Complex128:
|
||||||
|
switch v.Type().Kind() {
|
||||||
|
case reflect.Complex64:
|
||||||
|
x := v.Complex()
|
||||||
|
e.uint32(math.Float32bits(float32(real(x))))
|
||||||
|
e.uint32(math.Float32bits(float32(imag(x))))
|
||||||
|
case reflect.Complex128:
|
||||||
|
x := v.Complex()
|
||||||
|
e.uint64(math.Float64bits(real(x)))
|
||||||
|
e.uint64(math.Float64bits(imag(x)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *decoder) skip(v reflect.Value) {
|
||||||
|
d.buf = d.buf[dataSize(v):]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *encoder) skip(v reflect.Value) {
|
||||||
|
n := dataSize(v)
|
||||||
|
for i := range e.buf[0:n] {
|
||||||
|
e.buf[i] = 0
|
||||||
|
}
|
||||||
|
e.buf = e.buf[n:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// intDataSize returns the size of the data required to represent the data when encoded.
|
||||||
|
// It returns zero if the type cannot be implemented by the fast path in Read or Write.
|
||||||
|
func intDataSize(data interface{}) int {
|
||||||
|
switch data := data.(type) {
|
||||||
|
case int8, *int8, *uint8:
|
||||||
|
return 1
|
||||||
|
case []int8:
|
||||||
|
return len(data)
|
||||||
|
case []uint8:
|
||||||
|
return len(data)
|
||||||
|
case int16, *int16, *uint16:
|
||||||
|
return 2
|
||||||
|
case []int16:
|
||||||
|
return 2 * len(data)
|
||||||
|
case []uint16:
|
||||||
|
return 2 * len(data)
|
||||||
|
case int32, *int32, *uint32:
|
||||||
|
return 4
|
||||||
|
case []int32:
|
||||||
|
return 4 * len(data)
|
||||||
|
case []uint32:
|
||||||
|
return 4 * len(data)
|
||||||
|
case int64, *int64, *uint64:
|
||||||
|
return 8
|
||||||
|
case []int64:
|
||||||
|
return 8 * len(data)
|
||||||
|
case []uint64:
|
||||||
|
return 8 * len(data)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
|
@ -0,0 +1,386 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
//
|
||||||
|
// gopsutil is a port of psutil(http://pythonhosted.org/psutil/).
|
||||||
|
// This covers these architectures.
|
||||||
|
// - linux (amd64, arm)
|
||||||
|
// - freebsd (amd64)
|
||||||
|
// - windows (amd64)
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Timeout = 3 * time.Second
|
||||||
|
ErrTimeout = errors.New("Command timed out.")
|
||||||
|
)
|
||||||
|
|
||||||
|
type Invoker interface {
|
||||||
|
Command(string, ...string) ([]byte, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Invoke struct{}
|
||||||
|
|
||||||
|
func (i Invoke) Command(name string, arg ...string) ([]byte, error) {
|
||||||
|
cmd := exec.Command(name, arg...)
|
||||||
|
return CombinedOutputTimeout(cmd, Timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
type FakeInvoke struct {
|
||||||
|
CommandExpectedDir string // CommandExpectedDir specifies dir which includes expected outputs.
|
||||||
|
Suffix string // Suffix species expected file name suffix such as "fail"
|
||||||
|
Error error // If Error specfied, return the error.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Command in FakeInvoke returns from expected file if exists.
|
||||||
|
func (i FakeInvoke) Command(name string, arg ...string) ([]byte, error) {
|
||||||
|
if i.Error != nil {
|
||||||
|
return []byte{}, i.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
arch := runtime.GOOS
|
||||||
|
|
||||||
|
fname := strings.Join(append([]string{name}, arg...), "")
|
||||||
|
fname = url.QueryEscape(fname)
|
||||||
|
var dir string
|
||||||
|
if i.CommandExpectedDir == "" {
|
||||||
|
dir = "expected"
|
||||||
|
} else {
|
||||||
|
dir = i.CommandExpectedDir
|
||||||
|
}
|
||||||
|
fpath := path.Join(dir, arch, fname)
|
||||||
|
if i.Suffix != "" {
|
||||||
|
fpath += "_" + i.Suffix
|
||||||
|
}
|
||||||
|
if PathExists(fpath) {
|
||||||
|
return ioutil.ReadFile(fpath)
|
||||||
|
}
|
||||||
|
return exec.Command(name, arg...).Output()
|
||||||
|
}
|
||||||
|
|
||||||
|
var ErrNotImplementedError = errors.New("not implemented yet")
|
||||||
|
|
||||||
|
// ReadLines reads contents from a file and splits them by new lines.
|
||||||
|
// A convenience wrapper to ReadLinesOffsetN(filename, 0, -1).
|
||||||
|
func ReadLines(filename string) ([]string, error) {
|
||||||
|
return ReadLinesOffsetN(filename, 0, -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadLines reads contents from file and splits them by new line.
|
||||||
|
// The offset tells at which line number to start.
|
||||||
|
// The count determines the number of lines to read (starting from offset):
|
||||||
|
// n >= 0: at most n lines
|
||||||
|
// n < 0: whole file
|
||||||
|
func ReadLinesOffsetN(filename string, offset uint, n int) ([]string, error) {
|
||||||
|
f, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return []string{""}, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
var ret []string
|
||||||
|
|
||||||
|
r := bufio.NewReader(f)
|
||||||
|
for i := 0; i < n+int(offset) || n < 0; i++ {
|
||||||
|
line, err := r.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if i < int(offset) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ret = append(ret, strings.Trim(line, "\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func IntToString(orig []int8) string {
|
||||||
|
ret := make([]byte, len(orig))
|
||||||
|
size := -1
|
||||||
|
for i, o := range orig {
|
||||||
|
if o == 0 {
|
||||||
|
size = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
ret[i] = byte(o)
|
||||||
|
}
|
||||||
|
if size == -1 {
|
||||||
|
size = len(orig)
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(ret[0:size])
|
||||||
|
}
|
||||||
|
|
||||||
|
func UintToString(orig []uint8) string {
|
||||||
|
ret := make([]byte, len(orig))
|
||||||
|
size := -1
|
||||||
|
for i, o := range orig {
|
||||||
|
if o == 0 {
|
||||||
|
size = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
ret[i] = byte(o)
|
||||||
|
}
|
||||||
|
if size == -1 {
|
||||||
|
size = len(orig)
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(ret[0:size])
|
||||||
|
}
|
||||||
|
|
||||||
|
func ByteToString(orig []byte) string {
|
||||||
|
n := -1
|
||||||
|
l := -1
|
||||||
|
for i, b := range orig {
|
||||||
|
// skip left side null
|
||||||
|
if l == -1 && b == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if l == -1 {
|
||||||
|
l = i
|
||||||
|
}
|
||||||
|
|
||||||
|
if b == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
n = i + 1
|
||||||
|
}
|
||||||
|
if n == -1 {
|
||||||
|
return string(orig)
|
||||||
|
}
|
||||||
|
return string(orig[l:n])
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadInts reads contents from single line file and returns them as []int32.
|
||||||
|
func ReadInts(filename string) ([]int64, error) {
|
||||||
|
f, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return []int64{}, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
var ret []int64
|
||||||
|
|
||||||
|
r := bufio.NewReader(f)
|
||||||
|
|
||||||
|
// The int files that this is concerned with should only be one liners.
|
||||||
|
line, err := r.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
return []int64{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
i, err := strconv.ParseInt(strings.Trim(line, "\n"), 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return []int64{}, err
|
||||||
|
}
|
||||||
|
ret = append(ret, i)
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse to int32 without error
|
||||||
|
func mustParseInt32(val string) int32 {
|
||||||
|
vv, _ := strconv.ParseInt(val, 10, 32)
|
||||||
|
return int32(vv)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse to uint64 without error
|
||||||
|
func mustParseUint64(val string) uint64 {
|
||||||
|
vv, _ := strconv.ParseInt(val, 10, 64)
|
||||||
|
return uint64(vv)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse to Float64 without error
|
||||||
|
func mustParseFloat64(val string) float64 {
|
||||||
|
vv, _ := strconv.ParseFloat(val, 64)
|
||||||
|
return vv
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringsHas checks the target string slice contains src or not
|
||||||
|
func StringsHas(target []string, src string) bool {
|
||||||
|
for _, t := range target {
|
||||||
|
if strings.TrimSpace(t) == src {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringsContains checks the src in any string of the target string slice
|
||||||
|
func StringsContains(target []string, src string) bool {
|
||||||
|
for _, t := range target {
|
||||||
|
if strings.Contains(t, src) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// IntContains checks the src in any int of the target int slice.
|
||||||
|
func IntContains(target []int, src int) bool {
|
||||||
|
for _, t := range target {
|
||||||
|
if src == t {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// get struct attributes.
|
||||||
|
// This method is used only for debugging platform dependent code.
|
||||||
|
func attributes(m interface{}) map[string]reflect.Type {
|
||||||
|
typ := reflect.TypeOf(m)
|
||||||
|
if typ.Kind() == reflect.Ptr {
|
||||||
|
typ = typ.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
attrs := make(map[string]reflect.Type)
|
||||||
|
if typ.Kind() != reflect.Struct {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < typ.NumField(); i++ {
|
||||||
|
p := typ.Field(i)
|
||||||
|
if !p.Anonymous {
|
||||||
|
attrs[p.Name] = p.Type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return attrs
|
||||||
|
}
|
||||||
|
|
||||||
|
func PathExists(filename string) bool {
|
||||||
|
if _, err := os.Stat(filename); err == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
//GetEnv retrieves the environment variable key. If it does not exist it returns the default.
|
||||||
|
func GetEnv(key string, dfault string, combineWith ...string) string {
|
||||||
|
value := os.Getenv(key)
|
||||||
|
if value == "" {
|
||||||
|
value = dfault
|
||||||
|
}
|
||||||
|
|
||||||
|
switch len(combineWith) {
|
||||||
|
case 0:
|
||||||
|
return value
|
||||||
|
case 1:
|
||||||
|
return filepath.Join(value, combineWith[0])
|
||||||
|
default:
|
||||||
|
all := make([]string, len(combineWith)+1)
|
||||||
|
all[0] = value
|
||||||
|
copy(all[1:], combineWith)
|
||||||
|
return filepath.Join(all...)
|
||||||
|
}
|
||||||
|
panic("invalid switch case")
|
||||||
|
}
|
||||||
|
|
||||||
|
func HostProc(combineWith ...string) string {
|
||||||
|
return GetEnv("HOST_PROC", "/proc", combineWith...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HostSys(combineWith ...string) string {
|
||||||
|
return GetEnv("HOST_SYS", "/sys", combineWith...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HostEtc(combineWith ...string) string {
|
||||||
|
return GetEnv("HOST_ETC", "/etc", combineWith...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CombinedOutputTimeout runs the given command with the given timeout and
|
||||||
|
// returns the combined output of stdout and stderr.
|
||||||
|
// If the command times out, it attempts to kill the process.
|
||||||
|
// copied from https://github.com/influxdata/telegraf
|
||||||
|
func CombinedOutputTimeout(c *exec.Cmd, timeout time.Duration) ([]byte, error) {
|
||||||
|
var b bytes.Buffer
|
||||||
|
c.Stdout = &b
|
||||||
|
c.Stderr = &b
|
||||||
|
if err := c.Start(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err := WaitTimeout(c, timeout)
|
||||||
|
return b.Bytes(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaitTimeout waits for the given command to finish with a timeout.
|
||||||
|
// It assumes the command has already been started.
|
||||||
|
// If the command times out, it attempts to kill the process.
|
||||||
|
// copied from https://github.com/influxdata/telegraf
|
||||||
|
func WaitTimeout(c *exec.Cmd, timeout time.Duration) error {
|
||||||
|
timer := time.NewTimer(timeout)
|
||||||
|
done := make(chan error)
|
||||||
|
go func() { done <- c.Wait() }()
|
||||||
|
select {
|
||||||
|
case err := <-done:
|
||||||
|
timer.Stop()
|
||||||
|
return err
|
||||||
|
case <-timer.C:
|
||||||
|
if err := c.Process.Kill(); err != nil {
|
||||||
|
log.Printf("FATAL error killing process: %s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// wait for the command to return after killing it
|
||||||
|
<-done
|
||||||
|
return ErrTimeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://gist.github.com/kylelemons/1525278
|
||||||
|
func Pipeline(cmds ...*exec.Cmd) ([]byte, []byte, error) {
|
||||||
|
// Require at least one command
|
||||||
|
if len(cmds) < 1 {
|
||||||
|
return nil, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect the output from the command(s)
|
||||||
|
var output bytes.Buffer
|
||||||
|
var stderr bytes.Buffer
|
||||||
|
|
||||||
|
last := len(cmds) - 1
|
||||||
|
for i, cmd := range cmds[:last] {
|
||||||
|
var err error
|
||||||
|
// Connect each command's stdin to the previous command's stdout
|
||||||
|
if cmds[i+1].Stdin, err = cmd.StdoutPipe(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
// Connect each command's stderr to a buffer
|
||||||
|
cmd.Stderr = &stderr
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect the output and error for the last command
|
||||||
|
cmds[last].Stdout, cmds[last].Stderr = &output, &stderr
|
||||||
|
|
||||||
|
// Start each command
|
||||||
|
for _, cmd := range cmds {
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
return output.Bytes(), stderr.Bytes(), err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for each command to complete
|
||||||
|
for _, cmd := range cmds {
|
||||||
|
if err := cmd.Wait(); err != nil {
|
||||||
|
return output.Bytes(), stderr.Bytes(), err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the pipeline output and the collected standard error
|
||||||
|
return output.Bytes(), stderr.Bytes(), nil
|
||||||
|
}
|
70
vendor/github.com/shirou/gopsutil/internal/common/common_darwin.go
generated
vendored
Normal file
70
vendor/github.com/shirou/gopsutil/internal/common/common_darwin.go
generated
vendored
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
// +build darwin
|
||||||
|
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DoSysctrl(mib string) ([]string, error) {
|
||||||
|
err := os.Setenv("LC_ALL", "C")
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sysctl, err := exec.LookPath("/usr/sbin/sysctl")
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, err
|
||||||
|
}
|
||||||
|
out, err := exec.Command(sysctl, "-n", mib).Output()
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, err
|
||||||
|
}
|
||||||
|
v := strings.Replace(string(out), "{ ", "", 1)
|
||||||
|
v = strings.Replace(string(v), " }", "", 1)
|
||||||
|
values := strings.Fields(string(v))
|
||||||
|
|
||||||
|
return values, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CallSyscall(mib []int32) ([]byte, uint64, error) {
|
||||||
|
miblen := uint64(len(mib))
|
||||||
|
|
||||||
|
// get required buffer size
|
||||||
|
length := uint64(0)
|
||||||
|
_, _, err := syscall.Syscall6(
|
||||||
|
syscall.SYS___SYSCTL,
|
||||||
|
uintptr(unsafe.Pointer(&mib[0])),
|
||||||
|
uintptr(miblen),
|
||||||
|
0,
|
||||||
|
uintptr(unsafe.Pointer(&length)),
|
||||||
|
0,
|
||||||
|
0)
|
||||||
|
if err != 0 {
|
||||||
|
var b []byte
|
||||||
|
return b, length, err
|
||||||
|
}
|
||||||
|
if length == 0 {
|
||||||
|
var b []byte
|
||||||
|
return b, length, err
|
||||||
|
}
|
||||||
|
// get proc info itself
|
||||||
|
buf := make([]byte, length)
|
||||||
|
_, _, err = syscall.Syscall6(
|
||||||
|
syscall.SYS___SYSCTL,
|
||||||
|
uintptr(unsafe.Pointer(&mib[0])),
|
||||||
|
uintptr(miblen),
|
||||||
|
uintptr(unsafe.Pointer(&buf[0])),
|
||||||
|
uintptr(unsafe.Pointer(&length)),
|
||||||
|
0,
|
||||||
|
0)
|
||||||
|
if err != 0 {
|
||||||
|
return buf, length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf, length, nil
|
||||||
|
}
|
70
vendor/github.com/shirou/gopsutil/internal/common/common_freebsd.go
generated
vendored
Normal file
70
vendor/github.com/shirou/gopsutil/internal/common/common_freebsd.go
generated
vendored
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
// +build freebsd openbsd
|
||||||
|
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DoSysctrl(mib string) ([]string, error) {
|
||||||
|
err := os.Setenv("LC_ALL", "C")
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, err
|
||||||
|
}
|
||||||
|
sysctl, err := exec.LookPath("/sbin/sysctl")
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, err
|
||||||
|
}
|
||||||
|
out, err := exec.Command(sysctl, "-n", mib).Output()
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, err
|
||||||
|
}
|
||||||
|
v := strings.Replace(string(out), "{ ", "", 1)
|
||||||
|
v = strings.Replace(string(v), " }", "", 1)
|
||||||
|
values := strings.Fields(string(v))
|
||||||
|
|
||||||
|
return values, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CallSyscall(mib []int32) ([]byte, uint64, error) {
|
||||||
|
mibptr := unsafe.Pointer(&mib[0])
|
||||||
|
miblen := uint64(len(mib))
|
||||||
|
|
||||||
|
// get required buffer size
|
||||||
|
length := uint64(0)
|
||||||
|
_, _, err := syscall.Syscall6(
|
||||||
|
syscall.SYS___SYSCTL,
|
||||||
|
uintptr(mibptr),
|
||||||
|
uintptr(miblen),
|
||||||
|
0,
|
||||||
|
uintptr(unsafe.Pointer(&length)),
|
||||||
|
0,
|
||||||
|
0)
|
||||||
|
if err != 0 {
|
||||||
|
var b []byte
|
||||||
|
return b, length, err
|
||||||
|
}
|
||||||
|
if length == 0 {
|
||||||
|
var b []byte
|
||||||
|
return b, length, err
|
||||||
|
}
|
||||||
|
// get proc info itself
|
||||||
|
buf := make([]byte, length)
|
||||||
|
_, _, err = syscall.Syscall6(
|
||||||
|
syscall.SYS___SYSCTL,
|
||||||
|
uintptr(mibptr),
|
||||||
|
uintptr(miblen),
|
||||||
|
uintptr(unsafe.Pointer(&buf[0])),
|
||||||
|
uintptr(unsafe.Pointer(&length)),
|
||||||
|
0,
|
||||||
|
0)
|
||||||
|
if err != 0 {
|
||||||
|
return buf, length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf, length, nil
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DoSysctrl(mib string) ([]string, error) {
|
||||||
|
err := os.Setenv("LC_ALL", "C")
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, err
|
||||||
|
}
|
||||||
|
sysctl, err := exec.LookPath("/sbin/sysctl")
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, err
|
||||||
|
}
|
||||||
|
out, err := exec.Command(sysctl, "-n", mib).Output()
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, err
|
||||||
|
}
|
||||||
|
v := strings.Replace(string(out), "{ ", "", 1)
|
||||||
|
v = strings.Replace(string(v), " }", "", 1)
|
||||||
|
values := strings.Fields(string(v))
|
||||||
|
|
||||||
|
return values, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NumProcs() (uint64, error) {
|
||||||
|
f, err := os.Open(HostProc())
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
list, err := f.Readdir(-1)
|
||||||
|
defer f.Close()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return uint64(len(list)), err
|
||||||
|
}
|
70
vendor/github.com/shirou/gopsutil/internal/common/common_openbsd.go
generated
vendored
Normal file
70
vendor/github.com/shirou/gopsutil/internal/common/common_openbsd.go
generated
vendored
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
// +build openbsd
|
||||||
|
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DoSysctrl(mib string) ([]string, error) {
|
||||||
|
err := os.Setenv("LC_ALL", "C")
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, err
|
||||||
|
}
|
||||||
|
sysctl, err := exec.LookPath("/sbin/sysctl")
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, err
|
||||||
|
}
|
||||||
|
out, err := exec.Command(sysctl, "-n", mib).Output()
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, err
|
||||||
|
}
|
||||||
|
v := strings.Replace(string(out), "{ ", "", 1)
|
||||||
|
v = strings.Replace(string(v), " }", "", 1)
|
||||||
|
values := strings.Fields(string(v))
|
||||||
|
|
||||||
|
return values, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CallSyscall(mib []int32) ([]byte, uint64, error) {
|
||||||
|
mibptr := unsafe.Pointer(&mib[0])
|
||||||
|
miblen := uint64(len(mib))
|
||||||
|
|
||||||
|
// get required buffer size
|
||||||
|
length := uint64(0)
|
||||||
|
_, _, err := syscall.Syscall6(
|
||||||
|
syscall.SYS___SYSCTL,
|
||||||
|
uintptr(mibptr),
|
||||||
|
uintptr(miblen),
|
||||||
|
0,
|
||||||
|
uintptr(unsafe.Pointer(&length)),
|
||||||
|
0,
|
||||||
|
0)
|
||||||
|
if err != 0 {
|
||||||
|
var b []byte
|
||||||
|
return b, length, err
|
||||||
|
}
|
||||||
|
if length == 0 {
|
||||||
|
var b []byte
|
||||||
|
return b, length, err
|
||||||
|
}
|
||||||
|
// get proc info itself
|
||||||
|
buf := make([]byte, length)
|
||||||
|
_, _, err = syscall.Syscall6(
|
||||||
|
syscall.SYS___SYSCTL,
|
||||||
|
uintptr(mibptr),
|
||||||
|
uintptr(miblen),
|
||||||
|
uintptr(unsafe.Pointer(&buf[0])),
|
||||||
|
uintptr(unsafe.Pointer(&length)),
|
||||||
|
0,
|
||||||
|
0)
|
||||||
|
if err != 0 {
|
||||||
|
return buf, length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf, length, nil
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
// +build linux freebsd darwin openbsd
|
||||||
|
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CallLsof(invoke Invoker, pid int32, args ...string) ([]string, error) {
|
||||||
|
var cmd []string
|
||||||
|
if pid == 0 { // will get from all processes.
|
||||||
|
cmd = []string{"-a", "-n", "-P"}
|
||||||
|
} else {
|
||||||
|
cmd = []string{"-a", "-n", "-P", "-p", strconv.Itoa(int(pid))}
|
||||||
|
}
|
||||||
|
cmd = append(cmd, args...)
|
||||||
|
lsof, err := exec.LookPath("lsof")
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, err
|
||||||
|
}
|
||||||
|
out, err := invoke.Command(lsof, cmd...)
|
||||||
|
if err != nil {
|
||||||
|
// if no pid found, lsof returnes code 1.
|
||||||
|
if err.Error() == "exit status 1" && len(out) == 0 {
|
||||||
|
return []string{}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lines := strings.Split(string(out), "\n")
|
||||||
|
|
||||||
|
var ret []string
|
||||||
|
for _, l := range lines[1:] {
|
||||||
|
if len(l) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ret = append(ret, l)
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CallPgrep(invoke Invoker, pid int32) ([]int32, error) {
|
||||||
|
var cmd []string
|
||||||
|
cmd = []string{"-P", strconv.Itoa(int(pid))}
|
||||||
|
pgrep, err := exec.LookPath("pgrep")
|
||||||
|
if err != nil {
|
||||||
|
return []int32{}, err
|
||||||
|
}
|
||||||
|
out, err := invoke.Command(pgrep, cmd...)
|
||||||
|
if err != nil {
|
||||||
|
return []int32{}, err
|
||||||
|
}
|
||||||
|
lines := strings.Split(string(out), "\n")
|
||||||
|
ret := make([]int32, 0, len(lines))
|
||||||
|
for _, l := range lines {
|
||||||
|
if len(l) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
i, err := strconv.Atoi(l)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ret = append(ret, int32(i))
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
110
vendor/github.com/shirou/gopsutil/internal/common/common_windows.go
generated
vendored
Normal file
110
vendor/github.com/shirou/gopsutil/internal/common/common_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// for double values
|
||||||
|
type PDH_FMT_COUNTERVALUE_DOUBLE struct {
|
||||||
|
CStatus uint32
|
||||||
|
DoubleValue float64
|
||||||
|
}
|
||||||
|
|
||||||
|
// for 64 bit integer values
|
||||||
|
type PDH_FMT_COUNTERVALUE_LARGE struct {
|
||||||
|
CStatus uint32
|
||||||
|
LargeValue int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// for long values
|
||||||
|
type PDH_FMT_COUNTERVALUE_LONG struct {
|
||||||
|
CStatus uint32
|
||||||
|
LongValue int32
|
||||||
|
padding [4]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// windows system const
|
||||||
|
const (
|
||||||
|
ERROR_SUCCESS = 0
|
||||||
|
ERROR_FILE_NOT_FOUND = 2
|
||||||
|
DRIVE_REMOVABLE = 2
|
||||||
|
DRIVE_FIXED = 3
|
||||||
|
HKEY_LOCAL_MACHINE = 0x80000002
|
||||||
|
RRF_RT_REG_SZ = 0x00000002
|
||||||
|
RRF_RT_REG_DWORD = 0x00000010
|
||||||
|
PDH_FMT_LONG = 0x00000100
|
||||||
|
PDH_FMT_DOUBLE = 0x00000200
|
||||||
|
PDH_FMT_LARGE = 0x00000400
|
||||||
|
PDH_INVALID_DATA = 0xc0000bc6
|
||||||
|
PDH_INVALID_HANDLE = 0xC0000bbc
|
||||||
|
PDH_NO_DATA = 0x800007d5
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Modkernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||||
|
ModNt = syscall.NewLazyDLL("ntdll.dll")
|
||||||
|
ModPdh = syscall.NewLazyDLL("pdh.dll")
|
||||||
|
|
||||||
|
ProcGetSystemTimes = Modkernel32.NewProc("GetSystemTimes")
|
||||||
|
ProcNtQuerySystemInformation = ModNt.NewProc("NtQuerySystemInformation")
|
||||||
|
PdhOpenQuery = ModPdh.NewProc("PdhOpenQuery")
|
||||||
|
PdhAddCounter = ModPdh.NewProc("PdhAddCounterW")
|
||||||
|
PdhCollectQueryData = ModPdh.NewProc("PdhCollectQueryData")
|
||||||
|
PdhGetFormattedCounterValue = ModPdh.NewProc("PdhGetFormattedCounterValue")
|
||||||
|
PdhCloseQuery = ModPdh.NewProc("PdhCloseQuery")
|
||||||
|
)
|
||||||
|
|
||||||
|
type FILETIME struct {
|
||||||
|
DwLowDateTime uint32
|
||||||
|
DwHighDateTime uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// borrowed from net/interface_windows.go
|
||||||
|
func BytePtrToString(p *uint8) string {
|
||||||
|
a := (*[10000]uint8)(unsafe.Pointer(p))
|
||||||
|
i := 0
|
||||||
|
for a[i] != 0 {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return string(a[:i])
|
||||||
|
}
|
||||||
|
|
||||||
|
// CounterInfo
|
||||||
|
// copied from https://github.com/mackerelio/mackerel-agent/
|
||||||
|
type CounterInfo struct {
|
||||||
|
PostName string
|
||||||
|
CounterName string
|
||||||
|
Counter syscall.Handle
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateQuery XXX
|
||||||
|
// copied from https://github.com/mackerelio/mackerel-agent/
|
||||||
|
func CreateQuery() (syscall.Handle, error) {
|
||||||
|
var query syscall.Handle
|
||||||
|
r, _, err := PdhOpenQuery.Call(0, 0, uintptr(unsafe.Pointer(&query)))
|
||||||
|
if r != 0 {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return query, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateCounter XXX
|
||||||
|
func CreateCounter(query syscall.Handle, pname, cname string) (*CounterInfo, error) {
|
||||||
|
var counter syscall.Handle
|
||||||
|
r, _, err := PdhAddCounter.Call(
|
||||||
|
uintptr(query),
|
||||||
|
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(cname))),
|
||||||
|
0,
|
||||||
|
uintptr(unsafe.Pointer(&counter)))
|
||||||
|
if r != 0 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &CounterInfo{
|
||||||
|
PostName: pname,
|
||||||
|
CounterName: cname,
|
||||||
|
Counter: counter,
|
||||||
|
}, nil
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
|
||||||
|
DIRS="cpu disk docker host load mem net process"
|
||||||
|
|
||||||
|
GOOS=`uname | tr '[:upper:]' '[:lower:]'`
|
||||||
|
ARCH=`uname -m`
|
||||||
|
|
||||||
|
case $ARCH in
|
||||||
|
amd64)
|
||||||
|
GOARCH="amd64"
|
||||||
|
;;
|
||||||
|
x86_64)
|
||||||
|
GOARCH="amd64"
|
||||||
|
;;
|
||||||
|
i386)
|
||||||
|
GOARCH="386"
|
||||||
|
;;
|
||||||
|
i686)
|
||||||
|
GOARCH="386"
|
||||||
|
;;
|
||||||
|
arm)
|
||||||
|
GOARCH="arm"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "unknown arch: $ARCH"
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
|
|
||||||
|
for DIR in $DIRS
|
||||||
|
do
|
||||||
|
if [ -e ${DIR}/types_${GOOS}.go ]; then
|
||||||
|
echo "// +build $GOOS" > ${DIR}/${DIR}_${GOOS}_${GOARCH}.go
|
||||||
|
echo "// +build $GOARCH" >> ${DIR}/${DIR}_${GOOS}_${GOARCH}.go
|
||||||
|
go tool cgo -godefs ${DIR}/types_${GOOS}.go >> ${DIR}/${DIR}_${GOOS}_${GOARCH}.go
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
# This script is a helper of migration to gopsutil v2 using gorename
|
||||||
|
#
|
||||||
|
# go get golang.org/x/tools/cmd/gorename
|
||||||
|
|
||||||
|
IFS=$'\n'
|
||||||
|
|
||||||
|
## Part 1. rename Functions to pass golint. ex) cpu.CPUTimesStat -> cpu.TimesStat
|
||||||
|
|
||||||
|
#
|
||||||
|
# Note:
|
||||||
|
# process has IOCounters() for file IO, and also NetIOCounters() for Net IO.
|
||||||
|
# This scripts replace process.NetIOCounters() to IOCounters().
|
||||||
|
# So you need hand-fixing process.
|
||||||
|
|
||||||
|
TARGETS=`cat <<EOF
|
||||||
|
CPUTimesStat -> TimesStat
|
||||||
|
CPUInfoStat -> InfoStat
|
||||||
|
CPUTimes -> Times
|
||||||
|
CPUInfo -> Info
|
||||||
|
CPUCounts -> Counts
|
||||||
|
CPUPercent -> Percent
|
||||||
|
DiskUsageStat -> UsageStat
|
||||||
|
DiskPartitionStat -> PartitionStat
|
||||||
|
DiskIOCountersStat -> IOCountersStat
|
||||||
|
DiskPartitions -> Partitions
|
||||||
|
DiskIOCounters -> IOCounters
|
||||||
|
DiskUsage -> Usage
|
||||||
|
HostInfoStat -> InfoStat
|
||||||
|
HostInfo -> Info
|
||||||
|
GetVirtualization -> Virtualization
|
||||||
|
GetPlatformInformation -> PlatformInformation
|
||||||
|
LoadAvgStat -> AvgStat
|
||||||
|
LoadAvg -> Avg
|
||||||
|
NetIOCountersStat -> IOCountersStat
|
||||||
|
NetConnectionStat -> ConnectionStat
|
||||||
|
NetProtoCountersStat -> ProtoCountersStat
|
||||||
|
NetInterfaceAddr -> InterfaceAddr
|
||||||
|
NetInterfaceStat -> InterfaceStat
|
||||||
|
NetFilterStat -> FilterStat
|
||||||
|
NetInterfaces -> Interfaces
|
||||||
|
getNetIOCountersAll -> getIOCountersAll
|
||||||
|
NetIOCounters -> IOCounters
|
||||||
|
NetIOCountersByFile -> IOCountersByFile
|
||||||
|
NetProtoCounters -> ProtoCounters
|
||||||
|
NetFilterCounters -> FilterCounters
|
||||||
|
NetConnections -> Connections
|
||||||
|
NetConnectionsPid -> ConnectionsPid
|
||||||
|
Uid -> UID
|
||||||
|
Id -> ID
|
||||||
|
convertCpuTimes -> convertCPUTimes
|
||||||
|
EOF`
|
||||||
|
|
||||||
|
for T in $TARGETS
|
||||||
|
do
|
||||||
|
echo $T
|
||||||
|
gofmt -w -r "$T" ./*.go
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
###### Part 2 rename JSON key name
|
||||||
|
## Google JSOn style
|
||||||
|
## https://google.github.io/styleguide/jsoncstyleguide.xml
|
||||||
|
|
||||||
|
sed -i "" 's/guest_nice/guestNice/g' cpu/*.go
|
||||||
|
sed -i "" 's/vendor_id/vendorId/g' cpu/*.go
|
||||||
|
sed -i "" 's/physical_id/physicalId/g' cpu/*.go
|
||||||
|
sed -i "" 's/model_name/modelName/g' cpu/*.go
|
||||||
|
sed -i "" 's/cache_size/cacheSize/g' cpu/*.go
|
||||||
|
sed -i "" 's/core_id/coreId/g' cpu/*.go
|
||||||
|
|
||||||
|
sed -i "" 's/inodes_total/inodesTotal/g' disk/*.go
|
||||||
|
sed -i "" 's/inodes_used/inodesUsed/g' disk/*.go
|
||||||
|
sed -i "" 's/inodes_free/inodesFree/g' disk/*.go
|
||||||
|
sed -i "" 's/inodes_used_percent/inodesUsedPercent/g' disk/*.go
|
||||||
|
sed -i "" 's/read_count/readCount/g' disk/*.go
|
||||||
|
sed -i "" 's/write_count/writeCount/g' disk/*.go
|
||||||
|
sed -i "" 's/read_bytes/readBytes/g' disk/*.go
|
||||||
|
sed -i "" 's/write_bytes/writeBytes/g' disk/*.go
|
||||||
|
sed -i "" 's/read_time/readTime/g' disk/*.go
|
||||||
|
sed -i "" 's/write_time/writeTime/g' disk/*.go
|
||||||
|
sed -i "" 's/io_time/ioTime/g' disk/*.go
|
||||||
|
sed -i "" 's/serial_number/serialNumber/g' disk/*.go
|
||||||
|
sed -i "" 's/used_percent/usedPercent/g' disk/*.go
|
||||||
|
sed -i "" 's/inodesUsed_percent/inodesUsedPercent/g' disk/*.go
|
||||||
|
|
||||||
|
sed -i "" 's/total_cache/totalCache/g' docker/*.go
|
||||||
|
sed -i "" 's/total_rss_huge/totalRssHuge/g' docker/*.go
|
||||||
|
sed -i "" 's/total_rss/totalRss/g' docker/*.go
|
||||||
|
sed -i "" 's/total_mapped_file/totalMappedFile/g' docker/*.go
|
||||||
|
sed -i "" 's/total_pgpgin/totalPgpgin/g' docker/*.go
|
||||||
|
sed -i "" 's/total_pgpgout/totalPgpgout/g' docker/*.go
|
||||||
|
sed -i "" 's/total_pgfault/totalPgfault/g' docker/*.go
|
||||||
|
sed -i "" 's/total_pgmajfault/totalPgmajfault/g' docker/*.go
|
||||||
|
sed -i "" 's/total_inactive_anon/totalInactiveAnon/g' docker/*.go
|
||||||
|
sed -i "" 's/total_active_anon/totalActiveAnon/g' docker/*.go
|
||||||
|
sed -i "" 's/total_inactive_file/totalInactiveFile/g' docker/*.go
|
||||||
|
sed -i "" 's/total_active_file/totalActiveFile/g' docker/*.go
|
||||||
|
sed -i "" 's/total_unevictable/totalUnevictable/g' docker/*.go
|
||||||
|
sed -i "" 's/mem_usage_in_bytes/memUsageInBytes/g' docker/*.go
|
||||||
|
sed -i "" 's/mem_max_usage_in_bytes/memMaxUsageInBytes/g' docker/*.go
|
||||||
|
sed -i "" 's/memory.limit_in_bytes/memoryLimitInBbytes/g' docker/*.go
|
||||||
|
sed -i "" 's/memory.failcnt/memoryFailcnt/g' docker/*.go
|
||||||
|
sed -i "" 's/mapped_file/mappedFile/g' docker/*.go
|
||||||
|
sed -i "" 's/container_id/containerID/g' docker/*.go
|
||||||
|
sed -i "" 's/rss_huge/rssHuge/g' docker/*.go
|
||||||
|
sed -i "" 's/inactive_anon/inactiveAnon/g' docker/*.go
|
||||||
|
sed -i "" 's/active_anon/activeAnon/g' docker/*.go
|
||||||
|
sed -i "" 's/inactive_file/inactiveFile/g' docker/*.go
|
||||||
|
sed -i "" 's/active_file/activeFile/g' docker/*.go
|
||||||
|
sed -i "" 's/hierarchical_memory_limit/hierarchicalMemoryLimit/g' docker/*.go
|
||||||
|
|
||||||
|
sed -i "" 's/boot_time/bootTime/g' host/*.go
|
||||||
|
sed -i "" 's/platform_family/platformFamily/g' host/*.go
|
||||||
|
sed -i "" 's/platform_version/platformVersion/g' host/*.go
|
||||||
|
sed -i "" 's/virtualization_system/virtualizationSystem/g' host/*.go
|
||||||
|
sed -i "" 's/virtualization_role/virtualizationRole/g' host/*.go
|
||||||
|
|
||||||
|
sed -i "" 's/used_percent/usedPercent/g' mem/*.go
|
||||||
|
|
||||||
|
sed -i "" 's/bytes_sent/bytesSent/g' net/*.go
|
||||||
|
sed -i "" 's/bytes_recv/bytesRecv/g' net/*.go
|
||||||
|
sed -i "" 's/packets_sent/packetsSent/g' net/*.go
|
||||||
|
sed -i "" 's/packets_recv/packetsRecv/g' net/*.go
|
||||||
|
sed -i "" 's/conntrack_count/conntrackCount/g' net/*.go
|
||||||
|
sed -i "" 's/conntrack_max/conntrackMax/g' net/*.go
|
||||||
|
|
||||||
|
sed -i "" 's/read_count/readCount/g' process/*.go
|
||||||
|
sed -i "" 's/write_count/writeCount/g' process/*.go
|
||||||
|
sed -i "" 's/read_bytes/readBytes/g' process/*.go
|
||||||
|
sed -i "" 's/write_bytes/writeBytes/g' process/*.go
|
||||||
|
sed -i "" 's/shared_clean/sharedClean/g' process/*.go
|
||||||
|
sed -i "" 's/shared_dirty/sharedDirty/g' process/*.go
|
||||||
|
sed -i "" 's/private_clean/privateClean/g' process/*.go
|
||||||
|
sed -i "" 's/private_dirty/privateDirty/g' process/*.go
|
|
@ -0,0 +1,36 @@
|
||||||
|
Windows memo
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Size
|
||||||
|
----------
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
32-bit unsigned integer
|
||||||
|
DWORDLONG
|
||||||
|
64-bit unsigned integer
|
||||||
|
DWORD_PTR
|
||||||
|
unsigned long type for pointer precision
|
||||||
|
DWORD32
|
||||||
|
32-bit unsigned integer
|
||||||
|
DWORD64
|
||||||
|
64-bit unsigned integer
|
||||||
|
HALF_PTR
|
||||||
|
_WIN64 = int, else short
|
||||||
|
INT
|
||||||
|
32-bit signed integer
|
||||||
|
INT_PTR
|
||||||
|
_WIN64 = __int64 else int
|
||||||
|
LONG
|
||||||
|
32-bit signed integer
|
||||||
|
LONGLONG
|
||||||
|
64-bit signed integer
|
||||||
|
LONG_PTR
|
||||||
|
_WIN64 = __int64 else long
|
||||||
|
SHORT
|
||||||
|
16-bit integer
|
||||||
|
SIZE_T
|
||||||
|
maximum number of bytes to which a pointer can point. typedef ULONG_PTR SIZE_T;
|
||||||
|
SSIZE_T
|
||||||
|
signed version of SIZE_T. typedef LONG_PTR SSIZE_T;
|
||||||
|
WORD
|
||||||
|
16-bit unsigned integer
|
|
@ -674,6 +674,24 @@
|
||||||
"revision": "9b3edd62028f107d7cabb19353292afd29311a4e",
|
"revision": "9b3edd62028f107d7cabb19353292afd29311a4e",
|
||||||
"revisionTime": "2016-07-12T16:32:29Z"
|
"revisionTime": "2016-07-12T16:32:29Z"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "HoB8jOyjbTgm03BTbwkwqH+lrXs=",
|
||||||
|
"path": "github.com/shirou/gopsutil",
|
||||||
|
"revision": "70a1b78fe69202d93d6718fc9e3a4d6f81edfd58",
|
||||||
|
"revisionTime": "2017-01-30T15:34:44Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "74PIzS+la5td63oGs74K66mQ7hk=",
|
||||||
|
"path": "github.com/shirou/gopsutil/host",
|
||||||
|
"revision": "70a1b78fe69202d93d6718fc9e3a4d6f81edfd58",
|
||||||
|
"revisionTime": "2017-01-30T15:34:44Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "F4xYQ60JlmamCUSCJl7zuuq58Kw=",
|
||||||
|
"path": "github.com/shirou/gopsutil/internal/common",
|
||||||
|
"revision": "70a1b78fe69202d93d6718fc9e3a4d6f81edfd58",
|
||||||
|
"revisionTime": "2017-01-30T15:34:44Z"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "9jjO5GjLa0XF/nfWihF02RoH4qc=",
|
"checksumSHA1": "9jjO5GjLa0XF/nfWihF02RoH4qc=",
|
||||||
"path": "golang.org/x/net/context",
|
"path": "golang.org/x/net/context",
|
||||||
|
|
Loading…
Reference in New Issue