rpaste/modules/paste/sysinfo.go

369 lines
9.4 KiB
Go

// sysinfo
package paste
import (
"bytes"
"io/ioutil"
"os/exec"
"regexp"
"strconv"
"strings"
"text/template"
"github.com/rocky-linux/rpaste/modules/setting"
"github.com/rocky-linux/rpaste/modules/utility"
)
var (
buf bytes.Buffer
osID string
sysInfoReturn string
)
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
AppArmorStatus string
}
// Distro agnostic functions
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 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 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 efiSupport() string {
app := "efibootmgr"
args := []string{"-v"}
cmd, _ := exec.Command(app, args...).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)
}
// End agnostic functions
// Red Hat (EL, Fedora) specific functions that may not work elsewhere
// using these on non-rh distros should be used with caution.
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 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)
}
// End Red Hat functions
// SuSE specific functions
// End SuSE
// Debian/Ubuntu specific functions
// End Debian
// AppArmor, affects Debian/Ubuntu/SuSE
func appArmorStatus() string {
app := "aa-status"
cmd, _ := exec.Command(app).CombinedOutput()
return string(cmd)
}
// End AppArmor
func SysInfoGather() string {
osID = utility.GetGenericDistroID()
switch osID {
case "redhat":
sysInfoReturn = redHatSysInfoGather()
case "suse":
sysInfoReturn = suseSysInfoGather()
}
return sysInfoReturn
}
func redHatSysInfoGather() 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.RedHatSysInfoTemplate)
t.Execute(&buf, sysInfoData)
sysInfoResults := buf.String()
return sysInfoResults
}
func suseSysInfoGather() string {
sysInfoData := SystemInfo{
OsRelease: osRelease(),
DesktopEnvs: desktopEnvs(),
DesktopInstalled: desktopInstalled(),
AppArmorStatus: appArmorStatus(),
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(),
LastTwentyPackages: lastTwentyPkgs(),
EFISupport: efiSupport(),
}
t := template.New("sysinfo")
t, _ = t.Parse(setting.SuseSysInfoTemplate)
t.Execute(&buf, sysInfoData)
sysInfoResults := buf.String()
return sysInfoResults
}