A-Tune/common/utils/utils.go
Zhipeng Xie 4335408875 atune: init code
upload code to gitee

Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
2019-11-13 17:14:15 +08:00

285 lines
6.1 KiB
Go

/*
* Copyright (c) 2019 Huawei Technologies Co., Ltd.
* A-Tune is licensed under the Mulan PSL v1.
* You can use this software according to the terms and conditions of the Mulan PSL v1.
* You may obtain a copy of Mulan PSL v1 at:
* http://license.coscl.org.cn/MulanPSL
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
* PURPOSE.
* See the Mulan PSL v1 for more details.
* Create: 2019-10-29
*/
package utils
import (
PB "atune/api/profile"
"bufio"
"fmt"
"io"
"math/rand"
"net"
"os"
"os/exec"
"path"
"path/filepath"
"plugin"
"strconv"
"strings"
"syscall"
"time"
"github.com/urfave/cli"
)
// disk filename
const (
diskFilename = "diskstats"
)
// the number of args
const (
ConstExactArgs = iota
ConstMinArgs
)
// Status of AckCheck
const (
SUCCESS = "SUCCESS"
FAILD = "FAILED"
WARNING = "WARNING"
REQUEST = "REQUEST"
INFO = "INFO"
)
// CheckArgs method check command args num
func CheckArgs(context *cli.Context, expected, checkType int) error {
var err error
cmdName := context.Command.Name
switch checkType {
case ConstExactArgs:
if context.NArg() != expected {
err = fmt.Errorf("%s: %q requires exactly %d argument(s)", os.Args[0], cmdName, expected)
}
case ConstMinArgs:
if context.NArg() < expected {
err = fmt.Errorf("%s: %q requires a minimum of %d argument(s)", os.Args[0], cmdName, expected)
}
}
if err != nil {
fmt.Printf("Incorrect Usage.\n\n")
cli.ShowCommandHelp(context, cmdName)
return err
}
return nil
}
// Fatal method exit the application
func Fatal(err error) {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// Random method return a random uint value, the source is the timestamp
func Random() uint64 {
rand.Seed(time.Now().Unix())
return rand.Uint64()
}
// LoadPlugins method load the plugin service
func LoadPlugins(path string) error {
abs, err := filepath.Abs(path)
if err != nil {
return err
}
pattern := filepath.Join(abs, fmt.Sprintf("*"))
libs, err := filepath.Glob(pattern)
if err != nil {
return err
}
for _, lib := range libs {
if _, err := plugin.Open(lib); err != nil {
fmt.Printf("load %s failed : err\n", lib, err)
continue
}
}
return nil
}
// PathExist method check path if exist or not
func PathExist(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
// PathIsDir method check path is dir or not
func PathIsDir(path string) (bool, error) {
info, err := os.Stat(path)
if err == nil {
return info.IsDir(), nil
}
if os.IsNotExist(err) {
return false, fmt.Errorf("path %s doens't exist", path)
}
return false, err
}
// Print method print AckCheck to stdout
func Print(ackCheck *PB.AckCheck) {
fc := 32
if ackCheck.Status == FAILD {
fc = 31
} else if ackCheck.Status == WARNING {
fc = 33
} else if ackCheck.Status == REQUEST {
fc = 36
} else if ackCheck.Status == INFO {
fc = 37
}
if ackCheck.Description == "" {
fmt.Printf("%c[1;40;%dm %s %c[0m\n", 0x1B, fc, ackCheck.GetName(), 0x1B)
} else {
description := strings.Replace(ackCheck.Description, "\n", ",", -1)
fmt.Printf(" [%c[1;40;%dm %-7s] %-40s %-50s %c[0m\n", 0x1B, fc, ackCheck.Status, ackCheck.Name, description, 0x1B)
}
}
// PrintStr method print string to stdout
func PrintStr(description string) {
fmt.Printf("%c[1;40;%dm %s %c[0m\n", 0x1B, 32, description, 0x1B)
}
// IsHost method check whether it is a physical machine or a virtual machine
func IsHost() bool {
cmd := exec.Command("virt-what")
_, err := cmd.Output()
if err != nil {
return false
}
return true
}
// CreateNamedPipe method create a named pip to communicatin
func CreateNamedPipe() (string, error) {
npipe := strconv.FormatInt(time.Now().Unix(), 10)
npipe = path.Join("/tmp", npipe)
exist, err := PathExist(npipe)
if err != nil {
return "", err
}
if exist {
os.Remove(npipe)
}
err = syscall.Mkfifo(npipe, 0666)
if err != nil {
return "", err
}
return npipe, nil
}
// CopyFile method copy file from srcName to dstname
func CopyFile(dstName string, srcName string) error {
src, err := os.Open(srcName)
if err != nil {
return err
}
defer src.Close()
dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
return err
}
defer dst.Close()
if _, err := io.Copy(dst, src); err != nil {
return err
}
return nil
}
// RemoveDuplicateElement method remove duplicate elem from slice
func RemoveDuplicateElement(message []string) []string {
result := make([]string, 0, len(message))
messageMap := map[string]struct{}{}
for _, item := range message {
if _, ok := messageMap[item]; !ok {
messageMap[item] = struct{}{}
result = append(result, item)
}
}
return result
}
// WaitForPyservice method waiting for pyEngine service start success
func WaitForPyservice() error {
ticker := time.NewTicker(time.Second * 2)
timeout := time.After(time.Second * 120)
for {
select {
case <-ticker.C:
_, err := net.Dial("tcp", "localhost:8383")
if err != nil {
continue
}
return nil
case <-timeout:
return fmt.Errorf("waiting for pyservice timeout")
}
}
return nil
}
// InterfaceByName method check the interface state, up or down
// if interface is not exist or down return err, otherwise return nil
func InterfaceByName(name string) error {
netIntface, err := net.InterfaceByName(name)
if err != nil {
return fmt.Errorf("interface %s is not exist", name)
}
if netIntface.Flags&net.FlagUp == 0 {
return fmt.Errorf("interface %s may be down", name)
}
return nil
}
// DiskByName method check wether the disk is exist
// if disk is exist return nil, otherwise return error
func DiskByName(disk string) error {
diskFile := path.Join("/proc", diskFilename)
file, err := os.Open(diskFile)
if err != nil {
return fmt.Errorf("open file %s error: %v", diskFile, err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
parts := strings.Fields(scanner.Text())
if len(parts) < 4 {
continue
}
if parts[2] == disk {
return nil
}
}
return fmt.Errorf("disk %s is not exist", disk)
}