219 lines
4.3 KiB
Go
219 lines
4.3 KiB
Go
package sys
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"os/exec"
|
|
"os/signal"
|
|
"os/user"
|
|
"strconv"
|
|
"strings"
|
|
"syscall"
|
|
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
var TERM_WIDTH = 50
|
|
|
|
func RunSilentCmd(cmd *exec.Cmd) int {
|
|
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)
|
|
}
|
|
|
|
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())
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
func RunInteractiveCmd(cmd string, withStderr bool, buffers ...*bytes.Buffer) int {
|
|
// fmt.Printf(" == go before command : %s\n", cmd)
|
|
icmd := exec.Command("bash", "-c", cmd)
|
|
icmd.Stdin = os.Stdin
|
|
icmd.Stdout = os.Stdout
|
|
if withStderr {
|
|
if len(buffers) > 0 {
|
|
icmd.Stderr = buffers[0]
|
|
} else {
|
|
icmd.Stderr = os.Stderr
|
|
}
|
|
}
|
|
return ManageStatusCmd(icmd, icmd.Run())
|
|
}
|
|
|
|
func PipeCmd(cmd1 *exec.Cmd, cmd2 *exec.Cmd, buffers ...io.Writer) int {
|
|
status := -1
|
|
// fmt.Println("> Pipe Commands")
|
|
if len(buffers) > 0 {
|
|
errIndex := 0
|
|
pr, pw := io.Pipe()
|
|
cmd1.Stdout = pw
|
|
cmd2.Stdin = pr
|
|
cmd2.Stdout = buffers[errIndex]
|
|
if len(buffers) > 1 {
|
|
errIndex = 1
|
|
cmd2.Stderr = buffers[errIndex]
|
|
}
|
|
|
|
cmd1.Start()
|
|
cmd2.Start()
|
|
|
|
go func() {
|
|
defer pw.Close()
|
|
err1 := cmd1.Wait()
|
|
if err1 != nil {
|
|
buffers[errIndex].Write([]byte(fmt.Sprintf(" Error pipe in : %v\n", err1)))
|
|
}
|
|
}()
|
|
|
|
err2 := cmd2.Wait()
|
|
if err2 != nil {
|
|
buffers[errIndex].Write([]byte(fmt.Sprintf(" Error pipe out : %v\n", err2)))
|
|
status = 1
|
|
} else {
|
|
status = 0
|
|
}
|
|
// fmt.Println("< Pipe Commands")
|
|
}
|
|
return status
|
|
}
|
|
|
|
func UpdateTermSize() error {
|
|
ws, err := unix.IoctlGetWinsize(syscall.Stdout, unix.TIOCGWINSZ)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
TERM_WIDTH = int(ws.Col)
|
|
return nil
|
|
}
|
|
|
|
func HandleTermChange(sigwinch chan os.Signal) {
|
|
// set signal handler
|
|
signal.Notify(sigwinch, syscall.SIGWINCH)
|
|
go func() {
|
|
for {
|
|
if _, ok := <-sigwinch; !ok {
|
|
return
|
|
}
|
|
_ = UpdateTermSize()
|
|
}
|
|
}()
|
|
}
|
|
|
|
func HandleSigKill(done chan os.Signal) {
|
|
signal.Notify(done, syscall.SIGINT, syscall.SIGTERM)
|
|
go func() {
|
|
<-done // Will block here until user hits ctrl+c
|
|
RunCmd(exec.Command("tput", "cnorm"))
|
|
RunCmd(exec.Command("tput", "-x", "clear"))
|
|
os.Exit(0)
|
|
}()
|
|
}
|
|
|
|
func IsRunningOnPod() bool {
|
|
var bufout bytes.Buffer
|
|
return PipeCmd(exec.Command("cat", "/proc/1/cgroup"), exec.Command("grep", "kubepods"), &bufout) == 0
|
|
}
|
|
|
|
func IsFileExists(path string) bool {
|
|
exists := false
|
|
if _, err := os.Open(path); !errors.Is(err, os.ErrNotExist) {
|
|
exists = true
|
|
}
|
|
return exists
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
func IsRootUser() bool {
|
|
done := false
|
|
if usr, err := user.Current(); err == nil {
|
|
done = usr.Uid == "0" && usr.HomeDir == "/root"
|
|
}
|
|
return done
|
|
}
|
|
|
|
func IsUser(name string) bool {
|
|
done := false
|
|
if usr, err := user.Current(); err == nil {
|
|
done = usr.Name == name
|
|
}
|
|
return done
|
|
}
|
|
|
|
func IsSystemUser(name string) bool {
|
|
done := false
|
|
if usr, err := user.Current(); err == nil {
|
|
var id int
|
|
if id, err = strconv.Atoi(usr.Uid); err != nil {
|
|
done = id < 1000
|
|
}
|
|
}
|
|
return done
|
|
}
|