This commit is contained in:
Aliberk Sandıkçı 2023-09-02 00:15:55 +03:00
parent c1bc30d830
commit c7dc28fc44
Signed by: asandikci
GPG key ID: 25C67A03B5666BC1
25 changed files with 473 additions and 182 deletions

2
.gitignore vendored
View file

@ -22,4 +22,4 @@
go.work go.work
# Go temporary test files # Go temporary test files
**/plugins/tmptest/** # **/plugins/tmptest/**

View file

@ -23,18 +23,18 @@ preclean:
sudo rm -rf /usr/bin/${OLD_DAEMON_NAME} sudo rm -rf /usr/bin/${OLD_DAEMON_NAME}
sudo rm -rf /usr/bin/${PYTHON_DAEMON_NAME} sudo rm -rf /usr/bin/${PYTHON_DAEMON_NAME}
@# TODO systemd control for both three process for docker # @# TODO systemd control for both three process for docker
@# REVIEW are both killall and systemctl commands running? # @# REVIEW are both killall and systemctl commands running?
@pgrep -x ${DAEMON_NAME} && (sudo killall "${DAEMON_NAME}" || sudo systemctl disable "${DAEMON_NAME}" || sudo systemctl stop "${DAEMON_NAME}") || echo "no ${DAEMON_NAME} found" # @pgrep -x ${DAEMON_NAME} && (sudo killall "${DAEMON_NAME}" || sudo systemctl disable "${DAEMON_NAME}" || sudo systemctl stop "${DAEMON_NAME}") || echo "no ${DAEMON_NAME} found"
@pgrep -x ${OLD_DAEMON_NAME} && (sudo killall "${OLD_DAEMON_NAME}" || sudo systemctl disable "${OLD_DAEMON_NAME}" || sudo systemctl stop "${OLD_DAEMON_NAME}") || echo "no ${OLD_DAEMON_NAME} found" # @pgrep -x ${OLD_DAEMON_NAME} && (sudo killall "${OLD_DAEMON_NAME}" || sudo systemctl disable "${OLD_DAEMON_NAME}" || sudo systemctl stop "${OLD_DAEMON_NAME}") || echo "no ${OLD_DAEMON_NAME} found"
@# TODO # @# TODO
@# echo -e "Do you want to remove python implementation of ahenk if installed in system?" # @# echo -e "Do you want to remove python implementation of ahenk if installed in system?"
@# read -rp "(Y/N) " input # @# read -rp "(Y/N) " input
@pgrep -x ${PYTHON_DAEMON_NAME} && (sudo killall "${PYTHON_DAEMON_NAME}" || sudo systemctl disable "${PYTHON_DAEMON_NAME}" || sudo systemctl stop "${PYTHON_DAEMON_NAME}") || echo "no ${PYTHON_DAEMON_NAME} found" # @pgrep -x ${PYTHON_DAEMON_NAME} && (sudo killall "${PYTHON_DAEMON_NAME}" || sudo systemctl disable "${PYTHON_DAEMON_NAME}" || sudo systemctl stop "${PYTHON_DAEMON_NAME}") || echo "no ${PYTHON_DAEMON_NAME} found"
sudo systemctl daemon-reload # sudo systemctl daemon-reload
sudo rm -rf ${DATA_DIR} sudo rm -rf ${DATA_DIR}
@echo -e "PRE-CLENING DONE\n" @echo -e "PRE-CLENING DONE\n"
test: test:
@ -48,6 +48,13 @@ install:
sudo go build -buildmode=plugin -o ${DESTDIR}/${PLUGIN_DIR}/tmptest.so ./plugins/tmptest sudo go build -buildmode=plugin -o ${DESTDIR}/${PLUGIN_DIR}/tmptest.so ./plugins/tmptest
@sudo mkdir -p "${DESTDIR}/${DATA_DIR}" @sudo mkdir -p "${DESTDIR}/${DATA_DIR}"
linux_goloader_install:
sudo go build -o ${DESTDIR}/usr/bin/${REPO_NAME} ./cmd/ahenk-go/
@sudo mkdir -p "${DESTDIR}/${DATA_DIR}"
sudo cp -r ./plugins "${DESTDIR}/${DATA_DIR}/"
windows_install: windows_install:
sudo env GOOS=windows GOARCH=amd64 go build -o ${DESTDIR}/usr/bin/${REPO_NAME} ./cmd/ahenk-go/ 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}/${LIB_DIR}"

View file

@ -5,33 +5,29 @@ import (
"os" "os"
"os/user" "os/user"
"git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/confdir"
"git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/pluginmanager"
"git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/utils" "git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/utils"
"github.com/sevlyar/go-daemon" "github.com/sevlyar/go-daemon"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
) )
const PidFile = "/run/ahenk-go.pid"
const ExecutablePath = "/usr/bin/ahenk-go"
const DataDir = "/etc/ahenk-go/"
const LogFile = DataDir + "ahenk.log"
const LibDir = "/usr/share/ahenk-go/"
const PluginDir = LibDir + "/plugins/"
// Main Function that starts daemon and controls arguments // Main Function that starts daemon and controls arguments
func main() { func main() {
confdir.GetPaths()
if len(os.Args) == 2 && slices.Contains([]string{"start", "stop", "restart", "nodaemon", "tmptest"}, os.Args[1]) { if len(os.Args) == 2 && slices.Contains([]string{"start", "stop", "restart", "nodaemon", "tmptest"}, os.Args[1]) {
switch os.Args[1] { switch os.Args[1] {
case "start": case "start":
utils.CreatePath(DataDir) utils.CreatePath(confdir.Paths.Data)
cntxt := &daemon.Context{ cntxt := &daemon.Context{
PidFileName: PidFile, PidFileName: confdir.Paths.Pid,
PidFilePerm: 0644, PidFilePerm: 0644,
LogFileName: LogFile, LogFileName: confdir.Paths.Logs + "main.log",
LogFilePerm: 0640, LogFilePerm: 0640,
WorkDir: LibDir, WorkDir: confdir.Paths.Data,
Umask: 027, Umask: 027,
Args: []string{ExecutablePath, "start"}, Args: []string{confdir.Paths.Program, "start"},
} }
d, err := cntxt.Reborn() d, err := cntxt.Reborn()
if err != nil { if err != nil {
@ -44,22 +40,27 @@ func main() {
log.Println("- - - - - - - - - - - - - - - - - -") log.Println("- - - - - - - - - - - - - - - - - -")
log.Print("Daemon Succesfully Started") log.Print("Daemon Succesfully Started")
case "stop": case "stop":
i, _ := daemon.ReadPidFile(PidFile) i, _ := daemon.ReadPidFile(confdir.Paths.Pid)
Stop(i, 15) Stop(i, 15)
case "restart": case "restart":
i, _ := daemon.ReadPidFile(PidFile) i, _ := daemon.ReadPidFile(confdir.Paths.Pid)
Restart(i, 15) Restart(i, 15)
case "nodaemon": case "nodaemon":
log.Print("STARTED AS NO-DAEMON") log.Print("STARTED AS NO-DAEMON")
f := utils.OpenLogFile(LogFile) f := utils.OpenLogFile(confdir.Paths.Logs + "main.log")
defer f.Close() defer f.Close()
log.SetOutput(f) log.SetOutput(f)
// TODO Also pipe fmt.Print* commands // TODO Also pipe fmt.Print* commands
case "tmptest": case "tmptest":
log.Print("TEMPORARY TEST STARTED, log files are NOT redirecting!") log.Print("TEMPORARY TEST STARTED, log files are NOT redirecting!")
PluginManager("tmptest") plugFunctions := map[string][]string{
"tmptest": {"TmpTest"},
"resources": {"AhenkInfo", "ResourceUsage"},
}
pluginmanager.StartPlugins(plugFunctions)
} }
} else { } else {
panic("Please enter a valid option !") panic("Please enter a valid option !")
@ -73,6 +74,8 @@ func main() {
log.Fatal("Ahenk-go requires superuser privilege") log.Fatal("Ahenk-go requires superuser privilege")
} }
PluginManager() // plugFunctions := map[string][]string{
// NEXT Make PluginManager async ! // "resources": {"AhenkInfo", "ResourceUsage"},
// }
// pluginmanager.StartPlugins(plugFunctions)
} }

View file

@ -7,6 +7,7 @@ import (
"os" "os"
"syscall" "syscall"
"git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/confdir"
"git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/utils" "git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/utils"
) )
@ -25,7 +26,7 @@ func Stop(pid, signal int) {
if err := syscall.Kill(pid, syscall.Signal(signal)); err == nil { if err := syscall.Kill(pid, syscall.Signal(signal)); err == nil {
log.Printf("Ahenk Daemon with pid number %v Successfully stopped", pid) log.Printf("Ahenk Daemon with pid number %v Successfully stopped", pid)
f := utils.OpenLogFile(LogFile) f := utils.OpenLogFile(confdir.Paths.Logs + "main.log")
defer f.Close() defer f.Close()
log.SetOutput(f) log.SetOutput(f)
log.Printf("Ahenk Daemon with pid number %v Successfully stopped", pid) log.Printf("Ahenk Daemon with pid number %v Successfully stopped", pid)

View file

@ -1,103 +0,0 @@
package main
import (
"encoding/json"
"log"
"time"
"git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/utils"
)
// General Functions/Methods that each plugin has
type PlugGeneral interface {
Info() map[string]interface{}
}
// plugins/resources
type Resources interface {
AgentInfo() map[string]interface{}
ResourceUsage() map[string]interface{}
}
// plugins/resources
type TmpTest interface {
TmpTest()
}
// FILLME creating new plugin interface, template
// type NewPluginInterface interface {
// PluginMethod() returnType
// }
// Loads Plugins and runs them concurrently.
// When you create a new plugin create a new interface and call this plugin in this function
func PluginManager(params ...string) {
chanPlug := make(chan interface{})
go LoadPlugin("resources", chanPlug)
res, ok := <-chanPlug
var resources Resources = res.(Resources)
checkPlugin(resources, ok)
if len(params) > 0 && params[0] == "tmptest" {
go LoadPlugin("tmptest", chanPlug)
res, ok := <-chanPlug
var tmptest TmpTest = res.(TmpTest)
checkPlugin(res, ok)
tmptest.TmpTest()
}
// FILLME Loading new plugin, template
// go LoadPlugin("pluginName", chanPlug)
// res, ok = <-chanPlug
// var pluginName NewPluginInterface = res.(NewPluginInterface)
// checkPlugin(res, ok)
// Run plugins concurrently and log out
go logPlugin("AgentInfo", resources.AgentInfo(), true)
for {
go logPlugin("ResourceUsage", resources.ResourceUsage(), true)
// FILLME Running/Log out a plugin, template
// go logPlugin("InfoAboutFunction", pluginName.Function(), true)
time.Sleep(30 * time.Second)
}
}
// Logs plugin outputs.
func logPlugin(title string, mp map[string]interface{}, toJson bool) {
log.Printf("\n----- %v -----\n", title)
if toJson {
data, err := json.MarshalIndent(&mp, "", " ")
utils.Check(err)
log.Println(string(data))
} else {
for i, v := range mp {
log.Printf("%v: %v\n", i, v)
}
}
}
// Checks plugin status
func checkPlugin(plugVal interface{}, status bool) {
if status {
if plugVal == nil {
log.Fatal("Plugin loaded but there is no value!")
} else {
plugInfo := plugVal.(PlugGeneral).Info()
log.Printf("Plugin \"%v\" loaded and ready to use, version \"%v\" ", plugInfo["name"], plugInfo["version"])
}
} else {
if plugVal == nil {
log.Fatal("Plugin closed and there is no value! ")
} else {
log.Fatal("Plugin closed or there is an error")
}
}
}
// // TODO response to Lider
// // func createResponse() {
// // }

View file

@ -1,37 +0,0 @@
package main
import (
"fmt"
"os"
"plugin"
"git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/utils"
)
// Load Plugin placed in PluginDir, returns empty interface with channel
// Do not forget to cast in plugin manager
//
// Give Plugin Name as argument and be sure you compiled plugins with `-buildmode=plugin` to PluginDir as `pluginname.so`
func LoadPlugin(plugName string, chn chan interface{}) {
// TODO if error caugth try without relative path, this will be good for local testing
plug, err := plugin.Open(PluginDir + plugName + ".so")
utils.Check(err)
// TODO also allow lookup another symbol other than PlugnameConnect
symPlug, err := plug.Lookup(utils.FirstUpperEN(plugName) + "Connect")
utils.Check(err)
var plugOut interface{}
plugOut, ok := symPlug.(interface{})
if !ok {
fmt.Println("unexpected type from module symbol")
os.Exit(1)
}
chn <- plugOut
}
// NEXT implement unload function
// func UnloadPlugin(plugName string) interface{} {
// }

2
go.mod
View file

@ -10,6 +10,7 @@ require (
) )
require ( require (
github.com/eh-steve/goloader v0.0.0-20230730231803-5c95d7a5f4e2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-ole/go-ole v1.2.6 // indirect
github.com/stretchr/testify v1.8.4 // indirect github.com/stretchr/testify v1.8.4 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect
@ -18,6 +19,7 @@ require (
) )
require ( require (
github.com/eh-steve/goloader/jit v0.0.0-20230731163325-b789213e8550
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // direct github.com/shirou/gopsutil v3.21.11+incompatible // direct
golang.org/x/sys v0.11.0 // direct golang.org/x/sys v0.11.0 // direct

4
go.sum
View file

@ -1,4 +1,8 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/eh-steve/goloader v0.0.0-20230730231803-5c95d7a5f4e2 h1:0mZ2Y8x4dhPfm9eOlbzBx31YSLaECdPvKEBrL5Hc0YE=
github.com/eh-steve/goloader v0.0.0-20230730231803-5c95d7a5f4e2/go.mod h1:k7xs3CUwCvOU9aw851I6AEb6ZzZJ3nos5dZ6A/2ewM0=
github.com/eh-steve/goloader/jit v0.0.0-20230731163325-b789213e8550 h1:clY7T47fFZdFcILcu7uksS7FStRaKMssCYGW0l/AoMo=
github.com/eh-steve/goloader/jit v0.0.0-20230731163325-b789213e8550/go.mod h1:p18VKcPYO8oWGYcQt/K5EGIGqak0ZT5HwVirGpUGZBg=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=

4
go.work.sum Normal file
View file

@ -0,0 +1,4 @@
github.com/eh-steve/goloader/jit/testdata v0.0.0-20230730231803-5c95d7a5f4e2/go.mod h1:GyUY1mfY7NCdoVRo5H8+kmhLa/xE418ZcjfDfgwicXw=
github.com/eh-steve/goloader/unload v0.0.0-20230730231803-5c95d7a5f4e2/go.mod h1:bA/aiceMvuZh45HAA/xzWJKT4E9EXqzmuPsB9yT/D/M=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=

16
pkg/confdir/confdir.go Normal file
View file

@ -0,0 +1,16 @@
package confdir
type Path struct {
Program string `json:"Program"`
UserConfig string `json:"User Config"`
Data string `json:"Data"`
Plugins string `json:"Plugins"`
Logs string `json:"Logs"`
Pid string `json:"pid"`
}
var Paths Path
func GetPaths() {
Paths = getPaths()
}

View file

@ -0,0 +1,16 @@
//go:build linux && !windows
package confdir
import "os"
func getPaths() Path {
var path Path
path.Program = "/usr/bin/ahenk-go"
path.UserConfig, _ = os.UserConfigDir()
path.Data = "/etc/ahenk-go/"
path.Plugins = path.Data + "plugins/"
path.Logs = path.Data + "logs/"
path.Pid = "/run/ahenk-go.pid"
return path
}

View file

@ -0,0 +1,16 @@
//go:build windows
package confdir
import "os"
func getPaths() Path {
var path Path
path.Program = "TODO"
path.UserConfig, _ = os.UserConfigDir()
path.Data = "TODO"
path.Plugins = path.Data + "plugins/"
path.Logs = path.Data + "logs/"
path.Pid = "TODO"
return path
}

3
pkg/confdir/go.mod Normal file
View file

@ -0,0 +1,3 @@
module git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/confdir
go 1.21.0

7
pkg/pluginmanager/go.mod Normal file
View file

@ -0,0 +1,7 @@
module git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/pluginmanager
go 1.21.0
require github.com/eh-steve/goloader/jit v0.0.0-20230731163325-b789213e8550
require github.com/eh-steve/goloader v0.0.0-20230730231803-5c95d7a5f4e2 // indirect

4
pkg/pluginmanager/go.sum Normal file
View file

@ -0,0 +1,4 @@
github.com/eh-steve/goloader v0.0.0-20230730231803-5c95d7a5f4e2 h1:0mZ2Y8x4dhPfm9eOlbzBx31YSLaECdPvKEBrL5Hc0YE=
github.com/eh-steve/goloader v0.0.0-20230730231803-5c95d7a5f4e2/go.mod h1:k7xs3CUwCvOU9aw851I6AEb6ZzZJ3nos5dZ6A/2ewM0=
github.com/eh-steve/goloader/jit v0.0.0-20230731163325-b789213e8550 h1:clY7T47fFZdFcILcu7uksS7FStRaKMssCYGW0l/AoMo=
github.com/eh-steve/goloader/jit v0.0.0-20230731163325-b789213e8550/go.mod h1:p18VKcPYO8oWGYcQt/K5EGIGqak0ZT5HwVirGpUGZBg=

View file

@ -0,0 +1,15 @@
//go:build linux && !windows
package pluginmanager
import "github.com/eh-steve/goloader/jit"
func getJITConf() jit.BuildConfig {
return jit.BuildConfig{
KeepTempFiles: true, // Files are copied/written to a temp dir to ensure it is writable. This retains the temporary copies
ExtraBuildFlags: []string{"-x"}, // Flags passed to go build command
BuildEnv: []string{"GOOS=linux"}, // Env vars to set for go build toolchain
TmpDir: "", // To control where temporary files are copied
DebugLog: false, //
}
}

View file

@ -0,0 +1,15 @@
//go:build windows
package pluginmanager
import "github.com/eh-steve/goloader/jit"
func getJITConf() jit.BuildConfig {
return jit.BuildConfig{
KeepTempFiles: true, // Files are copied/written to a temp dir to ensure it is writable. This retains the temporary copies
ExtraBuildFlags: []string{"-x"}, // Flags passed to go build command
BuildEnv: []string{"GOOS=windows"}, // Env vars to set for go build toolchain
TmpDir: "", // To control where temporary files are copied
DebugLog: true, //
}
}

View file

@ -0,0 +1,132 @@
package pluginmanager
import "fmt"
// General Functions/Methods that each plugin has
type PlugGeneral interface {
Info() (interface{}, error)
}
// plugins/resources
type Resources interface {
AgentInfo() (interface{}, error)
ResourceUsage() (interface{}, error)
}
type TmpTest interface {
TmpTest() (interface{}, error)
}
type anny any
// Start All plugins
func StartPlugins(params map[string][]string) {
// GeneralFunctions := []string{"Info"}
conf := getJITConf()
chanPlug := make(chan PluginStruct)
// var myint TmpTest
// for i, v := range params {
// v := append(v, GeneralFunctions...)
// go LoadPlugin2(i, v, conf, chanPlug)
// }
go LoadPlugin3("tmptest", conf, chanPlug)
a, ok := <-chanPlug
var an anny = a
fmt.Println(a, ok)
fmt.Println(an)
var aa []func() (interface{}, error)
for _, v := range a.Functions {
aa = append(aa, v)
}
fmt.Println(aa)
var loo interface{} = aa
fmt.Println(loo.(TmpTest))
}
//
// -------------------------
// OLD PLUGIN IMPLEMENTATION
// -------------------------
//
// // FILLME creating new plugin interface, template
// // type NewPluginInterface interface {
// // PluginMethod() returnType
// // }
// Loads Plugins and runs them concurrently.
// When you create a new plugin create a new interface and call this plugin in this function
// func PluginManager(params ...string) {
// chanPlug := make(chan interface{})
// go LoadPlugin("resources", chanPlug)
// res, ok := <-chanPlug
// var resources Resources = res.(Resources)
// checkPlugin(resources, ok)
// if len(params) > 0 && params[0] == "tmptest" {
// go LoadPlugin("tmptest", chanPlug)
// res, ok := <-chanPlug
// var tmptest TmpTest = res.(TmpTest)
// checkPlugin(res, ok)
// tmptest.TmpTest()
// }
// // FILLME Loading new plugin, template
// // go LoadPlugin("pluginName", chanPlug)
// // res, ok = <-chanPlug
// // var pluginName NewPluginInterface = res.(NewPluginInterface)
// // checkPlugin(res, ok)
// // Run plugins concurrently and log out
// go logPlugin("AgentInfo", resources.AgentInfo(), true)
// for {
// go logPlugin("ResourceUsage", resources.ResourceUsage(), true)
// // FILLME Running/Log out a plugin, template
// // go logPlugin("InfoAboutFunction", pluginName.Function(), true)
// time.Sleep(30 * time.Second)
// }
// }
// // Logs plugin outputs.
// func logPlugin(title string, mp map[string]interface{}, toJson bool) {
// log.Printf("\n----- %v -----\n", title)
// if toJson {
// data, err := json.MarshalIndent(&mp, "", " ")
// utils.Check(err)
// log.Println(string(data))
// } else {
// for i, v := range mp {
// log.Printf("%v: %v\n", i, v)
// }
// }
// }
// // Checks plugin status
// func checkPlugin(plugVal interface{}, status bool) {
// if status {
// if plugVal == nil {
// log.Fatal("Plugin loaded but there is no value!")
// } else {
// plugInfo, _ := plugVal.(PlugGeneral).Info()
// log.Printf("Plugin \"%v\" loaded and ready to use, version \"%v\" ", plugInfo["name"], plugInfo["version"])
// }
// } else {
// if plugVal == nil {
// log.Fatal("Plugin closed and there is no value! ")
// } else {
// log.Fatal("Plugin closed or there is an error")
// }
// }
// }
// // // TODO response to Lider
// // // func createResponse() {
// // // }

View file

@ -0,0 +1,140 @@
package pluginmanager
import (
"fmt"
"os"
"plugin"
"git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/confdir"
"git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/utils"
"github.com/eh-steve/goloader/jit"
)
// type mytype func() (interface{}, error)
type PluginStruct struct {
PluginFunction map[string]interface{}
Functions map[string](func() (interface{}, error))
}
func LoadPlugin3(plugName string, conf jit.BuildConfig, chn chan PluginStruct) {
loadable, err := jit.BuildGoPackage(conf, confdir.Paths.Plugins+plugName+"/")
utils.Check(err)
module, err := loadable.Load()
utils.Check(err)
plugSymbols := module.SymbolsByPkg[loadable.ImportPath]
// fmt.Println(*deneme, *deneme2)
// var empt interface{} = plugSymbols
// a = empt.(TmpTest)
// var a TmpTest
// jit.RegisterTypes(plugSymbols["TmpTest"])
var plugMan PluginStruct
plugMan.PluginFunction = plugSymbols
fmt.Println(plugMan.PluginFunction)
plugMan.Functions = make(map[string](func() (interface{}, error)))
for i, v := range plugMan.PluginFunction {
switch f := v.(type) {
case func([]byte) (interface{}, error):
result, err := f([]byte(`{"k":"v"}`))
if err != nil {
panic(err)
}
fmt.Println(result)
case func() (interface{}, error):
fmt.Println(i, 1)
plugMan.Functions[i] = f
default:
fmt.Println(f)
panic("Function signature was not what was expected")
}
}
fmt.Println(plugMan.Functions)
for i, o := range plugMan.Functions {
// fmt.Println(i, o)
fmt.Println(i, &o)
// fmt.Println(i, *o)
}
// plugMan.Functions["TmpTest"]()
fmt.Println(1)
chn <- plugMan
// var empt mytype = plugSymbols["TmpTest"].(mytype)
// a := empt.(TmpTest)
// fmt.Println(empt)
// switch f := plugSymbols["MyFunc"].(type) {
// case func([]byte) (interface{}, error):
// result, err := f([]byte(`{"k":"v"}`))
// if err != nil {
// panic(err)
// }
// fmt.Println(result)
// default:
// fmt.Println(f)
// panic("Function signature was not what was expected")
// }
// chn <- deneme
}
// func LoadPlugin2(plugName string, plugFunction []string, conf jit.BuildConfig, chn chan interface{}) {
// loadable, err := jit.BuildGoPackage(conf, confdir.Paths.Plugins+plugName+"/")
// utils.Check(err)
// module, err := loadable.Load()
// plugSymbols := module.SymbolsByPkg[loadable.ImportPath]
// utils.Check(err)
// for i, v := range plugFunction {
// var f interface{} = plugSymbols
// }
// // switch f := plugSymbols["MyFunc"].(type) {
// // case func([]byte) (interface{}, error):
// // result, err := f([]byte(`{"k":"v"}`))
// // if err != nil {
// // panic(err)
// // }
// // fmt.Println(result)
// // default:
// // fmt.Println(f)
// // panic("Function signature was not what was expected")
// // }
// // chn <-
// }
//
// -------------------------
// OLD PLUGIN IMPLEMENTATION
// -------------------------
//
// Load Plugin placed in PluginDir, returns empty interface with channel
// Do not forget to cast in plugin manager
//
// Give Plugin Name as argument and be sure you compiled plugins with `-buildmode=plugin` to PluginDir as `pluginname.so`
func LoadPlugin(plugName string, chn chan interface{}) {
// TODO if error caugth try without relative path, this will be good for local testing
plug, err := plugin.Open(confdir.Paths.Plugins + plugName + ".so")
utils.Check(err)
// TODO also allow lookup another symbol other than PlugnameConnect
symPlug, err := plug.Lookup(utils.FirstUpperEN(plugName) + "Connect")
utils.Check(err)
var plugOut interface{}
plugOut, ok := symPlug.(interface{})
if !ok {
fmt.Println("unexpected type from module symbol")
os.Exit(1)
}
chn <- plugOut
}

19
plugins/resources/go.mod Normal file
View file

@ -0,0 +1,19 @@
module git.aliberksandikci.com.tr/Liderahenk/ahenk-go/plugins/resources
go 1.21.0
require git.aliberksandikci.com.tr/Liderahenk/ahenk-go v0.0.0-20230831165035-c1bc30d83082
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
github.com/zcalusic/sysinfo v1.0.1 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/text v0.12.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

29
plugins/resources/go.sum Normal file
View file

@ -0,0 +1,29 @@
git.aliberksandikci.com.tr/Liderahenk/ahenk-go v0.0.0-20230831165035-c1bc30d83082 h1:xSuQQVwNcORPGt23VKivLIhOipz0hx9e5evxxiyV/No=
git.aliberksandikci.com.tr/Liderahenk/ahenk-go v0.0.0-20230831165035-c1bc30d83082/go.mod h1:CsfyC8E2IhrkmUf84/GvIDaofgSxtYdw3lojgQ8YMYc=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/zcalusic/sysinfo v1.0.1 h1:cVh8q3codjh43AGRTa54dJ2Zq+qPejv8n2VWpxKViwc=
github.com/zcalusic/sysinfo v1.0.1/go.mod h1:LxwKwtQdbTIQc65drhjQzYzt0o7jfB80LrrZm7SWn8o=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -1,6 +1,6 @@
package main package resources
func (p plug) Info() map[string]interface{} { func Info() (interface{}, error) {
return map[string]interface{}{ return map[string]interface{}{
"name": "resources", "name": "resources",
"version": "0.1.0", "version": "0.1.0",
@ -10,5 +10,5 @@ func (p plug) Info() map[string]interface{} {
}, },
"description": "Resource Usage Information and Controls", "description": "Resource Usage Information and Controls",
"developer": "asandikci@aliberksandikci.com.tr", "developer": "asandikci@aliberksandikci.com.tr",
} }, nil
} }

View file

@ -1,4 +1,4 @@
package main package resources
import ( import (
"runtime" "runtime"
@ -6,13 +6,8 @@ import (
"git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/osinfo" "git.aliberksandikci.com.tr/Liderahenk/ahenk-go/pkg/osinfo"
) )
type plug string
// exported plugin Symbol
var ResourcesConnect plug
// return instant resource usage information // return instant resource usage information
func (p plug) ResourceUsage() map[string]interface{} { func ResourceUsage() (interface{}, error) {
var system osinfo.System var system osinfo.System
system.GetSystemInfo() system.GetSystemInfo()
@ -35,13 +30,13 @@ func (p plug) ResourceUsage() map[string]interface{} {
} }
// TODO see https://github.com/Pardus-LiderAhenk/ahenk/blob/master/src/plugins/resource-usage/resource_info_fetcher.py // TODO see https://github.com/Pardus-LiderAhenk/ahenk/blob/master/src/plugins/resource-usage/resource_info_fetcher.py
return data return data, nil
} }
// return general Agent system information // return general Agent system information
// //
// these values changes rarely, see ResourceUsage() function for instant resource usage information // these values changes rarely, see ResourceUsage() function for instant resource usage information
func (p plug) AgentInfo() map[string]interface{} { func AgentInfo() (interface{}, error) {
var system osinfo.System var system osinfo.System
system.GetSystemInfo() system.GetSystemInfo()
@ -63,5 +58,5 @@ func (p plug) AgentInfo() map[string]interface{} {
// REVIEW is calling all functions one by one slow downs code? // 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 // TODO see https://github.com/Pardus-LiderAhenk/ahenk/blob/master/src/plugins/resource-usage/agent_info.py
return data return data, nil
} }

3
plugins/tmptest/go.mod Normal file
View file

@ -0,0 +1,3 @@
module git.aliberksandikci.com.tr/Liderahenk/ahenk-go/plugins/tmptest
go 1.21.0