Compare commits

..

2 commits

Author SHA1 Message Date
113359d34b
update readme 2023-09-01 09:52:19 +03:00
6728f916ce
update info 2023-08-31 20:54:18 +03:00
11 changed files with 271 additions and 7 deletions

3
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,3 @@
{
"go.buildFlags": ["-tags=linux"],
}

27
Makefile Normal file
View file

@ -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}

View file

@ -1,8 +1,9 @@
- test for plugin and goloader logics
- contains some parts from https://git.aliberksandikci.com.tr/Liderahenk/ahenk-go
This branch uses original go plugin implementation, see https://pkg.go.dev/plugin and https://git.aliberksandikci.com.tr/Liderahenk/ahenk-docs/src/branch/main/dev/resources.md#plugin-logic for more information
- official plugin logic: https://pkg.go.dev/plugin - [branch](https://git.aliberksandikci.com.tr/asandikci/go-loader-test/src/branch/original-plugin)
- goloader plugin logic: https://github.com/eh-steve/goloader - [branch](https://git.aliberksandikci.com.tr/asandikci/go-loader-test/src/branch/eh-steve/goloader)
- goloader plugin logic + [crosscompile](git.aliberksandikci.com.tr/asandikci/go-crosscompile) - [branch](https://git.aliberksandikci.com.tr/asandikci/go-loader-test/src/branch/eh-steve/goloader+crosscompile)
- see [branches](https://git.aliberksandikci.com.tr/asandikci/go-loader-test/branches) for more
---
# Pros
- Fast, Lightweight
- Official
# Cons
- Can't be unload
- Can't be use with windows

View file

@ -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 !")
}
}

View file

@ -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() {
// // }

View file

@ -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
}

5
go.mod Normal file
View file

@ -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

2
go.sum Normal file
View file

@ -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=

69
pkg/utils/main.go Normal file
View file

@ -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 !

11
plugins/tmptest/info.go Normal file
View file

@ -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",
}
}

24
plugins/tmptest/main.go Normal file
View file

@ -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)
}