volcano.sh/volcano@v1.9.0/pkg/scheduler/framework/plugins.go (about) 1 /* 2 Copyright 2018 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package framework 18 19 import ( 20 "fmt" 21 "path/filepath" 22 "plugin" 23 "strings" 24 "sync" 25 26 "k8s.io/klog/v2" 27 ) 28 29 var pluginMutex sync.RWMutex 30 31 // PluginBuilder plugin management 32 type PluginBuilder = func(Arguments) Plugin 33 34 // Plugin management 35 var pluginBuilders = map[string]PluginBuilder{} 36 37 // RegisterPluginBuilder register the plugin 38 func RegisterPluginBuilder(name string, pc PluginBuilder) { 39 pluginMutex.Lock() 40 defer pluginMutex.Unlock() 41 42 pluginBuilders[name] = pc 43 } 44 45 // CleanupPluginBuilders cleans up all the plugin 46 func CleanupPluginBuilders() { 47 pluginMutex.Lock() 48 defer pluginMutex.Unlock() 49 50 pluginBuilders = map[string]PluginBuilder{} 51 } 52 53 // GetPluginBuilder get the pluginbuilder by name 54 func GetPluginBuilder(name string) (PluginBuilder, bool) { 55 pluginMutex.RLock() 56 defer pluginMutex.RUnlock() 57 58 pb, found := pluginBuilders[name] 59 return pb, found 60 } 61 62 // LoadCustomPlugins loads custom implement plugins 63 func LoadCustomPlugins(pluginsDir string) error { 64 pluginPaths, _ := filepath.Glob(fmt.Sprintf("%s/*.so", pluginsDir)) 65 for _, pluginPath := range pluginPaths { 66 pluginBuilder, err := loadPluginBuilder(pluginPath) 67 if err != nil { 68 return err 69 } 70 pluginName := getPluginName(pluginPath) 71 RegisterPluginBuilder(pluginName, pluginBuilder) 72 klog.V(4).Infof("Custom plugin %s loaded", pluginName) 73 } 74 75 return nil 76 } 77 78 func getPluginName(pluginPath string) string { 79 return strings.TrimSuffix(filepath.Base(pluginPath), filepath.Ext(pluginPath)) 80 } 81 82 func loadPluginBuilder(pluginPath string) (PluginBuilder, error) { 83 plug, err := plugin.Open(pluginPath) 84 if err != nil { 85 return nil, err 86 } 87 88 symBuilder, err := plug.Lookup("New") 89 if err != nil { 90 return nil, err 91 } 92 93 builder, ok := symBuilder.(PluginBuilder) 94 if !ok { 95 return nil, fmt.Errorf("unexpected plugin: %s, failed to convert PluginBuilder `New`", pluginPath) 96 } 97 98 return builder, nil 99 } 100 101 // Action management 102 var actionMap = map[string]Action{} 103 104 // RegisterAction register action 105 func RegisterAction(act Action) { 106 pluginMutex.Lock() 107 defer pluginMutex.Unlock() 108 109 actionMap[act.Name()] = act 110 } 111 112 // GetAction get the action by name 113 func GetAction(name string) (Action, bool) { 114 pluginMutex.RLock() 115 defer pluginMutex.RUnlock() 116 117 act, found := actionMap[name] 118 return act, found 119 }