Add SysInfo Functions
Add sysinfo functions, template updates, stuff like that
This commit is contained in:
parent
2157e8a343
commit
c901ee769b
@ -3,6 +3,7 @@ package paste
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/rocky-linux/rpaste/modules/utility"
|
||||
@ -21,47 +22,36 @@ var (
|
||||
|
||||
func runPaste(ctx *cli.Context) error {
|
||||
// check
|
||||
stdResults := utility.StdInChecker()
|
||||
stdMethod := utility.StdInChecker()
|
||||
sysInfoMethod := ctx.Bool("sysinfo")
|
||||
|
||||
// If there's no more than 1 argument (the executable itself is arg 0), we
|
||||
// will check for stdin, and if not, print out the usage information.
|
||||
//if stdResults {
|
||||
// fio, err := os.Stdin.Stat()
|
||||
// if (fio.Mode() & os.ModeCharDevice) == 0 {
|
||||
// bytes, _ := ioutil.ReadAll(os.Stdin)
|
||||
// PasteData = string(bytes)
|
||||
// } else if err != nil {
|
||||
// fmt.Printf("Could not read from stdin: (%s)\n", err)
|
||||
// os.Exit(1)
|
||||
// }
|
||||
//} else {
|
||||
// cli.ShowAppHelp(ctx)
|
||||
// os.Exit(0)
|
||||
//}
|
||||
// Check sysinfo is enabled and run through all the required stuff
|
||||
if sysInfoMethod {
|
||||
PasteData = SysInfoGather()
|
||||
}
|
||||
|
||||
// Check args for a file or sysinfo
|
||||
//if len(PasteData) == 0 {
|
||||
// if ctx.Bool("sysinfo") {
|
||||
// //PasteData = GatherSysInfo()
|
||||
// PasteData = "Sys Info"
|
||||
// } else {
|
||||
// // Path is expected at the end of the command (matches current rpaste)
|
||||
// argList := os.Args
|
||||
// lastArg := argList[len(argList)-1]
|
||||
// fileBytes, err := ioutil.ReadFile(lastArg)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// PasteData = string(fileBytes)
|
||||
// }
|
||||
//}
|
||||
if stdMethod && PasteData == "" {
|
||||
fio, err := os.Stdin.Stat()
|
||||
if (fio.Mode() & os.ModeCharDevice) == 0 {
|
||||
bytes, _ := ioutil.ReadAll(os.Stdin)
|
||||
PasteData = string(bytes)
|
||||
} else if err != nil {
|
||||
fmt.Printf("Could not read from stdin: (%s)\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
} else if !stdMethod && PasteData == "" {
|
||||
argList := os.Args
|
||||
lastArg := argList[len(argList)-1]
|
||||
fileBytes, err := ioutil.ReadFile(lastArg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
PasteData = string(fileBytes)
|
||||
}
|
||||
|
||||
// Check that PasteData is text, and not binary
|
||||
|
||||
fmt.Println(len(PasteData))
|
||||
for i, arg := range os.Args {
|
||||
fmt.Println("item", i, "is", arg)
|
||||
}
|
||||
fmt.Println(PasteData)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -1,2 +1,296 @@
|
||||
// sysinfo
|
||||
package paste
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/rocky-linux/rpaste/modules/setting"
|
||||
)
|
||||
|
||||
var (
|
||||
buf bytes.Buffer
|
||||
)
|
||||
|
||||
type SystemInfo struct {
|
||||
OsRelease string
|
||||
DesktopEnvs string
|
||||
DesktopInstalled string
|
||||
SELinuxStatus string
|
||||
SELinuxErrors string
|
||||
CPUInfo string
|
||||
Support64bit string
|
||||
VirtSupport string
|
||||
LoadAverage string
|
||||
MemUsage string
|
||||
TopCPUHogs string
|
||||
TopMemHogs string
|
||||
DiskUsage string
|
||||
BlockDevs string
|
||||
PciDevs string
|
||||
USBDevs string
|
||||
DRMInfo string
|
||||
XorgModules string
|
||||
GLSupport string
|
||||
XorgErrors string
|
||||
DmesgTail string
|
||||
LastTenReboots string
|
||||
DnfRepoList string
|
||||
DnfRepoFiles string
|
||||
YumConf string
|
||||
LastTwentyPackages string
|
||||
EFISupport string
|
||||
}
|
||||
|
||||
func osRelease() string {
|
||||
app := "uniq"
|
||||
args := []string{"/etc/os-release"}
|
||||
cmd, _ := exec.Command(app, args...).CombinedOutput()
|
||||
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func desktopEnvs() string {
|
||||
// The below just returns whatever the match is, rather than each match. The
|
||||
// original command (and by extension, the original fpaste python script and
|
||||
// rpaste bash script) would spit out more than just the expected result
|
||||
app := "ps"
|
||||
args := []string{
|
||||
"-eo",
|
||||
"comm=",
|
||||
}
|
||||
cmd, _ := exec.Command(app, args...).CombinedOutput()
|
||||
re, _ := regexp.Compile(`(gnome-session|startkde|startactive|xfce.?-session|fluxbox|blackbox|hackedbox|ratpoison|enlightenment|icewm-session|od-session|wmaker|wmx|openbox-lxde|openbox-gnome-session|openbox-kde-session|mwm|e16|fvwm|xmonad|sugar-session|mate-session|lxqt-session|cinnamon)`)
|
||||
values := re.FindString(string(cmd))
|
||||
return values
|
||||
}
|
||||
|
||||
func desktopInstalled() string {
|
||||
app := "ls"
|
||||
args := []string{
|
||||
"-m",
|
||||
"/usr/share/xsessions/",
|
||||
}
|
||||
cmd, _ := exec.Command(app, args...).CombinedOutput()
|
||||
re, _ := regexp.Compile(`\.desktop`)
|
||||
values := re.ReplaceAllString(string(cmd), "")
|
||||
return values
|
||||
}
|
||||
|
||||
func selinuxStatus() string {
|
||||
app1 := "getenforce"
|
||||
app2 := "grep -v '^#' /etc/sysconfig/selinux"
|
||||
cmd1, _ := exec.Command(app1).CombinedOutput()
|
||||
cmd2, _ := exec.Command("/bin/sh", "-c", app2).CombinedOutput()
|
||||
combined := string(cmd1) + string(cmd2)
|
||||
return combined
|
||||
}
|
||||
|
||||
func selinuxErrors() string {
|
||||
// I'm not proud of this
|
||||
app := "journalctl --since yesterday |grep avc: | grep -Eo comm='[^ ]+' | sort |uniq -c |sort -rn"
|
||||
cmd, _ := exec.Command("/bin/sh", "-c", app).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func cpuInfo() string {
|
||||
// I'm not proud of this
|
||||
app := "grep 'model name' /proc/cpuinfo | awk -F: '{print $2}' | uniq -c | sed -re 's/^ +//'"
|
||||
cmd, _ := exec.Command("/bin/sh", "-c", app).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func support64Bit() string {
|
||||
text := " lm "
|
||||
file, _ := ioutil.ReadFile("/proc/cpuinfo")
|
||||
string := string(file)
|
||||
return strconv.FormatBool(strings.Contains(string, text))
|
||||
}
|
||||
|
||||
func virtSupport() string {
|
||||
re, _ := regexp.Compile(`(vmx|svm)`)
|
||||
file, _ := ioutil.ReadFile("/proc/cpuinfo")
|
||||
exists := re.Match(file)
|
||||
return strconv.FormatBool(exists)
|
||||
}
|
||||
|
||||
func loadAverage() string {
|
||||
app := "uptime"
|
||||
cmd, _ := exec.Command(app).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func memUsage() string {
|
||||
app := "free"
|
||||
args := []string{"-m"}
|
||||
cmd, _ := exec.Command(app, args...).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func topCPUHogs() string {
|
||||
// I'm not proud of this
|
||||
app := "ps axuScnh | sort -rnk3 | head -5"
|
||||
cmd, _ := exec.Command("/bin/sh", "-c", app).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func topMemHogs() string {
|
||||
// I'm not proud of this
|
||||
app := "ps axuScnh | sort -rnk4 | head -5"
|
||||
cmd, _ := exec.Command("/bin/sh", "-c", app).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func diskUsage() string {
|
||||
app := "df"
|
||||
args := []string{"-hT"}
|
||||
cmd, _ := exec.Command(app, args...).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func blockDevs() string {
|
||||
app := "/sbin/blkid"
|
||||
cmd, _ := exec.Command(app).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func pciDevs() string {
|
||||
app := "/sbin/lspci"
|
||||
args := []string{"-nn"}
|
||||
cmd, _ := exec.Command(app, args...).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func usbDevs() string {
|
||||
app := "/bin/lsusb"
|
||||
cmd, _ := exec.Command(app).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func drmInfo() string {
|
||||
// I'm not proud of this
|
||||
app := "journalctl -k -b | grep -o 'kernel:.*drm.*$' | cut -d ' ' -f 2-"
|
||||
cmd, _ := exec.Command("/bin/sh", "-c", app).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func xorgModules() string {
|
||||
// I'm not proud of this
|
||||
app := "grep LoadModule /var/log/Xorg.0.log ~/.local/share/xorg/Xorg.0.log | cut -d '\"' -f 2 | xargs"
|
||||
cmd, _ := exec.Command("/bin/sh", "-c", app).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func glSupport() string {
|
||||
// I'm not proud of this
|
||||
// turn to golang regexp? we would rather get the error output regardless
|
||||
app := "glxinfo | grep -E 'OpenGL version|OpenGL renderer'"
|
||||
cmd, _ := exec.Command("/bin/sh", "-c", app).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func xorgErrors() string {
|
||||
// I'm not proud of this
|
||||
app := "grep '^\\[.*(EE)' /var/log/Xorg.0.log ~/.local/share/xorg/Xorg.0.log | cut -d ':' -f 2-"
|
||||
cmd, _ := exec.Command("/bin/sh", "-c", app).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func dmesgTail() string {
|
||||
// I'm not proud of this
|
||||
// Maybe I can implement a tail-like function
|
||||
app := "dmesg | tail"
|
||||
cmd, _ := exec.Command("/bin/sh", "-c", app).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func lastTenReboots() string {
|
||||
app := "last"
|
||||
args := []string{
|
||||
"-x",
|
||||
"-n10",
|
||||
"reboot",
|
||||
"runlevel",
|
||||
}
|
||||
cmd, _ := exec.Command(app, args...).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func dnfRepoList() string {
|
||||
app := "dnf"
|
||||
args := []string{"repolist"}
|
||||
cmd, _ := exec.Command(app, args...).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func dnfRepoFiles() string {
|
||||
app := "ls"
|
||||
args := []string{
|
||||
"-l",
|
||||
"/etc/yum.repos.d/",
|
||||
}
|
||||
cmd, _ := exec.Command(app, args...).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func yumConf() string {
|
||||
app := "grep -v '^#' /etc/yum.conf"
|
||||
cmd, _ := exec.Command("/bin/sh", "-c", app).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func lastTwentyPkgs() string {
|
||||
app := "rpm -qa --nodigest --nosignature --last | head -20"
|
||||
cmd, _ := exec.Command("/bin/sh", "-c", app).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func efiSupport() string {
|
||||
app := "efibootmgr"
|
||||
args := []string{"-v"}
|
||||
cmd, _ := exec.Command(app, args...).CombinedOutput()
|
||||
return string(cmd)
|
||||
}
|
||||
|
||||
func SysInfoGather() string {
|
||||
sysInfoData := SystemInfo{
|
||||
OsRelease: osRelease(),
|
||||
DesktopEnvs: desktopEnvs(),
|
||||
DesktopInstalled: desktopInstalled(),
|
||||
SELinuxStatus: selinuxStatus(),
|
||||
SELinuxErrors: selinuxErrors(),
|
||||
CPUInfo: cpuInfo(),
|
||||
Support64bit: support64Bit(),
|
||||
VirtSupport: virtSupport(),
|
||||
LoadAverage: loadAverage(),
|
||||
MemUsage: memUsage(),
|
||||
TopCPUHogs: topCPUHogs(),
|
||||
TopMemHogs: topMemHogs(),
|
||||
DiskUsage: diskUsage(),
|
||||
BlockDevs: blockDevs(),
|
||||
PciDevs: pciDevs(),
|
||||
USBDevs: usbDevs(),
|
||||
DRMInfo: drmInfo(),
|
||||
XorgModules: xorgModules(),
|
||||
GLSupport: glSupport(),
|
||||
XorgErrors: xorgErrors(),
|
||||
DmesgTail: dmesgTail(),
|
||||
LastTenReboots: lastTenReboots(),
|
||||
DnfRepoList: dnfRepoList(),
|
||||
DnfRepoFiles: dnfRepoFiles(),
|
||||
YumConf: yumConf(),
|
||||
LastTwentyPackages: lastTwentyPkgs(),
|
||||
EFISupport: efiSupport(),
|
||||
}
|
||||
|
||||
t := template.New("sysinfo")
|
||||
t, _ = t.Parse(setting.SysInfoTemplate)
|
||||
t.Execute(&buf, sysInfoData)
|
||||
sysInfoResults := buf.String()
|
||||
return sysInfoResults
|
||||
}
|
||||
|
129
modules/setting/template.go
Normal file
129
modules/setting/template.go
Normal file
@ -0,0 +1,129 @@
|
||||
package setting
|
||||
|
||||
var SysInfoTemplate = `################################################################################
|
||||
# OS Release
|
||||
#
|
||||
{{.OsRelease}}
|
||||
|
||||
################################################################################
|
||||
# Desktop Environments
|
||||
#
|
||||
{{.DesktopEnvs}}
|
||||
|
||||
################################################################################
|
||||
# Desktop Installed
|
||||
#
|
||||
{{.DesktopInstalled}}
|
||||
|
||||
################################################################################
|
||||
# SELinux Status
|
||||
#
|
||||
{{.SELinuxStatus}}
|
||||
|
||||
################################################################################
|
||||
# SELinux Errors
|
||||
#
|
||||
{{.SELinuxErrors}}
|
||||
|
||||
################################################################################
|
||||
# CPU Info
|
||||
#
|
||||
{{.CPUInfo}}
|
||||
|
||||
################################################################################
|
||||
# 64-bit Support
|
||||
#
|
||||
{{.Support64bit}}
|
||||
|
||||
################################################################################
|
||||
# Virtualization Support
|
||||
#
|
||||
{{.VirtSupport}}
|
||||
|
||||
################################################################################
|
||||
# Load Average
|
||||
#
|
||||
{{.LoadAverage}}
|
||||
|
||||
################################################################################
|
||||
# Memory usage
|
||||
#
|
||||
{{.MemUsage}}
|
||||
|
||||
################################################################################
|
||||
# Top 5 CPU hogs
|
||||
#
|
||||
{{.TopCPUHogs}}
|
||||
|
||||
################################################################################
|
||||
# Top 5 memory hogs
|
||||
#
|
||||
{{.TopMemHogs}}
|
||||
|
||||
################################################################################
|
||||
# Disk space usage
|
||||
#
|
||||
{{.DiskUsage}}
|
||||
|
||||
################################################################################
|
||||
# Block Devices
|
||||
#
|
||||
{{.BlockDevs}}
|
||||
|
||||
################################################################################
|
||||
# PCI devices
|
||||
#
|
||||
{{.PciDevs}}
|
||||
|
||||
################################################################################
|
||||
# USB devices
|
||||
#
|
||||
{{.USBDevs}}
|
||||
|
||||
################################################################################
|
||||
# DRM Information
|
||||
#
|
||||
{{.DRMInfo}}
|
||||
|
||||
################################################################################
|
||||
# Xorg modules
|
||||
#
|
||||
{{.XorgModules}}
|
||||
|
||||
################################################################################
|
||||
# GL Support
|
||||
#
|
||||
{{.GLSupport}}
|
||||
|
||||
################################################################################
|
||||
# Xorg errors
|
||||
#
|
||||
{{.XorgErrors}}
|
||||
|
||||
################################################################################
|
||||
# Kernel Buffer Tail
|
||||
#
|
||||
{{.DmesgTail}}
|
||||
|
||||
################################################################################
|
||||
# Last few reboots
|
||||
#
|
||||
{{.LastTenReboots}}
|
||||
|
||||
################################################################################
|
||||
# DNF Repos
|
||||
#
|
||||
{{.DnfRepoList}}
|
||||
{{.DnfRepoFiles}}
|
||||
{{.YumConf}}
|
||||
|
||||
################################################################################
|
||||
# Last 20 packages
|
||||
#
|
||||
{{.LastTwentyPackages}}
|
||||
|
||||
################################################################################
|
||||
# EFI Support
|
||||
#
|
||||
{{.EFISupport}}
|
||||
`
|
53
modules/utility/pipes.go
Normal file
53
modules/utility/pipes.go
Normal file
@ -0,0 +1,53 @@
|
||||
package utility
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"log"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func ExecutePipe(outbuffer *bytes.Buffer, stack ...*exec.Cmd) (err error) {
|
||||
var errbuffer bytes.Buffer
|
||||
pipestack := make([]*io.PipeWriter, len(stack)-1)
|
||||
i := 0
|
||||
|
||||
for ; i < len(stack)-1; i++ {
|
||||
stdin_pipe, stdoutpipe := io.Pipe()
|
||||
stack[i].Stdout = stdoutpipe
|
||||
stack[i].Stderr = &errbuffer
|
||||
stack[i+1].Stdin = stdin_pipe
|
||||
pipestack[i] = stdoutpipe
|
||||
}
|
||||
|
||||
stack[i].Stdout = outbuffer
|
||||
stack[i].Stderr = &errbuffer
|
||||
|
||||
if err := callpipe(stack, pipestack); err != nil {
|
||||
log.Fatalln(string(errbuffer.Bytes()), err)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func callpipe(stack []*exec.Cmd, pipes []*io.PipeWriter) (err error) {
|
||||
if stack[0].Process == nil {
|
||||
if err = stack[0].Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(stack) > 1 {
|
||||
if err = stack[1].Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err == nil {
|
||||
pipes[0].Close()
|
||||
err = callpipe(stack[1:], pipes[1:])
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
return stack[0].Wait()
|
||||
}
|
Loading…
Reference in New Issue
Block a user