Initial commit

This commit is contained in:
yan.y
2024-03-27 23:25:08 +08:00
commit 0884384e91
127 changed files with 9353 additions and 0 deletions
+76
View File
@@ -0,0 +1,76 @@
package sys
import (
"bytes"
"errors"
"fmt"
"os/exec"
"strings"
"syscall"
"time"
)
func CmdOutString(name string, arg ...string) (string, error) {
bs, err := CmdOutBytes(name, arg...)
if err != nil {
return "", errors.New(fmt.Sprintf("CmdOutBytes get error : %v", err))
}
return string(bs), nil
}
func CmdOutBytes(name string, arg ...string) ([]byte, error) {
cmd := exec.Command(name, arg...)
return cmd.CombinedOutput()
}
func CmdOutTrim(name string, arg ...string) (string, error) {
out, err := CmdOutString(name, arg...)
if err != nil {
return "", err
}
return strings.TrimSpace(string(out)), nil
}
func CmdRun(name string, arg ...string) error {
cmd := exec.Command(name, arg...)
return cmd.Run()
}
// CmdRunT Command run with timeout
func CmdRunT(timeout time.Duration, name string, arg ...string) (output string, err error, istimeout bool) {
cmd := exec.Command(name, arg...)
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
var b bytes.Buffer
cmd.Stdout = &b
cmd.Stderr = &b
cmd.Start()
err, istimeout = WrapTimeout(cmd, timeout)
output = b.String()
return
}
func WrapTimeout(cmd *exec.Cmd, timeout time.Duration) (error, bool) {
var err error
done := make(chan error)
go func() {
done <- cmd.Wait()
}()
select {
case <-time.After(timeout):
go func() {
<-done // allow goroutine to exit
}()
// IMPORTANT: cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} is necessary before cmd.Start()
// err = syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
err = cmd.Process.Kill()
return fmt.Errorf("cmd kill process %w", err), true
case err = <-done:
return err, false
}
}
+76
View File
@@ -0,0 +1,76 @@
package sys
import (
"bytes"
"errors"
"fmt"
"os/exec"
"strings"
"syscall"
"time"
)
func CmdOutString(name string, arg ...string) (string, error) {
bs, err := CmdOutBytes(name, arg...)
if err != nil {
return "", errors.New(fmt.Sprintf("CmdOutBytes get error : %v", err))
}
return string(bs), nil
}
func CmdOutBytes(name string, arg ...string) ([]byte, error) {
cmd := exec.Command(name, arg...)
return cmd.CombinedOutput()
}
func CmdOutTrim(name string, arg ...string) (string, error) {
out, err := CmdOutString(name, arg...)
if err != nil {
return "", err
}
return strings.TrimSpace(string(out)), nil
}
func CmdRun(name string, arg ...string) error {
cmd := exec.Command(name, arg...)
return cmd.Run()
}
// CmdRunT Command run with timeout
func CmdRunT(timeout time.Duration, name string, arg ...string) (output string, err error, istimeout bool) {
cmd := exec.Command(name, arg...)
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
var b bytes.Buffer
cmd.Stdout = &b
cmd.Stderr = &b
cmd.Start()
err, istimeout = WrapTimeout(cmd, timeout)
output = b.String()
return
}
func WrapTimeout(cmd *exec.Cmd, timeout time.Duration) (error, bool) {
var err error
done := make(chan error)
go func() {
done <- cmd.Wait()
}()
select {
case <-time.After(timeout):
go func() {
<-done // allow goroutine to exit
}()
// IMPORTANT: cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} is necessary before cmd.Start()
// err = syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
err = cmd.Process.Kill()
return fmt.Errorf("cmd kill process %w", err), true
case err = <-done:
return err, false
}
}
+80
View File
@@ -0,0 +1,80 @@
package sys
import (
"bytes"
"errors"
"fmt"
"os/exec"
"strings"
"syscall"
"time"
)
func CmdOutString(name string, arg ...string) (string, error) {
bs, err := CmdOutBytes(name, arg...)
if err != nil {
return "", errors.New(fmt.Sprintf("CmdOutBytes get error : %v", err))
}
return string(bs), nil
}
func CmdOutBytes(name string, arg ...string) ([]byte, error) {
cmd := exec.Command(name, arg...)
return cmd.CombinedOutput()
}
func CmdOutTrim(name string, arg ...string) (string, error) {
out, err := CmdOutString(name, arg...)
if err != nil {
return "", err
}
return strings.TrimSpace(string(out)), nil
}
func CmdRun(name string, arg ...string) error {
cmd := exec.Command(name, arg...)
return cmd.Run()
}
// CmdRunT Command run with timeout
func CmdRunT(timeout time.Duration, name string, arg ...string) (output string, err error, istimeout bool) {
cmd := exec.Command(name, arg...)
// cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
cmd.SysProcAttr = &syscall.SysProcAttr{
HideWindow: true,
CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP,
}
var b bytes.Buffer
cmd.Stdout = &b
cmd.Stderr = &b
cmd.Start()
err, istimeout = WrapTimeout(cmd, timeout)
output = b.String()
return
}
func WrapTimeout(cmd *exec.Cmd, timeout time.Duration) (error, bool) {
var err error
done := make(chan error)
go func() {
done <- cmd.Wait()
}()
select {
case <-time.After(timeout):
go func() {
<-done // allow goroutine to exit
}()
// IMPORTANT: cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} is necessary before cmd.Start()
// err = syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
err = cmd.Process.Kill()
return fmt.Errorf("cmd kill process %w", err), true
case err = <-done:
return err, false
}
}
+24
View File
@@ -0,0 +1,24 @@
package sys
import (
"fmt"
"strconv"
"strings"
)
func KillProcessByCmdline(cmdline string) error {
cmdline = strings.TrimSpace(cmdline)
if cmdline == "" {
return fmt.Errorf("cmdline is blank")
}
pids := PidsByCmdline(cmdline)
for i := 0; i < len(pids); i++ {
out, err := CmdOutTrim("kill", "-9", strconv.Itoa(pids[i]))
if err != nil {
return fmt.Errorf("kill -9 %d fail: %v, output: %s", pids[i], err, out)
}
}
return nil
}
+134
View File
@@ -0,0 +1,134 @@
package sys
import (
"fmt"
"net"
"strconv"
"strings"
)
func IntranetIP() (ips []string, err error) {
ips = make([]string, 0)
ifaces, e := net.Interfaces()
if e != nil {
return ips, e
}
for _, iface := range ifaces {
if iface.Flags&net.FlagUp == 0 {
continue // interface down
}
if iface.Flags&net.FlagLoopback != 0 {
continue // loopback interface
}
// ignore docker and warden bridge
if strings.HasPrefix(iface.Name, "docker") || strings.HasPrefix(iface.Name, "w-") {
continue
}
addrs, e := iface.Addrs()
if e != nil {
return ips, e
}
for _, addr := range addrs {
var ip net.IP
switch v := addr.(type) {
case *net.IPNet:
ip = v.IP
case *net.IPAddr:
ip = v.IP
}
if ip == nil || ip.IsLoopback() {
continue
}
ip = ip.To4()
if ip == nil {
continue // not an ipv4 address
}
ipStr := ip.String()
if IsIntranet(ipStr) {
ips = append(ips, ipStr)
}
}
}
return ips, nil
}
func IsIntranet(ipStr string) bool {
if strings.HasPrefix(ipStr, "10.") {
return true
}
// for didi
if strings.HasPrefix(ipStr, "100.") {
return true
}
if strings.HasPrefix(ipStr, "192.168.") {
return true
}
if strings.HasPrefix(ipStr, "172.") {
// 172.16.0.0-172.31.255.255
arr := strings.Split(ipStr, ".")
if len(arr) != 4 {
return false
}
second, err := strconv.ParseInt(arr[1], 10, 64)
if err != nil {
return false
}
if second >= 16 && second <= 31 {
return true
}
}
return false
}
// ${sn}-${hostname}-${ip}
func LocalHostIdent() string {
sn, _ := CmdOutTrim("/bin/bash", "-c", "dmidecode -s system-serial-number")
if sn != "" {
arr := strings.Fields(sn)
sn = arr[len(arr)-1]
} else {
sn = "nil"
}
name, _ := CmdOutTrim("hostname")
ips, _ := IntranetIP()
ip := ""
if ips != nil && len(ips) > 0 {
ip = ips[0]
}
return fmt.Sprintf("%s-%s-%s", sn, name, ip)
}
func GetOutboundIpaddr() string {
conn, err := net.Dial("udp4", "1.2.3.4:56")
if err != nil {
return ""
}
defer conn.Close()
localAddr := conn.LocalAddr().String()
if ip, _, err := net.SplitHostPort(localAddr); err != nil {
return ""
} else {
return ip
}
}
+55
View File
@@ -0,0 +1,55 @@
package sys
import (
"fmt"
"strconv"
"strings"
"pet-house.com/core/helper/dir"
)
func PidsByCmdline(cmdline string) []int {
ret := []int{}
var dirs []string
dirs, err := dir.DirsUnder("/proc")
if err != nil {
return ret
}
count := len(dirs)
for i := 0; i < count; i++ {
pid, err := strconv.Atoi(dirs[i])
if err != nil {
continue
}
cmdlineFile := fmt.Sprintf("/proc/%d/cmdline", pid)
if !dir.IsExist(cmdlineFile) {
continue
}
cmdlineBytes, err := dir.ReadBytes(cmdlineFile)
if err != nil {
continue
}
cmdlineBytesLen := len(cmdlineBytes)
if cmdlineBytesLen == 0 {
continue
}
noNut := make([]byte, 0, cmdlineBytesLen)
for j := 0; j < cmdlineBytesLen; j++ {
if cmdlineBytes[j] != 0 {
noNut = append(noNut, cmdlineBytes[j])
}
}
if strings.Contains(string(noNut), cmdline) {
ret = append(ret, pid)
}
}
return ret
}