core/sys/sys.go

219 lines
4.3 KiB
Go
Raw Normal View History

2023-11-02 22:04:28 +00:00
package sys
import (
"bytes"
2023-11-07 22:18:16 +00:00
"errors"
2023-11-02 22:04:28 +00:00
"fmt"
"io"
"os"
"os/exec"
"os/signal"
2023-11-25 14:48:16 +00:00
"os/user"
"strconv"
2023-11-21 16:08:40 +00:00
"strings"
2023-11-02 22:04:28 +00:00
"syscall"
"golang.org/x/sys/unix"
)
2023-11-11 20:21:52 +00:00
var TERM_WIDTH = 50
2023-11-02 22:04:28 +00:00
func RunSilentCmd(cmd *exec.Cmd) int {
2023-11-06 23:41:41 +00:00
err := cmd.Run()
return ManageStatusCmd(cmd, err)
}
func RunBufferedCmd(cmd *exec.Cmd, out *bytes.Buffer) int {
rs1, err := cmd.CombinedOutput()
if err != nil {
fmt.Println("Error: ", err)
}
out.Write(rs1)
return ManageStatusCmd(cmd, err)
}
2023-11-02 22:04:28 +00:00
func RunCmd(cmd *exec.Cmd) int {
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return ManageStatusCmd(cmd, cmd.Run())
}
func RunShellCmd(call string) int {
cmd := exec.Command("sh", "-c", call)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return ManageStatusCmd(cmd, cmd.Run())
}
2023-11-25 12:30:49 +00:00
func RunBufferedShellCmd(call string, out *bytes.Buffer) int {
cmd := exec.Command("sh", "-c", call)
rs1, err := cmd.CombinedOutput()
if err != nil {
fmt.Println("Error: ", err)
}
out.Write(rs1)
return ManageStatusCmd(cmd, err)
}
2023-11-02 22:04:28 +00:00
func ManageStatusCmd(cmd *exec.Cmd, err error) int {
if err == nil {
return 0
}
// Figure out the exit code
if ws, ok := cmd.ProcessState.Sys().(syscall.WaitStatus); ok {
if ws.Exited() {
return ws.ExitStatus()
}
if ws.Signaled() {
return -int(ws.Signal())
}
}
return -1
}
2023-11-07 01:14:31 +00:00
func RunInteractiveCmd(cmd string, withStderr bool, buffers ...*bytes.Buffer) int {
2023-11-07 00:56:10 +00:00
// fmt.Printf(" == go before command : %s\n", cmd)
2023-11-02 22:04:28 +00:00
icmd := exec.Command("bash", "-c", cmd)
icmd.Stdin = os.Stdin
icmd.Stdout = os.Stdout
if withStderr {
2023-11-07 01:12:48 +00:00
if len(buffers) > 0 {
icmd.Stderr = buffers[0]
} else {
icmd.Stderr = os.Stderr
}
2023-11-02 22:04:28 +00:00
}
return ManageStatusCmd(icmd, icmd.Run())
}
2023-11-07 21:28:33 +00:00
func PipeCmd(cmd1 *exec.Cmd, cmd2 *exec.Cmd, buffers ...io.Writer) int {
status := -1
2023-11-07 00:56:10 +00:00
// fmt.Println("> Pipe Commands")
2023-11-02 22:04:28 +00:00
if len(buffers) > 0 {
2023-11-07 21:28:33 +00:00
errIndex := 0
2023-11-02 22:04:28 +00:00
pr, pw := io.Pipe()
cmd1.Stdout = pw
cmd2.Stdin = pr
2023-11-07 21:28:33 +00:00
cmd2.Stdout = buffers[errIndex]
2023-11-02 22:04:28 +00:00
if len(buffers) > 1 {
2023-11-07 21:28:33 +00:00
errIndex = 1
cmd2.Stderr = buffers[errIndex]
2023-11-02 22:04:28 +00:00
}
cmd1.Start()
cmd2.Start()
go func() {
defer pw.Close()
err1 := cmd1.Wait()
if err1 != nil {
2023-11-07 21:28:33 +00:00
buffers[errIndex].Write([]byte(fmt.Sprintf(" Error pipe in : %v\n", err1)))
2023-11-02 22:04:28 +00:00
}
}()
err2 := cmd2.Wait()
if err2 != nil {
2023-11-07 21:28:33 +00:00
buffers[errIndex].Write([]byte(fmt.Sprintf(" Error pipe out : %v\n", err2)))
status = 1
} else {
status = 0
2023-11-02 22:04:28 +00:00
}
2023-11-07 00:56:10 +00:00
// fmt.Println("< Pipe Commands")
2023-11-02 22:04:28 +00:00
}
2023-11-07 21:28:33 +00:00
return status
2023-11-02 22:04:28 +00:00
}
func UpdateTermSize() error {
ws, err := unix.IoctlGetWinsize(syscall.Stdout, unix.TIOCGWINSZ)
if err != nil {
return err
}
TERM_WIDTH = int(ws.Col)
return nil
}
2023-11-04 10:30:17 +00:00
func HandleTermChange(sigwinch chan os.Signal) {
2023-11-02 22:04:28 +00:00
// set signal handler
signal.Notify(sigwinch, syscall.SIGWINCH)
go func() {
for {
if _, ok := <-sigwinch; !ok {
return
}
_ = UpdateTermSize()
}
}()
}
2023-11-03 22:10:43 +00:00
func HandleSigKill(done chan os.Signal) {
2023-11-02 22:04:28 +00:00
signal.Notify(done, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-done // Will block here until user hits ctrl+c
2023-11-06 23:10:32 +00:00
RunCmd(exec.Command("tput", "cnorm"))
RunCmd(exec.Command("tput", "-x", "clear"))
2023-11-02 22:04:28 +00:00
os.Exit(0)
}()
}
2023-11-07 21:38:10 +00:00
func IsRunningOnPod() bool {
var bufout bytes.Buffer
return PipeCmd(exec.Command("cat", "/proc/1/cgroup"), exec.Command("grep", "kubepods"), &bufout) == 0
}
2023-11-07 22:18:16 +00:00
func IsFileExists(path string) bool {
exists := false
if _, err := os.Open(path); !errors.Is(err, os.ErrNotExist) {
exists = true
}
return exists
}
2023-11-21 16:08:40 +00:00
func CheckFileSize(remoteSize int64, path string) bool {
var size int64 = -1
if IsFileExists(path) {
if infos, err := os.Stat(path); err == nil {
size = infos.Size()
}
}
return size == remoteSize
}
func CheckSumFile(remoteChecksum string, path string) bool {
var checksum string = ""
if IsFileExists(path) {
var buf bytes.Buffer
RunBufferedCmd(exec.Command("sha256sum", path), &buf)
checksum = strings.Split(buf.String(), " ")[0]
}
return checksum == remoteChecksum
}
2023-11-25 14:48:16 +00:00
func IsRootUser() bool {
done := false
2023-11-25 14:57:03 +00:00
if usr, err := user.Current(); err == nil {
2023-11-25 14:48:16 +00:00
done = usr.Uid == "0" && usr.HomeDir == "/root"
}
return done
}
func IsUser(name string) bool {
done := false
2023-11-25 14:57:03 +00:00
if usr, err := user.Current(); err == nil {
2023-11-25 14:48:16 +00:00
done = usr.Name == name
}
return done
}
func IsSystemUser(name string) bool {
done := false
2023-11-25 14:57:03 +00:00
if usr, err := user.Current(); err == nil {
2023-11-25 14:48:16 +00:00
var id int
if id, err = strconv.Atoi(usr.Uid); err != nil {
done = id < 1000
}
}
return done
}