89 lines
2.4 KiB
Go
89 lines
2.4 KiB
Go
/*
|
|
* Copyright 2020 The Dragonfly Authors
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package dfplugin
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"path"
|
|
"plugin"
|
|
"regexp"
|
|
)
|
|
|
|
const (
|
|
// PluginFormat indicates the lookup name of a plugin in plugin directory.
|
|
PluginFormat = "d7y-%s-plugin-%s.so"
|
|
|
|
// PluginInitFuncName indicates the function `DragonflyPluginInit` must be implemented in plugin
|
|
PluginInitFuncName = "DragonflyPluginInit"
|
|
|
|
// PluginMetaKeyType indicates the type of plugin, currently support: resource
|
|
PluginMetaKeyType = "type"
|
|
|
|
// PluginMetaKeyName indicates the name of a plugin
|
|
PluginMetaKeyName = "name"
|
|
)
|
|
|
|
var PluginFormatExpr = regexp.MustCompile("d7y-(resource|manager|scheduler)-plugin-([a-z0-9]+).so")
|
|
|
|
type PluginType string
|
|
|
|
const (
|
|
PluginTypeResource = PluginType("resource")
|
|
PluginTypeManager = PluginType("manager")
|
|
PluginTypeScheduler = PluginType("scheduler")
|
|
)
|
|
|
|
type PluginInitFunc func(option map[string]string) (plugin any, meta map[string]string, err error)
|
|
|
|
func Load(dir string, typ PluginType, name string, option map[string]string) (any, map[string]string, error) {
|
|
soName := fmt.Sprintf(PluginFormat, string(typ), name)
|
|
p, err := plugin.Open(path.Join(dir, soName))
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
symbol, err := p.Lookup(PluginInitFuncName)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
// FIXME when use symbol.(PluginInitFunc), ok is always false
|
|
f, ok := symbol.(func(option map[string]string) (plugin any, meta map[string]string, err error))
|
|
if !ok {
|
|
return nil, nil, errors.New("invalid plugin init function signature")
|
|
}
|
|
|
|
i, meta, err := f(option)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
if meta == nil {
|
|
return nil, nil, errors.New("empty plugin metadata")
|
|
}
|
|
|
|
if meta[PluginMetaKeyType] != string(typ) {
|
|
return nil, nil, errors.New("plugin type not match")
|
|
}
|
|
|
|
if meta[PluginMetaKeyName] != name {
|
|
return nil, nil, errors.New("plugin name not match")
|
|
}
|
|
return i, meta, nil
|
|
}
|