diff --git a/pkg/cmd/web.go b/pkg/cmd/web.go index 57726de654f..61534e7d346 100644 --- a/pkg/cmd/web.go +++ b/pkg/cmd/web.go @@ -31,7 +31,7 @@ func newMacaron() *macaron.Macaron { for _, route := range plugins.StaticRoutes { pluginRoute := path.Join("/public/plugins/", route.PluginId) - log.Info("Plugin: Adding static route %s -> %s", pluginRoute, route.Directory) + log.Info("Plugins: Adding route %s -> %s", pluginRoute, route.Directory) mapStatic(m, route.Directory, "", pluginRoute) } diff --git a/pkg/plugins/app_plugin.go b/pkg/plugins/app_plugin.go index aa704da7f74..474b7354762 100644 --- a/pkg/plugins/app_plugin.go +++ b/pkg/plugins/app_plugin.go @@ -57,7 +57,9 @@ func (app *AppPlugin) Load(decoder *json.Decoder, pluginDir string) error { return err } - app.PluginDir = pluginDir + if err := app.registerPlugin(pluginDir); err != nil { + return err + } Apps[app.Id] = app return nil diff --git a/pkg/plugins/datasource_plugin.go b/pkg/plugins/datasource_plugin.go index 2e1dd806e23..ecffb87b8db 100644 --- a/pkg/plugins/datasource_plugin.go +++ b/pkg/plugins/datasource_plugin.go @@ -17,8 +17,10 @@ func (p *DataSourcePlugin) Load(decoder *json.Decoder, pluginDir string) error { return err } - p.PluginDir = pluginDir - DataSources[p.Id] = p + if err := p.registerPlugin(pluginDir); err != nil { + return err + } + DataSources[p.Id] = p return nil } diff --git a/pkg/plugins/frontend_plugin.go b/pkg/plugins/frontend_plugin.go index 9e4d9f67053..a1bcd0c68b5 100644 --- a/pkg/plugins/frontend_plugin.go +++ b/pkg/plugins/frontend_plugin.go @@ -6,7 +6,6 @@ import ( "path/filepath" "strings" - "github.com/grafana/grafana/pkg/log" "github.com/grafana/grafana/pkg/util" ) @@ -38,13 +37,10 @@ func (fp *FrontendPluginBase) initFrontendPlugin() { } func (fp *FrontendPluginBase) setPathsBasedOnApp(app *AppPlugin) { - // log.Info("Module Before: %v", fp.Module) - // find out plugins path relative to app static root appSubPath := strings.Replace(fp.PluginDir, app.StaticRootAbs, "", 1) fp.IncludedInAppId = app.Id fp.BaseUrl = app.BaseUrl fp.Module = util.JoinUrlFragments("plugins/"+app.Id, appSubPath) + "/module" - log.Info("setting paths based on app: subpath = %v, module: %v", appSubPath, fp.Module) } func (fp *FrontendPluginBase) handleModuleDefaults() { diff --git a/pkg/plugins/models.go b/pkg/plugins/models.go index f45b3718a67..83f43c1f544 100644 --- a/pkg/plugins/models.go +++ b/pkg/plugins/models.go @@ -2,6 +2,11 @@ package plugins import ( "encoding/json" + "errors" + "strings" + + "github.com/grafana/grafana/pkg/log" + "github.com/grafana/grafana/pkg/setting" ) type PluginLoader interface { @@ -18,6 +23,20 @@ type PluginBase struct { PluginDir string `json:"-"` } +func (pb *PluginBase) registerPlugin(pluginDir string) error { + if _, exists := Plugins[pb.Id]; exists { + return errors.New("Plugin with same id already exists") + } + + if !strings.HasPrefix(pluginDir, setting.StaticRootPath) { + log.Info("Plugins: Registering plugin %v", pb.Name) + } + + pb.PluginDir = pluginDir + Plugins[pb.Id] = pb + return nil +} + type PluginInfo struct { Author PluginInfoLink `json:"author"` Description string `json:"description"` diff --git a/pkg/plugins/panel_plugin.go b/pkg/plugins/panel_plugin.go index ae638b6777e..49cbfb19fc6 100644 --- a/pkg/plugins/panel_plugin.go +++ b/pkg/plugins/panel_plugin.go @@ -11,8 +11,10 @@ func (p *PanelPlugin) Load(decoder *json.Decoder, pluginDir string) error { return err } - p.PluginDir = pluginDir - Panels[p.Id] = p + if err := p.registerPlugin(pluginDir); err != nil { + return err + } + Panels[p.Id] = p return nil } diff --git a/pkg/plugins/plugins.go b/pkg/plugins/plugins.go index ab679baa796..e4a8f52b259 100644 --- a/pkg/plugins/plugins.go +++ b/pkg/plugins/plugins.go @@ -19,6 +19,7 @@ var ( Panels map[string]*PanelPlugin StaticRoutes []*PluginStaticRoute Apps map[string]*AppPlugin + Plugins map[string]*PluginBase PluginTypes map[string]interface{} ) @@ -32,14 +33,30 @@ func Init() error { StaticRoutes = make([]*PluginStaticRoute, 0) Panels = make(map[string]*PanelPlugin) Apps = make(map[string]*AppPlugin) + Plugins = make(map[string]*PluginBase) PluginTypes = map[string]interface{}{ "panel": PanelPlugin{}, "datasource": DataSourcePlugin{}, "app": AppPlugin{}, } + log.Info("Plugins: Scan starting") scan(path.Join(setting.StaticRootPath, "app/plugins")) - scan(setting.PluginsPath) + + // check if plugins dir exists + if _, err := os.Stat(setting.PluginsPath); os.IsNotExist(err) { + log.Warn("Plugins: Plugin dir %v does not exist", setting.PluginsPath) + if err = os.MkdirAll(setting.PluginsPath, os.ModePerm); err != nil { + log.Warn("Plugins: Failed to create plugin dir: %v, error: %v", setting.PluginsPath, err) + } else { + log.Info("Plugins: Plugin dir %v created", setting.PluginsPath) + scan(setting.PluginsPath) + } + } else { + scan(setting.PluginsPath) + } + + // check plugin paths defined in config checkPluginPaths() for _, panel := range Panels { @@ -55,32 +72,11 @@ func Init() error { return nil } -// func checkDependencies() { -// for appType, app := range Apps { -// for _, reqPanel := range app.PanelPlugins { -// if _, ok := Panels[reqPanel]; !ok { -// log.Fatal(4, "App %s requires Panel type %s, but it is not present.", appType, reqPanel) -// } -// } -// for _, reqDataSource := range app.DatasourcePlugins { -// if _, ok := DataSources[reqDataSource]; !ok { -// log.Fatal(4, "App %s requires DataSource type %s, but it is not present.", appType, reqDataSource) -// } -// } -// for _, reqApiPlugin := range app.ApiPlugins { -// if _, ok := ApiPlugins[reqApiPlugin]; !ok { -// log.Fatal(4, "App %s requires ApiPlugin type %s, but it is not present.", appType, reqApiPlugin) -// } -// } -// } -// } - func checkPluginPaths() 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) } } @@ -93,6 +89,8 @@ func scan(pluginDir string) error { pluginPath: pluginDir, } + log.Info("Plugins: Scaning dir %s", pluginDir) + if err := util.Walk(pluginDir, true, true, scanner.walker); err != nil { if pluginDir != "data/plugins" { log.Warn("Could not scan dir \"%v\" error: %s", pluginDir, err) @@ -123,7 +121,7 @@ func (scanner *PluginScanner) walker(currentPath string, f os.FileInfo, err erro 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) + log.Error(3, "Plugins: Failed to load plugin json file: %v, err: %v", currentPath, err) scanner.errors = append(scanner.errors, err) } } diff --git a/public/app/plugins/datasource/influxdb/plugin.json b/public/app/plugins/datasource/influxdb/plugin.json index 4007010fd21..dd60a16b715 100644 --- a/public/app/plugins/datasource/influxdb/plugin.json +++ b/public/app/plugins/datasource/influxdb/plugin.json @@ -1,6 +1,6 @@ { "type": "datasource", - "name": "InfluxDB 0.9.x", + "name": "InfluxDB", "id": "influxdb", "defaultMatchFormat": "regex values",