diff --git a/Makefile b/Makefile index 522ae2a..8b61679 100644 --- a/Makefile +++ b/Makefile @@ -48,5 +48,13 @@ install: sudo go build -buildmode=plugin -o ${DESTDIR}/${PLUGIN_DIR}/tmptest.so ./plugins/tmptest @sudo mkdir -p "${DESTDIR}/${DATA_DIR}" +windows_install: + sudo env GOOS=windows GOARCH=amd64 go build -o ${DESTDIR}/usr/bin/${REPO_NAME} ./cmd/ahenk-go/ + @sudo mkdir -p "${DESTDIR}/${LIB_DIR}" + @sudo mkdir -p "${DESTDIR}/${PLUGIN_DIR}" + + sudo GOOS=windows GOARCH=amd64 go build -buildmode=plugin -o ${DESTDIR}/${PLUGIN_DIR}/resources.so ./plugins/resources + sudo GOOS=windows GOARCH=amd64 go build -buildmode=plugin -o ${DESTDIR}/${PLUGIN_DIR}/tmptest.so ./plugins/tmptest + @sudo mkdir -p "${DESTDIR}/${DATA_DIR}" uninstall: @sudo rm -rf ${DESTDIR}/usr/bin/${REPO_NAME} diff --git a/cmd/ahenk-go/main.go b/cmd/ahenk-go/main.go index 22a7310..cc2e7cc 100644 --- a/cmd/ahenk-go/main.go +++ b/cmd/ahenk-go/main.go @@ -4,7 +4,6 @@ import ( "log" "os" "os/user" - "syscall" "git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/utils" @@ -77,28 +76,3 @@ func main() { PluginManager() // NEXT Make PluginManager async ! } - -// FIXME there isn't any difference with Stop() function -// TODO There can be a Start() function in it but start function doesnt work properly right now -// Restart ahenk daemon with a specific PID (running from second copy) -func Restart(pid, signal int) { - Stop(pid, signal) -} - -// Stop ahenk daemon with a specific PID (running from second copy) -func Stop(pid, signal int) { - log.Println("Stop Signal Caught") - - // FILLME what you want to do before stopping daemon? - - if err := syscall.Kill(pid, syscall.Signal(signal)); err == nil { - log.Printf("Ahenk Daemon with pid number %v Successfully stopped", pid) - f := utils.OpenLogFile(LogFile) - defer f.Close() - log.SetOutput(f) - log.Printf("Ahenk Daemon with pid number %v Successfully stopped", pid) - } else { - log.Fatal(err) - } - os.Exit(0) -} diff --git a/cmd/ahenk-go/main_linux.go b/cmd/ahenk-go/main_linux.go new file mode 100644 index 0000000..5793820 --- /dev/null +++ b/cmd/ahenk-go/main_linux.go @@ -0,0 +1,36 @@ +//go:build linux + +package main + +import ( + "log" + "os" + "syscall" + + "git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/utils" +) + +// FIXME there isn't any difference with Stop() function +// TODO There can be a Start() function in it but start function doesnt work properly right now +// Restart ahenk daemon with a specific PID (running from second copy) +func Restart(pid, signal int) { + Stop(pid, signal) +} + +// Stop ahenk daemon with a specific PID (running from second copy) +func Stop(pid, signal int) { + log.Println("Stop Signal Caught") + + // FILLME what you want to do before stopping daemon? + + if err := syscall.Kill(pid, syscall.Signal(signal)); err == nil { + log.Printf("Ahenk Daemon with pid number %v Successfully stopped", pid) + f := utils.OpenLogFile(LogFile) + defer f.Close() + log.SetOutput(f) + log.Printf("Ahenk Daemon with pid number %v Successfully stopped", pid) + } else { + log.Fatal(err) + } + os.Exit(0) +} diff --git a/cmd/ahenk-go/main_windows.go b/cmd/ahenk-go/main_windows.go new file mode 100644 index 0000000..94eddbb --- /dev/null +++ b/cmd/ahenk-go/main_windows.go @@ -0,0 +1,18 @@ +//go:build windows + +package main + +import ( + "log" + "os" +) + +func Restart(pid, signal int) { + Stop(pid, signal) +} + +func Stop(pid, signal int) { + log.Println("Stop Signal Caught") + log.Println("TODO, STOP FUNCTION IS NOT FUNCTIONAL IN WINDOWS YET!") + os.Exit(0) +} diff --git a/cmd/ahenk-go/plugin-manager.go b/cmd/ahenk-go/plugin-manager.go index b869100..cc2cc20 100644 --- a/cmd/ahenk-go/plugin-manager.go +++ b/cmd/ahenk-go/plugin-manager.go @@ -10,7 +10,7 @@ import ( // General Functions/Methods that each plugin has type PlugGeneral interface { - Info() map[string]string + Info() map[string]interface{} } // plugins/resources diff --git a/pkg/osinfo/cpu.go b/pkg/osinfo/cpu.go index 4ab0aee..d7b8131 100644 --- a/pkg/osinfo/cpu.go +++ b/pkg/osinfo/cpu.go @@ -18,7 +18,7 @@ type CPU struct { Threads uint `json:"threads,omitempty"` // number of logical (HT) CPU cores } -func (h *Hardware) getCPUInfo() { +func (h *System) getCPUInfo() { if runtime.GOOS == "linux" { var si sysinfo.SysInfo si.GetSysInfo() @@ -39,3 +39,5 @@ func (h *Hardware) getCPUInfo() { } } + +// REVIEW Windows compatibility and separate files diff --git a/pkg/osinfo/disk.go b/pkg/osinfo/disk.go index 9dca7b6..219b6f8 100644 --- a/pkg/osinfo/disk.go +++ b/pkg/osinfo/disk.go @@ -12,10 +12,10 @@ type Disk struct { Free float64 `json:"free,omitempty"` // Free Disk size in GiB } -func (h *Hardware) getDiskInfo() { +func (h *System) getDiskInfo() { for _, v := range GetDisks() { - h.Disk.Devices += v.Device + h.Disk.Devices += v.Device + ", " } h.Disk.Total = GetDiskUsage()["spaceTotal"] h.Disk.Used = GetDiskUsage()["usedTotal"] @@ -51,3 +51,5 @@ func GetDiskUsage() map[string]float64 { "usedTotal": utils.Byte2GiB(usedSize), } } + +// REVIEW Windows compatibility and separate files diff --git a/pkg/osinfo/kernel.go b/pkg/osinfo/kernel.go new file mode 100644 index 0000000..459ba79 --- /dev/null +++ b/pkg/osinfo/kernel.go @@ -0,0 +1,32 @@ +package osinfo + +import ( + "syscall" + + "git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/utils" + "github.com/zcalusic/sysinfo" +) + +type Kernel struct { + Sysname string `json:"sysname,omitempty"` + Release string `json:"release,omitempty"` + Version string `json:"version,omitempty"` + Arch string `json:"arch,omitempty"` +} + +func (h *System) getKernelInfo() { + + var si sysinfo.SysInfo + si.GetSysInfo() + + var uname syscall.Utsname + if err := syscall.Uname(&uname); err != nil { + panic(err) + } + h.Kernel.Sysname = utils.Byte2String(uname.Sysname[:]) + h.Kernel.Release = si.Kernel.Release + h.Kernel.Version = si.Kernel.Version + h.Kernel.Arch = si.Kernel.Architecture +} + +// REVIEW Windows compatibility diff --git a/pkg/osinfo/main.go b/pkg/osinfo/main.go index 2af6cd4..c7503b4 100644 --- a/pkg/osinfo/main.go +++ b/pkg/osinfo/main.go @@ -1,75 +1,39 @@ package osinfo -import ( - "syscall" - - "git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/utils" - "github.com/shirou/gopsutil/mem" - "github.com/zcalusic/sysinfo" -) - const KB = uint64(1024) -type Hardware struct { +type System struct { + Kernel Kernel `json:"kernel"` + OS OS `json:"OS"` + Node Node `json:"node"` + CPU CPU `json:"cpu"` Memory Memory `json:"memory"` Disk Disk `json:"disk"` - // Node Node `json:"node"` - // Kernel Kernel `json:"kernel"` - OS OS `json:"OS"` } -func (h *Hardware) GetHardwareInfo() { +// initializes all hardware structs that gets software and hardware (system) information +func (h *System) GetSystemInfo() { + h.getKernelInfo() + h.getOSInfo() + h.getNodeInfo() + h.getCPUInfo() h.getMemoryInfo() h.getDiskInfo() - h.getOSInfo() } -// return linux Kernel, Node and System Information -// -// REVIEW are there any command that also compatible with windows? -func GetLinuxInfo() map[string]map[string]interface{} { - var uname syscall.Utsname - if err := syscall.Uname(&uname); err != nil { - panic(err) - } - - var si sysinfo.SysInfo - si.GetSysInfo() - return map[string]map[string]interface{}{ - "Kernel": { - "Sysname": utils.Byte2String(uname.Sysname[:]), - "Release": si.Kernel.Release, - "Version": si.Kernel.Version, - "Machine": si.Kernel.Architecture, - }, - "Node": { - "Domainname": utils.Byte2String(uname.Domainname[:]), - "Hostname": si.Node.Hostname, - "MachineID": si.Node.MachineID, - "Timezone": si.Node.Timezone, - }, - "OS": { //REVIEW review info in pardus - "Name": si.OS.Name, - "Vendor": si.OS.Vendor, - "Arch": si.OS.Architecture, - "Version": si.OS.Version, - "Release": si.OS.Release, - }, - } -} - -// return memory usage as GiB -// -// TODO also implement swap usage -func GetMemoryUsage() map[string]float64 { - v, _ := mem.VirtualMemory() - return map[string]float64{ - "total": utils.Byte2GiB(v.Total), - "free": utils.Byte2GiB(v.Free), - "used": utils.Byte2GiB(v.Used), - "avaliable": utils.Byte2GiB(v.Available), - "cached": utils.Byte2GiB(v.Cached), - } -} +// TODO seperate file structure (as in gopsutil) +/* +main.go +disk/ +--disk.go +--disk_linux.go +--disk_windows.go +cpu/ +--cpu.go +--cpu_linux.go +--cpu_windows.go +memory/ ... +... +*/ diff --git a/pkg/osinfo/memory.go b/pkg/osinfo/memory.go index 987c067..d07431d 100644 --- a/pkg/osinfo/memory.go +++ b/pkg/osinfo/memory.go @@ -15,7 +15,7 @@ type Memory struct { Used float64 `json:"used,omitempty"` // Used RAM size in GiB } -func (h *Hardware) getMemoryInfo() { +func (h *System) getMemoryInfo() { // TODO also implement swap usage memInfo, err := mem.VirtualMemory() utils.Check(err) h.Memory.Used = utils.Byte2GiB(memInfo.Used) @@ -29,3 +29,5 @@ func (h *Hardware) getMemoryInfo() { h.Memory.Speed = si.Memory.Speed } } + +// REVIEW Windows compatibility and separate files diff --git a/pkg/osinfo/node.go b/pkg/osinfo/node.go new file mode 100644 index 0000000..d351c38 --- /dev/null +++ b/pkg/osinfo/node.go @@ -0,0 +1,34 @@ +package osinfo + +import ( + "syscall" + + "git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/utils" + "github.com/zcalusic/sysinfo" +) + +type Node struct { + Domainname string `json:"domainname,omitempty"` + Hostname string `json:"hostname,omitempty"` + MachineID string `json:"machineid,omitempty"` + Hypervisor string `json:"hypervisor,omitempty"` + Timezone string `json:"timezone,omitempty"` +} + +func (h *System) getNodeInfo() { + var si sysinfo.SysInfo + si.GetSysInfo() + + var uname syscall.Utsname + if err := syscall.Uname(&uname); err != nil { + panic(err) + } + + h.Node.Domainname = utils.Byte2String(uname.Domainname[:]) + h.Node.Hostname = si.Node.Hostname + h.Node.MachineID = si.Node.MachineID + h.Node.Hypervisor = si.Node.Hypervisor + h.Node.Timezone = si.Node.Timezone +} + +// REVIEW Windows compatibility diff --git a/pkg/osinfo/os.go b/pkg/osinfo/os.go index fa3a615..a987d23 100644 --- a/pkg/osinfo/os.go +++ b/pkg/osinfo/os.go @@ -1,11 +1,5 @@ package osinfo -import ( - "runtime" - - "github.com/zcalusic/sysinfo" -) - type OS struct { Name string `json:"name,omitempty"` Distro string `json:"distro,omitempty"` @@ -13,16 +7,3 @@ type OS struct { Release string `json:"release,omitempty"` Arch string `json:"architecture,omitempty"` } - -func (h *Hardware) getOSInfo() { - if runtime.GOOS == "linux" { - var si sysinfo.SysInfo - si.GetSysInfo() - - h.OS.Name = si.OS.Name - h.OS.Distro = si.OS.Vendor - h.OS.Version = si.OS.Version - h.OS.Release = si.OS.Release - h.OS.Arch = si.OS.Architecture - } -} diff --git a/pkg/osinfo/os_linux.go b/pkg/osinfo/os_linux.go new file mode 100644 index 0000000..c80700c --- /dev/null +++ b/pkg/osinfo/os_linux.go @@ -0,0 +1,16 @@ +//go:build linux + +package osinfo + +import "github.com/zcalusic/sysinfo" + +func (h *System) getOSInfo() { //REVIEW review info in pardus + var si sysinfo.SysInfo + si.GetSysInfo() + + h.OS.Name = si.OS.Name + h.OS.Distro = si.OS.Vendor + h.OS.Version = si.OS.Version + h.OS.Release = si.OS.Release + h.OS.Arch = si.OS.Architecture +} diff --git a/pkg/osinfo/os_windows.go b/pkg/osinfo/os_windows.go new file mode 100644 index 0000000..912dd70 --- /dev/null +++ b/pkg/osinfo/os_windows.go @@ -0,0 +1,21 @@ +//go:build windows + +package osinfo + +import ( + "git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/utils" + "golang.org/x/sys/windows/registry" +) + +func (h *System) getOSInfo() { + + reg, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE) + utils.Check(err) + defer reg.Close() + + pn, _, err := reg.GetStringValue("ProductName") + utils.Check(err) + + h.OS.Name = pn + // TODO add other h.OS values +} diff --git a/plugins/resources/info.go b/plugins/resources/info.go new file mode 100644 index 0000000..b58dec1 --- /dev/null +++ b/plugins/resources/info.go @@ -0,0 +1,14 @@ +package main + +func (p plug) Info() map[string]interface{} { + return map[string]interface{}{ + "name": "resources", + "version": "0.1.0", + "support": map[string]interface{}{ + "linux": "debian", + "windows": "10", + }, + "description": "Resource Usage Information and Controls", + "developer": "asandikci@aliberksandikci.com.tr", + } +} diff --git a/plugins/resources/main.go b/plugins/resources/main.go index f255839..ec64da3 100644 --- a/plugins/resources/main.go +++ b/plugins/resources/main.go @@ -13,31 +13,25 @@ var ResourcesConnect plug // return instant resource usage information func (p plug) ResourceUsage() map[string]interface{} { - var hardware osinfo.Hardware - hardware.GetHardwareInfo() + var system osinfo.System + system.GetSystemInfo() data := map[string]interface{}{ - // General System Information - "System": runtime.GOOS, - "Release": osinfo.GetLinuxInfo()["Kernel"]["Release"], //needs REVIEW for windows - "Version": osinfo.GetLinuxInfo()["OS"]["Version"], //needs REVIEW for windows - "Machine": osinfo.GetLinuxInfo()["OS"]["Arch"], //needs REVIEW for windows - // CPU Information - "CPU Physical Core Count": hardware.CPU.Cores, - // "CPU Logical Core Count": hardware.CPU.Logical_core_count, // TODO - // "CPU Actual Hz": hardware.CPU.ActualHz, // TODO - // "CPU Advertised Hz": hardware.CPU.Hz_advertised, // TODO - // "Processor": hardware.CPU.Brand, // TODO + "CPU Physical Core Count": system.CPU.Cores, + // "CPU Logical Core Count": system.CPU.Logical_core_count, // TODO + // "CPU Actual Hz": system.CPU.ActualHz, // TODO + // "CPU Advertised Hz": system.CPU.Hz_advertised, // TODO + // "Processor": system.CPU.Brand, // TODO // Memory Information - "Total Memory": hardware.Memory.Total, - "Usage": hardware.Memory.Used, + "Total Memory": system.Memory.Total, + "Usage": system.Memory.Used, // Disk Information - "Total Disk": hardware.Disk.Total, - "Usage Disk": hardware.Disk.Used, - "Device": hardware.Disk.Devices, + "Total Disk": system.Disk.Total, + "Usage Disk": system.Disk.Used, + "Device": system.Disk.Devices, } // TODO see https://github.com/Pardus-LiderAhenk/ahenk/blob/master/src/plugins/resource-usage/resource_info_fetcher.py @@ -48,45 +42,26 @@ func (p plug) ResourceUsage() map[string]interface{} { // // these values changes rarely, see ResourceUsage() function for instant resource usage information func (p plug) AgentInfo() map[string]interface{} { - var hardware osinfo.Hardware - hardware.GetHardwareInfo() + var system osinfo.System + system.GetSystemInfo() // Common data data := map[string]interface{}{ "System": runtime.GOOS, - "DiskSpaceTotal": hardware.Disk.Total, - "MemoryTotal": hardware.Memory.Total, + "DiskSpaceTotal": system.Disk.Total, + "MemoryTotal": system.Memory.Total, // TODO "AhenkVersion": get Ahenk self version here + + "Name": system.OS.Name, + "Distribution": system.OS.Distro, + "Arch": system.OS.Arch, + "Version": system.OS.Version, + "Hostname": system.Node.Hostname, + "KernelVersion": system.Kernel.Version, + "KernelRelease": system.Kernel.Release, } - // Linux specific data - if runtime.GOOS == "linux" { - data["Name"] = osinfo.GetLinuxInfo()["OS"]["Name"] - data["Distribution"] = osinfo.GetLinuxInfo()["OS"]["Vendor"] - data["Architecture"] = osinfo.GetLinuxInfo()["OS"]["Arch"] - data["Version"] = osinfo.GetLinuxInfo()["OS"]["Version"] - - data["NodeHostname"] = osinfo.GetLinuxInfo()["Node"]["Hostname"] - - data["Architecture"] = osinfo.GetLinuxInfo()["Kernel"]["Machine"] - data["KernelVersion"] = osinfo.GetLinuxInfo()["Kernel"]["Version"] - } - - // LINK see https://github.com/golang/go/blob/master/src/go/build/syslist.go#L14 for all possible Operating systems - // and https://go.dev/doc/install/source#environment for all possible combinations - // REVIEW is calling all functions one by one slow downs code? - // TODO see https://github.com/Pardus-LiderAhenk/ahenk/blob/master/src/plugins/resource-usage/agent_info.py return data } - -func (p plug) Info() map[string]string { - inf := make(map[string]string) - inf["name"] = "resources" - inf["version"] = "0.0.2" - inf["support"] = "debian" - inf["description"] = "Resource Usage Information and Controls" - inf["developer"] = "asandikci@aliberksandikci.com.tr" - return inf -} diff --git a/plugins/tmptest/main.go b/plugins/tmptest/main.go index 9e29011..a2fec8f 100644 --- a/plugins/tmptest/main.go +++ b/plugins/tmptest/main.go @@ -24,13 +24,3 @@ func (p plug) TmpTest() { fmt.Println() time.Sleep(5 * time.Second) } - -func (p plug) Info() map[string]string { - inf := make(map[string]string) - inf["name"] = "tmptest" - inf["version"] = "0.0.1" - inf["support"] = "debian" - inf["description"] = "Temporary testing" - inf["developer"] = "asandikci@aliberksandikci.com.tr" - return inf -}