|
@@ -0,0 +1,69 @@
|
|
|
+//+build !windows
|
|
|
+
|
|
|
+package plugin
|
|
|
+
|
|
|
+import (
|
|
|
+ "errors"
|
|
|
+ "fmt"
|
|
|
+ "io/fs"
|
|
|
+ "io/ioutil"
|
|
|
+ "os"
|
|
|
+ "path/filepath"
|
|
|
+ "plugin"
|
|
|
+)
|
|
|
+
|
|
|
+// LoadPlugin 加载插件 传入path
|
|
|
+func LoadPlugin(path string) error {
|
|
|
+ path, err := filepath.Abs(path)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ fileInfo, err := os.Stat(path)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if fileInfo.IsDir() {
|
|
|
+ fileSlice, err := ioutil.ReadDir(path)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ for _, ff := range fileSlice {
|
|
|
+ if !ff.IsDir() && filepath.Ext(ff.Name()) == ".so" {
|
|
|
+ if err = loadPlugin(path, ff); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ } else if ff.IsDir() {
|
|
|
+ _ = LoadPlugin(filepath.Join(path, ff.Name()))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ } else {
|
|
|
+ return loadPlugin(path, fileInfo)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func loadPlugin(path string, f fs.FileInfo) error {
|
|
|
+ if filepath.Ext(f.Name()) == ".so" {
|
|
|
+ fPath := filepath.Join(path, f.Name())
|
|
|
+ // 加载插件
|
|
|
+ p, err := plugin.Open(fPath)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("loadPlugin err ", err)
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ // 判断是否满足协议
|
|
|
+ // 要满足 OnlyFuncName && 实现 Plugin 接口
|
|
|
+ if v, err := p.Lookup(OnlyFuncName); err != nil {
|
|
|
+ fmt.Println("loadPlugin err ", err)
|
|
|
+ return err
|
|
|
+ } else if _, ok := v.(Plugin); !ok {
|
|
|
+ fmt.Println("loadPlugin err ", fmt.Sprintf("path:%s 没有实现 %s 接口", filepath.Base(fPath), OnlyFuncName))
|
|
|
+ return errors.New("没有实现指定接口")
|
|
|
+ } else {
|
|
|
+
|
|
|
+ }
|
|
|
+ fmt.Println("loadPlugin add ", filepath.Base(fPath))
|
|
|
+ ManagementPlugin.SetPlugin(filepath.Base(fPath), p)
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|