mirror of
https://github.com/grafana/grafana.git
synced 2025-07-31 06:32:17 +08:00

symlinks outside to plugin folder can cause problems. This commit makes sure to warn about it in the logs
148 lines
3.1 KiB
Go
148 lines
3.1 KiB
Go
package plugins
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/grafana/grafana/pkg/log"
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
"github.com/grafana/grafana/pkg/util"
|
|
)
|
|
|
|
var (
|
|
DataSources map[string]DataSourcePlugin
|
|
Panels map[string]PanelPlugin
|
|
StaticRoutes []*StaticRootConfig
|
|
)
|
|
|
|
type PluginScanner struct {
|
|
pluginPath string
|
|
errors []error
|
|
}
|
|
|
|
func Init() error {
|
|
DataSources = make(map[string]DataSourcePlugin)
|
|
StaticRoutes = make([]*StaticRootConfig, 0)
|
|
Panels = make(map[string]PanelPlugin)
|
|
|
|
scan(path.Join(setting.StaticRootPath, "app/plugins"))
|
|
scan(path.Join(setting.PluginsPath))
|
|
checkExternalPluginPaths()
|
|
|
|
return nil
|
|
}
|
|
|
|
func checkExternalPluginPaths() error {
|
|
for _, section := range setting.Cfg.Sections() {
|
|
if strings.HasPrefix(section.Name(), "plugin.") {
|
|
path := section.Key("path").String()
|
|
if path != "" {
|
|
log.Info("Plugin: Scaning dir %s", path)
|
|
scan(path)
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func scan(pluginDir string) error {
|
|
scanner := &PluginScanner{
|
|
pluginPath: pluginDir,
|
|
}
|
|
|
|
if err := util.Walk(pluginDir, true, true, scanner.walker); err != nil {
|
|
log.Warn("Failed to scan dir \"%v\" error: %s", pluginDir, err)
|
|
return err
|
|
}
|
|
|
|
if len(scanner.errors) > 0 {
|
|
return errors.New("Some plugins failed to load")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (scanner *PluginScanner) walker(currentPath string, f os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if f.IsDir() {
|
|
return nil
|
|
}
|
|
|
|
if f.Name() == "plugin.json" {
|
|
err := scanner.loadPluginJson(currentPath)
|
|
if err != nil {
|
|
log.Error(3, "Failed to load plugin json file: %v, err: %v", currentPath, err)
|
|
scanner.errors = append(scanner.errors, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func addStaticRoot(staticRootConfig *StaticRootConfig, currentDir string) {
|
|
if staticRootConfig != nil {
|
|
staticRootConfig.Path = path.Join(currentDir, staticRootConfig.Path)
|
|
StaticRoutes = append(StaticRoutes, staticRootConfig)
|
|
}
|
|
}
|
|
|
|
func (scanner *PluginScanner) loadPluginJson(pluginJsonFilePath string) error {
|
|
currentDir := filepath.Dir(pluginJsonFilePath)
|
|
reader, err := os.Open(pluginJsonFilePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer reader.Close()
|
|
|
|
jsonParser := json.NewDecoder(reader)
|
|
|
|
pluginJson := make(map[string]interface{})
|
|
if err := jsonParser.Decode(&pluginJson); err != nil {
|
|
return err
|
|
}
|
|
|
|
pluginType, exists := pluginJson["pluginType"]
|
|
if !exists {
|
|
return errors.New("Did not find pluginType property in plugin.json")
|
|
}
|
|
|
|
if pluginType == "datasource" {
|
|
p := DataSourcePlugin{}
|
|
reader.Seek(0, 0)
|
|
if err := jsonParser.Decode(&p); err != nil {
|
|
return err
|
|
}
|
|
|
|
if p.Type == "" {
|
|
return errors.New("Did not find type property in plugin.json")
|
|
}
|
|
|
|
DataSources[p.Type] = p
|
|
addStaticRoot(p.StaticRootConfig, currentDir)
|
|
}
|
|
|
|
if pluginType == "panel" {
|
|
p := PanelPlugin{}
|
|
reader.Seek(0, 0)
|
|
if err := jsonParser.Decode(&p); err != nil {
|
|
return err
|
|
}
|
|
|
|
if p.Type == "" {
|
|
return errors.New("Did not find type property in plugin.json")
|
|
}
|
|
|
|
Panels[p.Type] = p
|
|
addStaticRoot(p.StaticRootConfig, currentDir)
|
|
}
|
|
|
|
return nil
|
|
}
|