commit 6ac65abfa31038101a3582b8c8c150b8ee9fde6a Author: asandikci Date: Thu Aug 31 20:51:52 2023 +0300 Initial Commit diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..d34daa0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "go.buildFlags": ["-tags=linux"], +} \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8efc85e --- /dev/null +++ b/Makefile @@ -0,0 +1,27 @@ +REPO_NAME=go-loader-test +REPO_LINK=https://git.aliberksandikci.com.tr/asandikci/${REPO_NAME} + +DATA_DIR=/etc/go-loader-test/ +LIB_DIR=/usr/share/go-loader-test/ +PLUGIN_DIR=${LIB_DIR}/plugins/ +TEMP_DIR=$(mktemp -d) +MAIN_DIR=${TEMP_DIR}/${REPO_NAME}/ + + +install: + sudo go build -o ${DESTDIR}/usr/bin/${REPO_NAME} ./cmd/go-loader-test/ + @sudo mkdir -p "${DESTDIR}/${LIB_DIR}" + @sudo mkdir -p "${DESTDIR}/${PLUGIN_DIR}" + + 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/go-loader-test/ + @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}/tmptest.so ./plugins/tmptest + @sudo mkdir -p "${DESTDIR}/${DATA_DIR}" +uninstall: + @sudo rm -rf ${DESTDIR}/usr/bin/${REPO_NAME} diff --git a/README.md b/README.md new file mode 100644 index 0000000..a8725e0 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +tests for https://github.com/pkujhd/goloader and https://github.com/eh-steve/goloader. +contains some parts from https://git.aliberksandikci.com.tr/Liderahenk/ahenk-go \ No newline at end of file diff --git a/cmd/go-loader-test/main.go b/cmd/go-loader-test/main.go new file mode 100644 index 0000000..905cc5e --- /dev/null +++ b/cmd/go-loader-test/main.go @@ -0,0 +1,22 @@ +package main + +import ( + "log" + "os" +) + +const ExecutablePath = "/usr/bin/go-loader-test" +const DataDir = "/etc/go-loader-test/" +const LogFile = DataDir + "go-loader-test" +const LibDir = "/usr/share/go-loader-test/" +const PluginDir = LibDir + "/plugins/" + +// Main Function that starts daemon and controls arguments +func main() { + if len(os.Args) == 2 && os.Args[1] == "tmptest" { + log.Print("TEMPORARY TEST STARTED, log files are NOT redirecting!") + PluginManager("tmptest") + } else { + panic("Please enter a valid option !") + } +} diff --git a/cmd/go-loader-test/plugin-manager.go b/cmd/go-loader-test/plugin-manager.go new file mode 100644 index 0000000..269a6b4 --- /dev/null +++ b/cmd/go-loader-test/plugin-manager.go @@ -0,0 +1,74 @@ +package main + +import ( + "encoding/json" + "log" + + "git.aliberksandikci.com.tr/asandikci/go-loader-test/pkg/utils" +) + +// General Functions/Methods that each plugin has +type PlugGeneral interface { + Info() map[string]interface{} +} + +// plugins/tmptest +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{}) + + if len(params) > 0 && params[0] == "tmptest" { + go LoadPlugin("tmptest", chanPlug) + res, ok := <-chanPlug + var tmptest TmpTest = res.(TmpTest) + checkPlugin(res, ok) + tmptest.TmpTest() + } +} + +// 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() { + +// // } diff --git a/cmd/go-loader-test/plugin-opener.go b/cmd/go-loader-test/plugin-opener.go new file mode 100644 index 0000000..7a88095 --- /dev/null +++ b/cmd/go-loader-test/plugin-opener.go @@ -0,0 +1,26 @@ +package main + +import ( + "fmt" + "os" + "plugin" + + "git.aliberksandikci.com.tr/asandikci/go-loader-test/pkg/utils" +) + +func LoadPlugin(plugName string, chn chan interface{}) { + + plug, err := plugin.Open(PluginDir + plugName + ".so") + utils.Check(err) + + 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 +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..351a5f8 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module git.aliberksandikci.com.tr/asandikci/go-loader-test + +go 1.21.0 + +require golang.org/x/text v0.12.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..09c64a2 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +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= diff --git a/pkg/utils/main.go b/pkg/utils/main.go new file mode 100644 index 0000000..165e144 --- /dev/null +++ b/pkg/utils/main.go @@ -0,0 +1,69 @@ +package utils + +import ( + "log" + "os" + + "golang.org/x/text/cases" + "golang.org/x/text/language" +) + +func Byte2String(arr []int8) string { + b := make([]byte, len(arr)) + for i, v := range arr { + b[i] = byte(v) + } + return string(b) +} + +func Byte2MiB(b uint64) float64 { + return float64(float64(b) / (1024 * 1024)) +} + +func Byte2GiB(b uint64) float64 { + return float64(float64(b) / (1024 * 1024 * 1024)) +} + +func MB2GiB(b uint64) float64 { + return float64(float64(b*1000*1000) / (1024 * 1024 * 1024)) +} + +func CheckPath(path string) (bool, error) { + _, err := os.Stat(path) + if err == nil { + return true, nil + } + if os.IsNotExist(err) { + return false, nil + } + return false, err +} + +func CreatePath(path string) { + if flag, err := CheckPath(path); flag { + if err != nil { + log.Fatal(err) + } + } else if err := os.Mkdir(path, os.ModePerm); err != nil { + log.Fatal(err) + } +} + +func Check(err error) { + if err != nil { + panic(err) + } +} + +func OpenLogFile(path string) *os.File { + f, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644) + if err != nil { + panic(err) + } + return f +} + +// Makes first character uppercase of given English string +func FirstUpperEN(str string) string { + return cases.Title(language.English).String(str) +} // TODO cases.NoLower vs cases.Compact ! diff --git a/plugins/tmptest/info.go b/plugins/tmptest/info.go new file mode 100644 index 0000000..34c9fc8 --- /dev/null +++ b/plugins/tmptest/info.go @@ -0,0 +1,11 @@ +package main + +func (p plug) Info() map[string]interface{} { + return map[string]interface{}{ + "name": "tmptest", + "version": "1.0.2", + "support": "any", + "description": "Temporary testing", + "developer": "asandikci@aliberksandikci.com.tr", + } +} diff --git a/plugins/tmptest/main.go b/plugins/tmptest/main.go new file mode 100644 index 0000000..ea057d2 --- /dev/null +++ b/plugins/tmptest/main.go @@ -0,0 +1,24 @@ +package main + +import ( + "fmt" + "time" +) + +type plug string + +// exported plugin Symbol +var TmptestConnect plug + +func (p plug) TmpTest() { + fmt.Println() + fmt.Println("----- Entered Test Area -----") + fmt.Println() + fmt.Println() + + fmt.Println() + fmt.Println() + fmt.Println("----- End of Test Area -----") + fmt.Println() + time.Sleep(3 * time.Second) +}