Compare commits
4 commits
main
...
eh-steve/g
Author | SHA1 | Date | |
---|---|---|---|
1228feddc8 | |||
c879b68f06 | |||
e2557da13f | |||
31d3dadc52 |
14 changed files with 346 additions and 6 deletions
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"go.buildFlags": ["-tags=linux"],
|
||||
}
|
27
Makefile
Normal file
27
Makefile
Normal 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}
|
23
README.md
23
README.md
|
@ -1,8 +1,19 @@
|
|||
- test for plugin and goloader logics
|
||||
- contains some parts from https://git.aliberksandikci.com.tr/Liderahenk/ahenk-go
|
||||
This branch uses unofficial goloader implementation, see https://pkg.go.dev/github.com/eh-steve/goloader, https://github.com/eh-steve/goloader and https://git.aliberksandikci.com.tr/Liderahenk/ahenk-docs/src/branch/main/dev/resources.md#goloader-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
|
||||
---
|
||||
#### When building for windows:
|
||||
- change `.vscode/settings.json` to `"go.buildFlags": ["-tags=windows"],`
|
||||
- change `cmd/go-loader-test/plugin-manager.go` to `BuildEnv: []string{"GOOS=windows"},`
|
||||
|
||||
---
|
||||
# Pros
|
||||
- Fast, Lightweight
|
||||
- **Can be unload**
|
||||
- **Can be use with windows**
|
||||
- Can build go programs in runtime
|
||||
# Cons
|
||||
- Unofficial
|
||||
- Changes default go configs and compiler settings !!
|
||||
- Missing Security features ?
|
||||
- Missing feature: use precompiled binaries
|
22
cmd/go-loader-test/main.go
Normal file
22
cmd/go-loader-test/main.go
Normal 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 !")
|
||||
}
|
||||
}
|
149
cmd/go-loader-test/plugin-manager.go
Normal file
149
cmd/go-loader-test/plugin-manager.go
Normal file
|
@ -0,0 +1,149 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/eh-steve/goloader/jit"
|
||||
)
|
||||
|
||||
// plugins/addsymbol
|
||||
type AddSymbol interface {
|
||||
st() map[string]interface{}
|
||||
}
|
||||
|
||||
type myInt2 map[string]interface {
|
||||
Symbol(a, b string) (interface{}, error)
|
||||
}
|
||||
|
||||
type STR struct {
|
||||
ress func(a string, b string) (interface{}, error)
|
||||
}
|
||||
|
||||
func PluginManager(params ...string) {
|
||||
conf := jit.BuildConfig{
|
||||
KeepTempFiles: false, // 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: "/tmp/inner", // To control where temporary files are copied
|
||||
DebugLog: false, //
|
||||
}
|
||||
|
||||
loadable, err := jit.BuildGoPackage(conf, "plugins/tmptest/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
module, err := loadable.Load()
|
||||
// module.SymbolsByPkg is a map[string]map[string]interface{} of all packages and their exported functions and global vars
|
||||
symbols := module.SymbolsByPkg[loadable.ImportPath]
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
switch f := symbols["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")
|
||||
}
|
||||
|
||||
// err = module.Unload()
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
loadable2, err := jit.BuildGoPackage(conf, "plugins/addsymbol/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
module2, err := loadable2.Load()
|
||||
// module.SymbolsByPkg is a map[string]map[string]interface{} of all packages and their exported functions and global vars
|
||||
symbols2 := module2.SymbolsByPkg[loadable2.ImportPath]
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// rst
|
||||
switch f2 := symbols2["Symbol"].(type) {
|
||||
|
||||
// rstrst
|
||||
case func(a, b string) (interface{}, error):
|
||||
// var mystruct SymbolPlugS
|
||||
|
||||
var mystr STR
|
||||
// var inter myInt
|
||||
|
||||
mystr.ress = f2
|
||||
// inter = mystr.ress.(myInt)
|
||||
// mystr.ress = Symbol
|
||||
|
||||
// result, err := Im("a", "b")
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
fmt.Println(mystr.ress("a", "b"))
|
||||
fmt.Println(&mystr.ress)
|
||||
// fmt.Println(*mystr.ress)
|
||||
// fmt.Println(*tmpresult)
|
||||
// fmt.Println()
|
||||
default:
|
||||
fmt.Println(symbols2)
|
||||
|
||||
panic("Function signature was not what was expected")
|
||||
}
|
||||
|
||||
// deneme := symbols2["Symbol"]
|
||||
// var inter myInt = deneme.(myInt)
|
||||
// inter.Symbol("st", "st")
|
||||
|
||||
// Symbol := symbols2["Symbol"]
|
||||
// if f, ok := Symbol.(func(a, b string) (interface{}, error)); ok {
|
||||
// // fmt.Println(HandlerType(f)("rst", "rstrtd"))
|
||||
// fmt.Println(f("ast", "srd"))
|
||||
// }
|
||||
|
||||
// for i, v := range symbols2 {
|
||||
// fmt.Println(i, v)
|
||||
// }
|
||||
// fmt.Println(&symbols2)
|
||||
// fmt.Println(symbols2)
|
||||
// fmt.Println()
|
||||
// fmt.Println(symbols)
|
||||
// fmt.Println(&symbols)
|
||||
|
||||
defer func() {
|
||||
err = module2.Unload()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
fmt.Println()
|
||||
fmt.Println()
|
||||
fmt.Println()
|
||||
|
||||
var empt interface{} = symbols2
|
||||
var inter myInt = empt.(myInt)
|
||||
// inter.Symbol("a", "b")
|
||||
fmt.Println(inter)
|
||||
fmt.Println(symbols2["Symbol"])
|
||||
|
||||
fmt.Println()
|
||||
fmt.Println()
|
||||
fmt.Println()
|
||||
|
||||
}
|
||||
|
||||
type myInt interface {
|
||||
// Symbol(a, b string) (interface{}, error)
|
||||
}
|
BIN
go-loader-test
Executable file
BIN
go-loader-test
Executable file
Binary file not shown.
10
go.mod
Normal file
10
go.mod
Normal file
|
@ -0,0 +1,10 @@
|
|||
module git.aliberksandikci.com.tr/asandikci/go-loader-test
|
||||
|
||||
go 1.21.0
|
||||
|
||||
require (
|
||||
github.com/eh-steve/goloader/jit v0.0.0-20230731163325-b789213e8550
|
||||
golang.org/x/text v0.12.0
|
||||
)
|
||||
|
||||
require github.com/eh-steve/goloader v0.0.0-20230730231803-5c95d7a5f4e2 // indirect
|
6
go.sum
Normal file
6
go.sum
Normal file
|
@ -0,0 +1,6 @@
|
|||
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=
|
||||
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
69
pkg/utils/main.go
Normal 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 !
|
9
plugins/addsymbol/symbol.go
Normal file
9
plugins/addsymbol/symbol.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
package addsymbol
|
||||
|
||||
func Symbol(a, b string) (interface{}, error) {
|
||||
return symbol(a, b), nil
|
||||
}
|
||||
|
||||
func TMPFUNC() {
|
||||
|
||||
}
|
7
plugins/addsymbol/symbol_linux.go
Normal file
7
plugins/addsymbol/symbol_linux.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
// go:build linux && !windows
|
||||
|
||||
package addsymbol
|
||||
|
||||
func symbol(a, b string) string {
|
||||
return a + "+" + b + "=linux"
|
||||
}
|
7
plugins/addsymbol/symbol_windows.go
Normal file
7
plugins/addsymbol/symbol_windows.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
// go:build windows
|
||||
|
||||
package addsymbol
|
||||
|
||||
func symbol(a, b string) string {
|
||||
return a + "-" + b + "=windows"
|
||||
}
|
11
plugins/tmptest/info.go
Normal file
11
plugins/tmptest/info.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
package mypackage
|
||||
|
||||
// func Info() map[string]interface{} {
|
||||
// return map[string]interface{}{
|
||||
// "name": "tmptest",
|
||||
// "version": "1.0.2",
|
||||
// "support": "any",
|
||||
// "description": "Temporary testing",
|
||||
// "developer": "asandikci@aliberksandikci.com.tr",
|
||||
// }
|
||||
// }
|
9
plugins/tmptest/main.go
Normal file
9
plugins/tmptest/main.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
package mypackage
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
func MyFunc(input []byte) (interface{}, error) {
|
||||
var output interface{}
|
||||
err := json.Unmarshal(input, &output)
|
||||
return output, err
|
||||
}
|
Loading…
Reference in a new issue