mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-05-22 20:40:23 +08:00
Conflicts: pkg/appsrv/appsrv.go pkg/cloudcommon/policy/defaults.go pkg/util/sysutils/sysutils.go
253 lines
5.5 KiB
Go
253 lines
5.5 KiB
Go
package sysutils
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"os"
|
|
"os/exec"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"yunion.io/x/jsonutils"
|
|
"yunion.io/x/log"
|
|
|
|
"yunion.io/x/onecloud/pkg/cloudcommon/types"
|
|
"yunion.io/x/onecloud/pkg/compute/baremetal"
|
|
)
|
|
|
|
func valueOfKeyword(line string, key string) *string {
|
|
lo := strings.ToLower(line)
|
|
ko := strings.ToLower(key)
|
|
pos := strings.Index(lo, ko)
|
|
if pos >= 0 {
|
|
val := strings.TrimSpace(line[pos+len(key):])
|
|
return &val
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func DumpMapToObject(data map[string]string, obj interface{}) error {
|
|
return jsonutils.Marshal(data).Unmarshal(obj)
|
|
}
|
|
|
|
func ParseDMISysinfo(lines []string) (*types.SDMISystemInfo, error) {
|
|
if len(lines) == 0 {
|
|
return nil, fmt.Errorf("Empty input")
|
|
}
|
|
keys := map[string]string{
|
|
"manufacture": "Manufacturer:",
|
|
"model": "Product Name:",
|
|
"version": "Version:",
|
|
"sn": "Serial Number:",
|
|
}
|
|
ret := make(map[string]string)
|
|
for _, line := range lines {
|
|
for key, keyword := range keys {
|
|
val := valueOfKeyword(line, keyword)
|
|
if val != nil {
|
|
ret[key] = *val
|
|
}
|
|
}
|
|
}
|
|
info := types.SDMISystemInfo{}
|
|
err := DumpMapToObject(ret, &info)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if strings.ToLower(info.Version) == "none" {
|
|
info.Version = ""
|
|
}
|
|
return &info, nil
|
|
}
|
|
|
|
func ParseCPUInfo(lines []string) (*types.SCPUInfo, error) {
|
|
cnt := 0
|
|
var (
|
|
model string
|
|
freq string
|
|
cache string
|
|
)
|
|
lv := func(line string) string {
|
|
return strings.TrimSpace(line[strings.Index(line, ":")+1:])
|
|
}
|
|
for _, line := range lines {
|
|
if len(model) == 0 && strings.HasPrefix(line, "model name") {
|
|
model = lv(line)
|
|
}
|
|
if len(freq) == 0 && strings.HasPrefix(line, "cpu MHz") {
|
|
freq = lv(line)
|
|
}
|
|
if len(cache) == 0 && strings.HasPrefix(line, "cache size") {
|
|
cache = strings.TrimSpace(line[strings.Index(line, ":")+1 : strings.Index(line, " KB")])
|
|
}
|
|
if strings.HasPrefix(line, "processor") {
|
|
cnt += 1
|
|
}
|
|
}
|
|
if len(model) == 0 {
|
|
return nil, fmt.Errorf("Not found model name")
|
|
}
|
|
if len(freq) == 0 {
|
|
return nil, fmt.Errorf("Not found cpu MHz")
|
|
}
|
|
if len(cache) == 0 {
|
|
return nil, fmt.Errorf("Not found cache size")
|
|
}
|
|
model = strings.TrimSpace(model)
|
|
info := &types.SCPUInfo{
|
|
Count: cnt,
|
|
Model: model,
|
|
}
|
|
info.Cache, _ = strconv.Atoi(cache)
|
|
freqF, _ := strconv.ParseFloat(freq, 32)
|
|
info.Freq = int(freqF)
|
|
return info, nil
|
|
}
|
|
|
|
func ParseDMICPUInfo(lines []string) *types.SDMICPUInfo {
|
|
cnt := 0
|
|
for _, line := range lines {
|
|
if strings.HasPrefix(line, "Processor Information") {
|
|
cnt += 1
|
|
}
|
|
}
|
|
return &types.SDMICPUInfo{
|
|
Nodes: cnt,
|
|
}
|
|
}
|
|
|
|
func ParseDMIMemInfo(lines []string) *types.SDMIMemInfo {
|
|
size := 0
|
|
for _, line := range lines {
|
|
val := valueOfKeyword(line, "Size:")
|
|
if val == nil {
|
|
continue
|
|
}
|
|
value := strings.ToLower(*val)
|
|
if strings.HasSuffix(value, " mb") {
|
|
sizeMb, err := strconv.Atoi(strings.TrimSuffix(value, " mb"))
|
|
if err != nil {
|
|
log.Errorf("parse MB error: %v", err)
|
|
continue
|
|
}
|
|
size += sizeMb
|
|
} else if strings.HasSuffix(value, " gb") {
|
|
sizeGb, err := strconv.Atoi(strings.TrimSuffix(value, " gb"))
|
|
if err != nil {
|
|
log.Errorf("parse GB error: %v", err)
|
|
continue
|
|
}
|
|
size += sizeGb * 1024
|
|
}
|
|
}
|
|
return &types.SDMIMemInfo{Total: size}
|
|
}
|
|
|
|
func ParseDMIIPMIInfo(lines []string) bool {
|
|
for _, line := range lines {
|
|
val := valueOfKeyword(line, "Interface Type:")
|
|
if val != nil {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func ParseNicInfo(lines []string) []*types.SNicDevInfo {
|
|
ret := make([]*types.SNicDevInfo, 0)
|
|
for _, line := range lines {
|
|
dat := strings.Split(line, " ")
|
|
if len(dat) > 4 {
|
|
dev := dat[0]
|
|
mac, _ := net.ParseMAC(dat[1])
|
|
speed, _ := strconv.Atoi(dat[2])
|
|
up := false
|
|
if dat[3] == "1" {
|
|
up = true
|
|
}
|
|
mtu, _ := strconv.Atoi(dat[4])
|
|
ret = append(ret, &types.SNicDevInfo{
|
|
Dev: dev,
|
|
Mac: mac,
|
|
Speed: speed,
|
|
Up: up,
|
|
Mtu: mtu,
|
|
})
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func ParseDiskInfo(lines []string, driver string) []*types.SDiskInfo {
|
|
ret := make([]*types.SDiskInfo, 0)
|
|
for _, line := range lines {
|
|
data := strings.Split(line, " ")
|
|
if len(data) <= 6 {
|
|
continue
|
|
}
|
|
dev := data[0]
|
|
sector, _ := strconv.Atoi(data[1])
|
|
size := sector * 512 / 1024 / 1024
|
|
block, _ := strconv.Atoi(data[2])
|
|
rotate := false
|
|
if data[3] == "1" {
|
|
rotate = true
|
|
}
|
|
kernel := data[4]
|
|
pciCls := data[5]
|
|
modinfo := strings.Join(data[6:], " ")
|
|
ret = append(ret, &types.SDiskInfo{
|
|
Dev: dev,
|
|
Sector: int64(sector),
|
|
Block: int64(block),
|
|
Size: int64(size),
|
|
Rotate: rotate,
|
|
ModuleInfo: modinfo,
|
|
Kernel: kernel,
|
|
PCIClass: pciCls,
|
|
Driver: driver,
|
|
})
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func ParsePCIEDiskInfo(lines []string) []*types.SDiskInfo {
|
|
return ParseDiskInfo(lines, baremetal.DISK_DRIVER_PCIE)
|
|
}
|
|
|
|
func ParseSCSIDiskInfo(lines []string) []*types.SDiskInfo {
|
|
return ParseDiskInfo(lines, baremetal.DISK_DRIVER_LINUX)
|
|
}
|
|
|
|
func GetSerialPorts(lines []string) []string {
|
|
ret := []string{}
|
|
for _, l := range lines {
|
|
if strings.Contains(l, "CTS") {
|
|
pos := strings.Index(l, ":")
|
|
if pos < 0 {
|
|
continue
|
|
}
|
|
idx := l[0:pos]
|
|
ret = append(ret, fmt.Sprintf("ttyS%s", idx))
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func Start(closeFd bool, args ...string) (p *os.Process, err error) {
|
|
if args[0], err = exec.LookPath(args[0]); err == nil {
|
|
var procAttr os.ProcAttr
|
|
if closeFd {
|
|
procAttr.Files = []*os.File{nil, nil, nil}
|
|
} else {
|
|
procAttr.Files = []*os.File{os.Stdin,
|
|
os.Stdout, os.Stderr}
|
|
}
|
|
p, err := os.StartProcess(args[0], args, &procAttr)
|
|
if err == nil {
|
|
return p, nil
|
|
}
|
|
}
|
|
return nil, err
|
|
}
|