1 Star 0 Fork 0

liucxer/ceph-tools

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
main.go 6.08 KB
一键复制 编辑 原始数据 按行查看 历史
刘昌喜 提交于 2023-03-02 19:48 +08:00 . 增加rados统计功能
package main
import (
"errors"
"fmt"
"github.com/go-cmd/cmd"
"github.com/sirupsen/logrus"
"io/ioutil"
"runtime"
"sort"
"strings"
"time"
)
var LineSeparator string
func init() {
switch runtime.GOOS {
case "windows":
LineSeparator = "\r\n"
case "android", "darwin", "freebsd", "linux", "netbsd", "openbsd", "solaris":
LineSeparator = "\n"
}
}
type CmdStatus struct {
Cmd string `json:"cmd"`
PID int `json:"pid"`
Complete bool `json:"complete"` // false if stopped or signaled
Exit int `json:"exit"` // exit code of process
Error error `json:"error" swaggertype:"string"` // Go error
StartTs int64 `json:"startTs"` // Unix ts (nanoseconds), zero if Cmd not started
StopTs int64 `json:"stopTs"` // Unix ts (nanoseconds), zero if Cmd not started or running
Runtime float64 `json:"runtime"` // seconds, zero if Cmd not started
StdoutLines []string `json:"stdout_lines"`
StderrLines []string `json:"stderr_lines"`
Stderr string `json:"stderr"`
Stdout string `json:"stdout"`
}
var (
DefaultTimeOut = int64(30)
)
type Option func(opts *Options)
type Options struct {
Timeout int64
}
func WithTimeoutOption(timeout int64) Option {
return func(opts *Options) {
opts.Timeout = timeout
}
}
func loadOptions(options ...Option) *Options {
opts := new(Options)
for _, option := range options {
option(opts)
}
return opts
}
// RemoveEmptyElm 数组去除空白元素
func RemoveEmptyElm(arr []string) []string {
var ret []string
if len(arr) == 0 {
return ret
}
for _, val := range arr {
if len(val) != 0 {
ret = append(ret, val)
}
}
return ret
}
func SyncExecute(cmdStr string, options ...Option) (*CmdStatus, error) {
var (
res CmdStatus
err error
timeout int64
)
// 开始时间
startTime := time.Now()
opts := loadOptions(options...)
if opts.Timeout != 0 {
timeout = opts.Timeout
} else {
timeout = DefaultTimeOut
}
command := cmd.NewCmd("sh", []string{"-c", cmdStr}...)
go func() {
<-time.After(time.Duration(timeout) * time.Second)
err = command.Stop()
if err != nil {
logrus.Errorf("command.Stop err:%v. cmdStr:%s", err, cmdStr)
}
err = errors.New(fmt.Sprintf("CmdMgr SyncExecute timeout:%d. cmdStr:%s", timeout, cmdStr))
}()
cmdStatus := <-command.Start()
if cmdStatus.Error != nil {
// 执行时间
latencyTime := time.Now().Sub(startTime)
logrus.Errorf("SyncExecute command.Start. err:%v. cmdStatus:%+v, cost:%0.2fs",
cmdStatus.Error, cmdStatus, float64(latencyTime)/float64(time.Second))
if err != nil { // timeout
return nil, err
}
return nil, cmdStatus.Error
}
// 执行时间
latencyTime := time.Now().Sub(startTime)
logrus.Debugf("SyncExecute success. cost:%0.2fs, cmdStr:%s, cmdStatus:%+v",
float64(latencyTime)/float64(time.Second), cmdStr, cmdStatus)
res.Cmd = cmdStr
res.PID = cmdStatus.PID
res.Complete = cmdStatus.Complete
res.Exit = cmdStatus.Exit
res.Error = cmdStatus.Error
res.StartTs = cmdStatus.StartTs
res.StopTs = cmdStatus.StopTs
res.Runtime = cmdStatus.Runtime
res.StdoutLines = cmdStatus.Stdout
res.StderrLines = cmdStatus.Stderr
stdout := strings.Join(RemoveEmptyElm(cmdStatus.Stdout), LineSeparator)
stderr := strings.Join(RemoveEmptyElm(cmdStatus.Stderr), LineSeparator)
res.Stdout = stdout
res.Stderr = stderr
return &res, cmdStatus.Error
}
func GetCurrentRpm(srcList, dstList []string) ([]string, error) {
sort.Strings(srcList)
sort.Strings(dstList)
srcRpmMap := map[string]string{}
for _, line := range srcList {
srcRpmMap[line] = line
}
dstRpmMap := map[string]string{}
for _, line := range dstList {
dstRpmMap[line] = line
}
//fmt.Println("len srcRpmMap:", len(srcRpmMap))
//fmt.Println("len srcStat:", len(srcList))
//fmt.Println("len dstRpmMap:", len(dstRpmMap))
//fmt.Println("len dstStat:", len(srcList))
var rpms []string
for _, rpm := range srcRpmMap {
if _, ok := dstRpmMap[rpm]; !ok {
rpms = append(rpms, rpm)
}
}
return rpms, nil
}
func DecodeYumInfo(str string) ([]string, error) {
type Rpm struct {
Name string
Version string
Release string
Architecture string
}
var rpms []Rpm
// 按照 \n\n分片
list := strings.Split(str, "\n\n")
for _, item := range list {
var rpm Rpm
itemList := strings.Split(item, "\n")
for _, subItem := range itemList {
if strings.Contains(subItem, "Name :") {
rpm.Name = strings.TrimSpace(strings.Split(subItem, ":")[1])
}
if strings.Contains(subItem, "Version :") {
rpm.Version = strings.TrimSpace(strings.Split(subItem, ":")[1])
}
if strings.Contains(subItem, "Release :") {
rpm.Release = strings.TrimSpace(strings.Split(subItem, ":")[1])
}
if strings.Contains(subItem, "Architecture :") {
rpm.Architecture = strings.TrimSpace(strings.Split(subItem, ":")[1])
}
}
rpms = append(rpms, rpm)
}
var rpmList []string
for _, rpm := range rpms {
rpmList = append(rpmList, rpm.Name+"-"+rpm.Version+"-"+rpm.Release+"."+rpm.Architecture+".rpm")
}
return rpmList, nil
}
func GetYumInfo() (string, error) {
dstCmd := "yum info"
dstStat, err := SyncExecute(dstCmd)
if err != nil {
return "", err
}
return dstStat.Stdout, nil
}
func GetMediaRpmList() ([]string, error) {
srcCmd := "ls -lh /media/ |awk -F' ' '{print $9}'"
srcStat, err := SyncExecute(srcCmd)
if err != nil {
return []string{}, err
}
return srcStat.StdoutLines, nil
}
func main() {
//// 获取yum info信息
//yumInfoList, err := GetYumInfo()
//// 获取/media信息
//mediaList, err := GetMediaRpmList()
yumInfoBts, err := ioutil.ReadFile("/Users/liucx/Desktop/yum_info_arm.txt")
mediaListBts, err := ioutil.ReadFile("/Users/liucx/Desktop/media_list.txt")
mediaList := strings.Split(string(mediaListBts), "\n")
// 解析yum info
yumInfoList, err := DecodeYumInfo(string(yumInfoBts))
rpms, err := GetCurrentRpm(mediaList, yumInfoList)
if err != nil {
return
}
for _, rpm := range rpms {
if rpm == "" || rpm == "repodata" || rpm == "TRANS.TBL" {
continue
}
fmt.Println(rpm)
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/liucxer/ceph-tools.git
git@gitee.com:liucxer/ceph-tools.git
liucxer
ceph-tools
ceph-tools
ed01591ec671

搜索帮助