diff --git a/pkg/plugins/manager/loader/assetpath/assetpath.go b/pkg/plugins/manager/loader/assetpath/assetpath.go index cc610f8d340..bc235c38466 100644 --- a/pkg/plugins/manager/loader/assetpath/assetpath.go +++ b/pkg/plugins/manager/loader/assetpath/assetpath.go @@ -47,12 +47,12 @@ func DefaultService(cfg *config.Cfg) *Service { func (s *Service) Base(n PluginInfo) (string, error) { if n.class == plugins.ClassCore { baseDir := getBaseDir(n.dir) - return path.Join("/", s.cfg.GrafanaAppSubURL, "/public/app/plugins", string(n.pluginJSON.Type), baseDir), nil + return path.Join("public/app/plugins", string(n.pluginJSON.Type), baseDir), nil } if s.cdn.PluginSupported(n.pluginJSON.ID) { return s.cdn.AssetURL(n.pluginJSON.ID, n.pluginJSON.Info.Version, "") } - return path.Join("/", s.cfg.GrafanaAppSubURL, "/public/plugins", n.pluginJSON.ID), nil + return path.Join("public/plugins", n.pluginJSON.ID), nil } // Module returns the module.js path for the specified plugin. @@ -70,7 +70,7 @@ func (s *Service) Module(n PluginInfo) (string, error) { if s.cdn.PluginSupported(n.pluginJSON.ID) { return s.cdn.AssetURL(n.pluginJSON.ID, n.pluginJSON.Info.Version, "module.js") } - return path.Join("/", s.cfg.GrafanaAppSubURL, "/public/plugins", n.pluginJSON.ID, "module.js"), nil + return path.Join("public/plugins", n.pluginJSON.ID, "module.js"), nil } // RelativeURL returns the relative URL for an arbitrary plugin asset. @@ -101,7 +101,7 @@ func (s *Service) RelativeURL(n PluginInfo, pathStr string) (string, error) { // DefaultLogoPath returns the default logo path for the specified plugin type. func (s *Service) DefaultLogoPath(pluginType plugins.Type) string { - return path.Join("/", s.cfg.GrafanaAppSubURL, fmt.Sprintf("/public/img/icn-%s.svg", string(pluginType))) + return path.Join("public/img", fmt.Sprintf("icn-%s.svg", string(pluginType))) } func getBaseDir(pluginDir string) string { diff --git a/pkg/plugins/manager/loader/assetpath/assetpath_test.go b/pkg/plugins/manager/loader/assetpath/assetpath_test.go index 78d32ee75d6..be0303f2732 100644 --- a/pkg/plugins/manager/loader/assetpath/assetpath_test.go +++ b/pkg/plugins/manager/loader/assetpath/assetpath_test.go @@ -69,11 +69,11 @@ func TestService(t *testing.T) { base, err = svc.Base(NewPluginInfo(jsonData["two"], plugins.ClassExternal, extPath("two"))) require.NoError(t, err) - require.Equal(t, "/public/plugins/two", base) + require.Equal(t, "public/plugins/two", base) base, err = svc.Base(NewPluginInfo(jsonData["table-old"], plugins.ClassCore, tableOldFS)) require.NoError(t, err) - require.Equal(t, "/public/app/plugins/table-old", base) + require.Equal(t, "public/app/plugins/table-old", base) }) t.Run("Module", func(t *testing.T) { @@ -86,7 +86,7 @@ func TestService(t *testing.T) { module, err = svc.Module(NewPluginInfo(jsonData["two"], plugins.ClassExternal, extPath("two"))) require.NoError(t, err) - require.Equal(t, "/public/plugins/two/module.js", module) + require.Equal(t, "public/plugins/two/module.js", module) module, err = svc.Module(NewPluginInfo(jsonData["table-old"], plugins.ClassCore, tableOldFS)) require.NoError(t, err) @@ -116,16 +116,16 @@ func TestService(t *testing.T) { u, err = svc.RelativeURL(NewPluginInfo(pluginsMap["two"].JSONData, plugins.ClassExternal, extPath("two")), "path/to/file.txt") require.NoError(t, err) - require.Equal(t, "/public/plugins/two/path/to/file.txt", u) + require.Equal(t, "public/plugins/two/path/to/file.txt", u) u, err = svc.RelativeURL(NewPluginInfo(pluginsMap["two"].JSONData, plugins.ClassExternal, extPath("two")), "default") require.NoError(t, err) - require.Equal(t, "/public/plugins/two/default", u) + require.Equal(t, "public/plugins/two/default", u) }) }) } - t.Run("With App Sub URL", func(t *testing.T) { + t.Run("App Sub URL has no effect on the path", func(t *testing.T) { for _, tc := range []struct { appSubURL string }{ @@ -151,15 +151,15 @@ func TestService(t *testing.T) { base, err := svc.Base(NewPluginInfo(p, plugins.ClassExternal, fs)) require.NoError(t, err) - require.Equal(t, "/grafana/public/plugins/test-datasource", base) + require.Equal(t, "public/plugins/test-datasource", base) mod, err := svc.Module(NewPluginInfo(p, plugins.ClassExternal, fs)) require.NoError(t, err) - require.Equal(t, "/grafana/public/plugins/test-datasource/module.js", mod) + require.Equal(t, "public/plugins/test-datasource/module.js", mod) base, err = svc.Base(NewPluginInfo(p, plugins.ClassCore, fs)) require.NoError(t, err) - require.Equal(t, "/grafana/public/app/plugins/test-datasource", base) + require.Equal(t, "public/app/plugins/test-datasource", base) mod, err = svc.Module(NewPluginInfo(p, plugins.ClassCore, fs)) require.NoError(t, err) diff --git a/pkg/plugins/manager/loader/loader_test.go b/pkg/plugins/manager/loader/loader_test.go index b152019ec40..111494e6227 100644 --- a/pkg/plugins/manager/loader/loader_test.go +++ b/pkg/plugins/manager/loader/loader_test.go @@ -83,8 +83,8 @@ func TestLoader_Load(t *testing.T) { }, Description: "Data source for Amazon AWS monitoring service", Logos: plugins.Logos{ - Small: "/public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png", - Large: "/public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png", + Small: "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png", + Large: "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png", }, }, Includes: []*plugins.Includes{ @@ -106,9 +106,8 @@ func TestLoader_Load(t *testing.T) { Backend: true, QueryOptions: map[string]bool{"minInterval": true}, }, - Module: "core:plugin/cloudwatch", - BaseURL: "/public/app/plugins/datasource/cloudwatch", - + Module: "core:plugin/cloudwatch", + BaseURL: "public/app/plugins/datasource/cloudwatch", FS: mustNewStaticFSForTests(t, filepath.Join(corePluginDir, "app/plugins/datasource/cloudwatch")), Signature: plugins.SignatureStatusInternal, Class: plugins.ClassCore, @@ -133,8 +132,8 @@ func TestLoader_Load(t *testing.T) { }, Version: "1.0.0", Logos: plugins.Logos{ - Small: "/public/img/icn-datasource.svg", - Large: "/public/img/icn-datasource.svg", + Small: "public/img/icn-datasource.svg", + Large: "public/img/icn-datasource.svg", }, Description: "Test", }, @@ -146,8 +145,8 @@ func TestLoader_Load(t *testing.T) { Backend: true, State: "alpha", }, - Module: "/public/plugins/test-datasource/module.js", - BaseURL: "/public/plugins/test-datasource", + Module: "public/plugins/test-datasource/module.js", + BaseURL: "public/plugins/test-datasource", FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/valid-v2-signature/plugin/")), Signature: "valid", SignatureType: plugins.SignatureTypeGrafana, @@ -172,8 +171,8 @@ func TestLoader_Load(t *testing.T) { URL: "http://test.com", }, Logos: plugins.Logos{ - Small: "/public/plugins/test-app/img/logo_small.png", - Large: "/public/plugins/test-app/img/logo_large.png", + Small: "public/plugins/test-app/img/logo_small.png", + Large: "public/plugins/test-app/img/logo_large.png", }, Links: []plugins.InfoLink{ {Name: "Project site", URL: "http://project.com"}, @@ -181,8 +180,8 @@ func TestLoader_Load(t *testing.T) { }, Description: "Official Grafana Test App & Dashboard bundle", Screenshots: []plugins.Screenshots{ - {Path: "/public/plugins/test-app/img/screenshot1.png", Name: "img1"}, - {Path: "/public/plugins/test-app/img/screenshot2.png", Name: "img2"}, + {Path: "public/plugins/test-app/img/screenshot1.png", Name: "img1"}, + {Path: "public/plugins/test-app/img/screenshot2.png", Name: "img2"}, }, Version: "1.0.0", Updated: "2015-02-10", @@ -223,8 +222,8 @@ func TestLoader_Load(t *testing.T) { }, }, Class: plugins.ClassExternal, - Module: "/public/plugins/test-app/module.js", - BaseURL: "/public/plugins/test-app", + Module: "public/plugins/test-app/module.js", + BaseURL: "public/plugins/test-app", FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/includes-symlinks")), Signature: "valid", SignatureType: plugins.SignatureTypeGrafana, @@ -251,8 +250,8 @@ func TestLoader_Load(t *testing.T) { URL: "https://grafana.com", }, Logos: plugins.Logos{ - Small: "/public/img/icn-datasource.svg", - Large: "/public/img/icn-datasource.svg", + Small: "public/img/icn-datasource.svg", + Large: "public/img/icn-datasource.svg", }, Description: "Test", }, @@ -264,8 +263,8 @@ func TestLoader_Load(t *testing.T) { State: plugins.ReleaseStateAlpha, }, Class: plugins.ClassExternal, - Module: "/public/plugins/test-datasource/module.js", - BaseURL: "/public/plugins/test-datasource", + Module: "public/plugins/test-datasource/module.js", + BaseURL: "public/plugins/test-datasource", FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/unsigned-datasource/plugin")), Signature: "unsigned", }, @@ -298,8 +297,8 @@ func TestLoader_Load(t *testing.T) { URL: "https://grafana.com", }, Logos: plugins.Logos{ - Small: "/public/img/icn-datasource.svg", - Large: "/public/img/icn-datasource.svg", + Small: "public/img/icn-datasource.svg", + Large: "public/img/icn-datasource.svg", }, Description: "Test", }, @@ -311,8 +310,8 @@ func TestLoader_Load(t *testing.T) { State: plugins.ReleaseStateAlpha, }, Class: plugins.ClassExternal, - Module: "/public/plugins/test-datasource/module.js", - BaseURL: "/public/plugins/test-datasource", + Module: "public/plugins/test-datasource/module.js", + BaseURL: "public/plugins/test-datasource", FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/unsigned-datasource/plugin")), Signature: plugins.SignatureStatusUnsigned, }, @@ -381,8 +380,8 @@ func TestLoader_Load(t *testing.T) { {Name: "License & Terms", URL: "http://license.com"}, }, Logos: plugins.Logos{ - Small: "/public/img/icn-app.svg", - Large: "/public/img/icn-app.svg", + Small: "public/img/icn-app.svg", + Large: "public/img/icn-app.svg", }, Updated: "2015-02-10", }, @@ -401,8 +400,8 @@ func TestLoader_Load(t *testing.T) { FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/test-app-with-includes")), Class: plugins.ClassExternal, Signature: plugins.SignatureStatusUnsigned, - Module: "/public/plugins/test-app/module.js", - BaseURL: "/public/plugins/test-app", + Module: "public/plugins/test-app/module.js", + BaseURL: "public/plugins/test-app", }, }, }, @@ -427,8 +426,8 @@ func TestLoader_Load(t *testing.T) { URL: "https://grafana.com", }, Logos: plugins.Logos{ - Small: "/grafana/public/img/icn-datasource.svg", - Large: "/grafana/public/img/icn-datasource.svg", + Small: "public/img/icn-datasource.svg", + Large: "public/img/icn-datasource.svg", }, Description: "Test", }, @@ -440,8 +439,8 @@ func TestLoader_Load(t *testing.T) { State: plugins.ReleaseStateAlpha, }, Class: plugins.ClassExternal, - Module: "/grafana/public/plugins/test-datasource/module.js", - BaseURL: "/grafana/public/plugins/test-datasource", + Module: "public/plugins/test-datasource/module.js", + BaseURL: "public/plugins/test-datasource", FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/unsigned-datasource/plugin")), Signature: plugins.SignatureStatusUnsigned, }, diff --git a/pkg/plugins/manager/pipeline/bootstrap/steps.go b/pkg/plugins/manager/pipeline/bootstrap/steps.go index 83e025b18cf..ab77106b740 100644 --- a/pkg/plugins/manager/pipeline/bootstrap/steps.go +++ b/pkg/plugins/manager/pipeline/bootstrap/steps.go @@ -33,7 +33,7 @@ func DefaultDecorateFuncs(cfg *config.Cfg) []DecorateFunc { return []DecorateFunc{ AppDefaultNavURLDecorateFunc, TemplateDecorateFunc, - AppChildDecorateFunc(cfg), + AppChildDecorateFunc(), SkipHostEnvVarsDecorateFunc(cfg), } } @@ -133,27 +133,28 @@ func setDefaultNavURL(p *plugins.Plugin) { } // AppChildDecorateFunc is a DecorateFunc that configures child plugins of app plugins. -func AppChildDecorateFunc(cfg *config.Cfg) DecorateFunc { +func AppChildDecorateFunc() DecorateFunc { return func(_ context.Context, p *plugins.Plugin) (*plugins.Plugin, error) { if p.Parent != nil && p.Parent.IsApp() { - configureAppChildPlugin(cfg, p.Parent, p) + configureAppChildPlugin(p.Parent, p) } return p, nil } } -func configureAppChildPlugin(cfg *config.Cfg, parent *plugins.Plugin, child *plugins.Plugin) { +func configureAppChildPlugin(parent *plugins.Plugin, child *plugins.Plugin) { if !parent.IsApp() { return } child.IncludedInAppID = parent.ID child.BaseURL = parent.BaseURL + // TODO move this logic within assetpath package appSubPath := strings.ReplaceAll(strings.Replace(child.FS.Base(), parent.FS.Base(), "", 1), "\\", "/") if parent.IsCorePlugin() { child.Module = path.Join("core:plugin", parent.ID, appSubPath) } else { - child.Module = path.Join("/", cfg.GrafanaAppSubURL, "/public/plugins", parent.ID, appSubPath, "module.js") + child.Module = path.Join("public/plugins", parent.ID, appSubPath, "module.js") } } diff --git a/pkg/plugins/manager/pipeline/bootstrap/steps_test.go b/pkg/plugins/manager/pipeline/bootstrap/steps_test.go index 53302890df0..d64ab36a2b0 100644 --- a/pkg/plugins/manager/pipeline/bootstrap/steps_test.go +++ b/pkg/plugins/manager/pipeline/bootstrap/steps_test.go @@ -108,25 +108,17 @@ func Test_configureAppChildPlugin(t *testing.T) { }, Class: plugins.ClassCore, FS: fakes.NewFakePluginFiles("c:\\grafana\\public\\app\\plugins\\app\\testdata-app"), - BaseURL: "/public/app/plugins/app/testdata-app", + BaseURL: "public/app/plugins/app/testdata-app", } - configureAppChildPlugin(&config.Cfg{}, parent, child) + configureAppChildPlugin(parent, child) require.Equal(t, "core:plugin/testdata-app/datasources/datasource", child.Module) require.Equal(t, "testdata-app", child.IncludedInAppID) - require.Equal(t, "/public/app/plugins/app/testdata-app", child.BaseURL) - - t.Run("App sub URL has no effect on Core plugins", func(t *testing.T) { - configureAppChildPlugin(&config.Cfg{GrafanaAppSubURL: "/grafana"}, parent, child) - - require.Equal(t, "core:plugin/testdata-app/datasources/datasource", child.Module) - require.Equal(t, "testdata-app", child.IncludedInAppID) - require.Equal(t, "/public/app/plugins/app/testdata-app", child.BaseURL) - }) + require.Equal(t, "public/app/plugins/app/testdata-app", child.BaseURL) }) - t.Run("When setting paths based on external plugin with app sub URL", func(t *testing.T) { + t.Run("When setting paths based on external plugin", func(t *testing.T) { child := &plugins.Plugin{ FS: fakes.NewFakePluginFiles("/plugins/parent-app/child-panel"), } @@ -137,14 +129,14 @@ func Test_configureAppChildPlugin(t *testing.T) { }, Class: plugins.ClassExternal, FS: fakes.NewFakePluginFiles("/plugins/parent-app"), - BaseURL: "/grafana/plugins/parent-app", + BaseURL: "plugins/parent-app", } - configureAppChildPlugin(&config.Cfg{GrafanaAppSubURL: "/grafana"}, parent, child) + configureAppChildPlugin(parent, child) - require.Equal(t, "/grafana/public/plugins/testdata-app/child-panel/module.js", child.Module) + require.Equal(t, "public/plugins/testdata-app/child-panel/module.js", child.Module) require.Equal(t, "testdata-app", child.IncludedInAppID) - require.Equal(t, "/grafana/plugins/parent-app", child.BaseURL) + require.Equal(t, "plugins/parent-app", child.BaseURL) }) } diff --git a/pkg/services/pluginsintegration/loader/loader_test.go b/pkg/services/pluginsintegration/loader/loader_test.go index 66370f71554..42799286cc1 100644 --- a/pkg/services/pluginsintegration/loader/loader_test.go +++ b/pkg/services/pluginsintegration/loader/loader_test.go @@ -83,8 +83,8 @@ func TestLoader_Load(t *testing.T) { }, Description: "Data source for Amazon AWS monitoring service", Logos: plugins.Logos{ - Small: "/public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png", - Large: "/public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png", + Small: "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png", + Large: "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png", }, }, Includes: []*plugins.Includes{ @@ -106,9 +106,8 @@ func TestLoader_Load(t *testing.T) { Backend: true, QueryOptions: map[string]bool{"minInterval": true}, }, - Module: "core:plugin/cloudwatch", - BaseURL: "/public/app/plugins/datasource/cloudwatch", - + Module: "core:plugin/cloudwatch", + BaseURL: "public/app/plugins/datasource/cloudwatch", FS: mustNewStaticFSForTests(t, filepath.Join(corePluginDir(t), "app/plugins/datasource/cloudwatch")), Signature: plugins.SignatureStatusInternal, Class: plugins.ClassCore, @@ -133,8 +132,8 @@ func TestLoader_Load(t *testing.T) { }, Version: "1.0.0", Logos: plugins.Logos{ - Small: "/public/img/icn-datasource.svg", - Large: "/public/img/icn-datasource.svg", + Small: "public/img/icn-datasource.svg", + Large: "public/img/icn-datasource.svg", }, Description: "Test", }, @@ -146,8 +145,8 @@ func TestLoader_Load(t *testing.T) { Backend: true, State: "alpha", }, - Module: "/public/plugins/test-datasource/module.js", - BaseURL: "/public/plugins/test-datasource", + Module: "public/plugins/test-datasource/module.js", + BaseURL: "public/plugins/test-datasource", FS: mustNewStaticFSForTests(t, filepath.Join(testDataDir(t), "valid-v2-signature/plugin/")), Signature: "valid", SignatureType: plugins.SignatureTypeGrafana, @@ -172,8 +171,8 @@ func TestLoader_Load(t *testing.T) { URL: "http://test.com", }, Logos: plugins.Logos{ - Small: "/public/plugins/test-app/img/logo_small.png", - Large: "/public/plugins/test-app/img/logo_large.png", + Small: "public/plugins/test-app/img/logo_small.png", + Large: "public/plugins/test-app/img/logo_large.png", }, Links: []plugins.InfoLink{ {Name: "Project site", URL: "http://project.com"}, @@ -181,8 +180,8 @@ func TestLoader_Load(t *testing.T) { }, Description: "Official Grafana Test App & Dashboard bundle", Screenshots: []plugins.Screenshots{ - {Path: "/public/plugins/test-app/img/screenshot1.png", Name: "img1"}, - {Path: "/public/plugins/test-app/img/screenshot2.png", Name: "img2"}, + {Path: "public/plugins/test-app/img/screenshot1.png", Name: "img1"}, + {Path: "public/plugins/test-app/img/screenshot2.png", Name: "img2"}, }, Version: "1.0.0", Updated: "2015-02-10", @@ -223,8 +222,8 @@ func TestLoader_Load(t *testing.T) { }, }, Class: plugins.ClassExternal, - Module: "/public/plugins/test-app/module.js", - BaseURL: "/public/plugins/test-app", + Module: "public/plugins/test-app/module.js", + BaseURL: "public/plugins/test-app", FS: mustNewStaticFSForTests(t, filepath.Join(testDataDir(t), "includes-symlinks")), Signature: "valid", SignatureType: plugins.SignatureTypeGrafana, @@ -251,8 +250,8 @@ func TestLoader_Load(t *testing.T) { URL: "https://grafana.com", }, Logos: plugins.Logos{ - Small: "/public/img/icn-datasource.svg", - Large: "/public/img/icn-datasource.svg", + Small: "public/img/icn-datasource.svg", + Large: "public/img/icn-datasource.svg", }, Description: "Test", }, @@ -264,8 +263,8 @@ func TestLoader_Load(t *testing.T) { State: plugins.ReleaseStateAlpha, }, Class: plugins.ClassExternal, - Module: "/public/plugins/test-datasource/module.js", - BaseURL: "/public/plugins/test-datasource", + Module: "public/plugins/test-datasource/module.js", + BaseURL: "public/plugins/test-datasource", FS: mustNewStaticFSForTests(t, filepath.Join(testDataDir(t), "unsigned-datasource/plugin")), Signature: "unsigned", }, @@ -303,8 +302,8 @@ func TestLoader_Load(t *testing.T) { URL: "https://grafana.com", }, Logos: plugins.Logos{ - Small: "/public/img/icn-datasource.svg", - Large: "/public/img/icn-datasource.svg", + Small: "public/img/icn-datasource.svg", + Large: "public/img/icn-datasource.svg", }, Description: "Test", }, @@ -316,8 +315,8 @@ func TestLoader_Load(t *testing.T) { State: plugins.ReleaseStateAlpha, }, Class: plugins.ClassExternal, - Module: "/public/plugins/test-datasource/module.js", - BaseURL: "/public/plugins/test-datasource", + Module: "public/plugins/test-datasource/module.js", + BaseURL: "public/plugins/test-datasource", FS: mustNewStaticFSForTests(t, filepath.Join(testDataDir(t), "unsigned-datasource/plugin")), Signature: plugins.SignatureStatusUnsigned, }, @@ -409,8 +408,8 @@ func TestLoader_Load(t *testing.T) { {Name: "License & Terms", URL: "http://license.com"}, }, Logos: plugins.Logos{ - Small: "/public/img/icn-app.svg", - Large: "/public/img/icn-app.svg", + Small: "public/img/icn-app.svg", + Large: "public/img/icn-app.svg", }, Updated: "2015-02-10", }, @@ -429,8 +428,8 @@ func TestLoader_Load(t *testing.T) { FS: mustNewStaticFSForTests(t, filepath.Join(testDataDir(t), "test-app-with-includes")), Class: plugins.ClassExternal, Signature: plugins.SignatureStatusUnsigned, - Module: "/public/plugins/test-app/module.js", - BaseURL: "/public/plugins/test-app", + Module: "public/plugins/test-app/module.js", + BaseURL: "public/plugins/test-app", }, }, }, @@ -455,8 +454,8 @@ func TestLoader_Load(t *testing.T) { URL: "https://grafana.com", }, Logos: plugins.Logos{ - Small: "/grafana/public/img/icn-datasource.svg", - Large: "/grafana/public/img/icn-datasource.svg", + Small: "public/img/icn-datasource.svg", + Large: "public/img/icn-datasource.svg", }, Description: "Test", }, @@ -468,8 +467,8 @@ func TestLoader_Load(t *testing.T) { State: plugins.ReleaseStateAlpha, }, Class: plugins.ClassExternal, - Module: "/grafana/public/plugins/test-datasource/module.js", - BaseURL: "/grafana/public/plugins/test-datasource", + Module: "public/plugins/test-datasource/module.js", + BaseURL: "public/plugins/test-datasource", FS: mustNewStaticFSForTests(t, filepath.Join(testDataDir(t), "unsigned-datasource/plugin")), Signature: plugins.SignatureStatusUnsigned, }, @@ -526,8 +525,8 @@ func TestLoader_Load_ExternalRegistration(t *testing.T) { }, Version: "1.0.0", Logos: plugins.Logos{ - Small: "/public/plugins/grafana-test-datasource/img/ds.svg", - Large: "/public/plugins/grafana-test-datasource/img/ds.svg", + Small: "public/plugins/grafana-test-datasource/img/ds.svg", + Large: "public/plugins/grafana-test-datasource/img/ds.svg", }, Updated: "2023-08-03", Screenshots: []plugins.Screenshots{}, @@ -557,8 +556,8 @@ func TestLoader_Load_ExternalRegistration(t *testing.T) { FS: mustNewStaticFSForTests(t, pluginPaths[0]), Class: plugins.ClassExternal, Signature: plugins.SignatureStatusUnsigned, - Module: "/public/plugins/grafana-test-datasource/module.js", - BaseURL: "/public/plugins/grafana-test-datasource", + Module: "public/plugins/grafana-test-datasource/module.js", + BaseURL: "public/plugins/grafana-test-datasource", ExternalService: &auth.ExternalService{ ClientID: "client-id", ClientSecret: "secretz", @@ -628,8 +627,8 @@ func TestLoader_Load_ExternalRegistration(t *testing.T) { }, Version: "1.0.0", Logos: plugins.Logos{ - Small: "/public/plugins/grafana-test-datasource/img/ds.svg", - Large: "/public/plugins/grafana-test-datasource/img/ds.svg", + Small: "public/plugins/grafana-test-datasource/img/ds.svg", + Large: "public/plugins/grafana-test-datasource/img/ds.svg", }, Updated: "2023-08-03", Screenshots: []plugins.Screenshots{}, @@ -650,8 +649,8 @@ func TestLoader_Load_ExternalRegistration(t *testing.T) { FS: mustNewStaticFSForTests(t, pluginPaths[0]), Class: plugins.ClassExternal, Signature: plugins.SignatureStatusUnsigned, - Module: "/public/plugins/grafana-test-datasource/module.js", - BaseURL: "/public/plugins/grafana-test-datasource", + Module: "public/plugins/grafana-test-datasource/module.js", + BaseURL: "public/plugins/grafana-test-datasource", ExternalService: &auth.ExternalService{ ClientID: "client-id", ClientSecret: "secretz", @@ -808,8 +807,8 @@ func TestLoader_Load_MultiplePlugins(t *testing.T) { URL: "https://willbrowne.com", }, Logos: plugins.Logos{ - Small: "/public/img/icn-datasource.svg", - Large: "/public/img/icn-datasource.svg", + Small: "public/img/icn-datasource.svg", + Large: "public/img/icn-datasource.svg", }, Description: "Test", Version: "1.0.0", @@ -823,8 +822,8 @@ func TestLoader_Load_MultiplePlugins(t *testing.T) { State: plugins.ReleaseStateAlpha, }, Class: plugins.ClassExternal, - Module: "/public/plugins/test-datasource/module.js", - BaseURL: "/public/plugins/test-datasource", + Module: "public/plugins/test-datasource/module.js", + BaseURL: "public/plugins/test-datasource", FS: mustNewStaticFSForTests(t, filepath.Join(testDataDir(t), "valid-v2-pvt-signature/plugin")), Signature: "valid", SignatureType: plugins.SignatureTypePrivate, @@ -904,8 +903,8 @@ func TestLoader_Load_RBACReady(t *testing.T) { Version: "1.0.0", Links: []plugins.InfoLink{}, Logos: plugins.Logos{ - Small: "/public/img/icn-app.svg", - Large: "/public/img/icn-app.svg", + Small: "public/img/icn-app.svg", + Large: "public/img/icn-app.svg", }, Updated: "2015-02-10", }, @@ -936,8 +935,8 @@ func TestLoader_Load_RBACReady(t *testing.T) { Signature: plugins.SignatureStatusValid, SignatureType: plugins.SignatureTypePrivate, SignatureOrg: "gabrielmabille", - Module: "/public/plugins/test-app/module.js", - BaseURL: "/public/plugins/test-app", + Module: "public/plugins/test-app/module.js", + BaseURL: "public/plugins/test-app", }, }, }, @@ -981,8 +980,8 @@ func TestLoader_Load_Signature_RootURL(t *testing.T) { Author: plugins.InfoLink{Name: "Will Browne", URL: "https://willbrowne.com"}, Description: "Test", Logos: plugins.Logos{ - Small: "/public/img/icn-datasource.svg", - Large: "/public/img/icn-datasource.svg", + Small: "public/img/icn-datasource.svg", + Large: "public/img/icn-datasource.svg", }, Version: "1.0.0", }, @@ -996,8 +995,8 @@ func TestLoader_Load_Signature_RootURL(t *testing.T) { Signature: plugins.SignatureStatusValid, SignatureType: plugins.SignatureTypePrivate, SignatureOrg: "Will Browne", - Module: "/public/plugins/test-datasource/module.js", - BaseURL: "/public/plugins/test-datasource", + Module: "public/plugins/test-datasource/module.js", + BaseURL: "public/plugins/test-datasource", }, } @@ -1043,12 +1042,12 @@ func TestLoader_Load_DuplicatePlugins(t *testing.T) { {Name: "License & Terms", URL: "http://license.com"}, }, Logos: plugins.Logos{ - Small: "/public/plugins/test-app/img/logo_small.png", - Large: "/public/plugins/test-app/img/logo_large.png", + Small: "public/plugins/test-app/img/logo_small.png", + Large: "public/plugins/test-app/img/logo_large.png", }, Screenshots: []plugins.Screenshots{ - {Path: "/public/plugins/test-app/img/screenshot1.png", Name: "img1"}, - {Path: "/public/plugins/test-app/img/screenshot2.png", Name: "img2"}, + {Path: "public/plugins/test-app/img/screenshot1.png", Name: "img1"}, + {Path: "public/plugins/test-app/img/screenshot2.png", Name: "img2"}, }, Updated: "2015-02-10", }, @@ -1072,8 +1071,8 @@ func TestLoader_Load_DuplicatePlugins(t *testing.T) { Signature: plugins.SignatureStatusValid, SignatureType: plugins.SignatureTypeGrafana, SignatureOrg: "Grafana Labs", - Module: "/public/plugins/test-app/module.js", - BaseURL: "/public/plugins/test-app", + Module: "public/plugins/test-app/module.js", + BaseURL: "public/plugins/test-app", }, } @@ -1123,12 +1122,12 @@ func TestLoader_Load_SkipUninitializedPlugins(t *testing.T) { {Name: "License & Terms", URL: "http://license.com"}, }, Logos: plugins.Logos{ - Small: "/public/plugins/test-app/img/logo_small.png", - Large: "/public/plugins/test-app/img/logo_large.png", + Small: "public/plugins/test-app/img/logo_small.png", + Large: "public/plugins/test-app/img/logo_large.png", }, Screenshots: []plugins.Screenshots{ - {Path: "/public/plugins/test-app/img/screenshot1.png", Name: "img1"}, - {Path: "/public/plugins/test-app/img/screenshot2.png", Name: "img2"}, + {Path: "public/plugins/test-app/img/screenshot1.png", Name: "img1"}, + {Path: "public/plugins/test-app/img/screenshot2.png", Name: "img2"}, }, Updated: "2015-02-10", }, @@ -1152,8 +1151,8 @@ func TestLoader_Load_SkipUninitializedPlugins(t *testing.T) { Signature: plugins.SignatureStatusValid, SignatureType: plugins.SignatureTypeGrafana, SignatureOrg: "Grafana Labs", - Module: "/public/plugins/test-app/module.js", - BaseURL: "/public/plugins/test-app", + Module: "public/plugins/test-app/module.js", + BaseURL: "public/plugins/test-app", }, } @@ -1345,8 +1344,8 @@ func TestLoader_Load_NestedPlugins(t *testing.T) { URL: "http://grafana.com", }, Logos: plugins.Logos{ - Small: "/public/img/icn-datasource.svg", - Large: "/public/img/icn-datasource.svg", + Small: "public/img/icn-datasource.svg", + Large: "public/img/icn-datasource.svg", }, Description: "Parent plugin", Version: "1.0.0", @@ -1358,8 +1357,8 @@ func TestLoader_Load_NestedPlugins(t *testing.T) { }, Backend: true, }, - Module: "/public/plugins/test-datasource/module.js", - BaseURL: "/public/plugins/test-datasource", + Module: "public/plugins/test-datasource/module.js", + BaseURL: "public/plugins/test-datasource", FS: mustNewStaticFSForTests(t, filepath.Join(testDataDir(t), "nested-plugins/parent")), Signature: plugins.SignatureStatusValid, SignatureType: plugins.SignatureTypeGrafana, @@ -1378,8 +1377,8 @@ func TestLoader_Load_NestedPlugins(t *testing.T) { URL: "http://grafana.com", }, Logos: plugins.Logos{ - Small: "/public/img/icn-panel.svg", - Large: "/public/img/icn-panel.svg", + Small: "public/img/icn-panel.svg", + Large: "public/img/icn-panel.svg", }, Description: "Child plugin", Version: "1.0.1", @@ -1390,8 +1389,8 @@ func TestLoader_Load_NestedPlugins(t *testing.T) { Plugins: []plugins.Dependency{}, }, }, - Module: "/public/plugins/test-panel/module.js", - BaseURL: "/public/plugins/test-panel", + Module: "public/plugins/test-panel/module.js", + BaseURL: "public/plugins/test-panel", FS: mustNewStaticFSForTests(t, filepath.Join(testDataDir(t), "nested-plugins/parent/nested")), Signature: plugins.SignatureStatusValid, SignatureType: plugins.SignatureTypeGrafana, @@ -1470,8 +1469,8 @@ func TestLoader_Load_NestedPlugins(t *testing.T) { {Name: "License", URL: "https://github.com/grafana/grafana-starter-app/blob/master/LICENSE"}, }, Logos: plugins.Logos{ - Small: "/public/plugins/myorgid-simple-app/img/logo.svg", - Large: "/public/plugins/myorgid-simple-app/img/logo.svg", + Small: "public/plugins/myorgid-simple-app/img/logo.svg", + Large: "public/plugins/myorgid-simple-app/img/logo.svg", }, Screenshots: []plugins.Screenshots{}, Description: "Grafana App Plugin Template", @@ -1526,8 +1525,8 @@ func TestLoader_Load_NestedPlugins(t *testing.T) { }, Backend: false, }, - Module: "/public/plugins/myorgid-simple-app/module.js", - BaseURL: "/public/plugins/myorgid-simple-app", + Module: "public/plugins/myorgid-simple-app/module.js", + BaseURL: "public/plugins/myorgid-simple-app", FS: mustNewStaticFSForTests(t, filepath.Join(testDataDir(t), "app-with-child/dist")), DefaultNavURL: "/plugins/myorgid-simple-app/page/root-page-react", Signature: plugins.SignatureStatusValid, @@ -1550,8 +1549,8 @@ func TestLoader_Load_NestedPlugins(t *testing.T) { {Name: "License", URL: "https://github.com/grafana/grafana-starter-panel/blob/master/LICENSE"}, }, Logos: plugins.Logos{ - Small: "/public/plugins/myorgid-simple-panel/img/logo.svg", - Large: "/public/plugins/myorgid-simple-panel/img/logo.svg", + Small: "public/plugins/myorgid-simple-panel/img/logo.svg", + Large: "public/plugins/myorgid-simple-panel/img/logo.svg", }, Screenshots: []plugins.Screenshots{}, Description: "Grafana Panel Plugin Template", @@ -1564,8 +1563,8 @@ func TestLoader_Load_NestedPlugins(t *testing.T) { Plugins: []plugins.Dependency{}, }, }, - Module: "/public/plugins/myorgid-simple-app/child/module.js", - BaseURL: "/public/plugins/myorgid-simple-app", + Module: "public/plugins/myorgid-simple-app/child/module.js", + BaseURL: "public/plugins/myorgid-simple-app", FS: mustNewStaticFSForTests(t, filepath.Join(testDataDir(t), "app-with-child/dist/child")), IncludedInAppID: parent.ID, Signature: plugins.SignatureStatusValid, diff --git a/pkg/tests/api/plugins/data/expectedListResp.json b/pkg/tests/api/plugins/data/expectedListResp.json index 3abaf4caf8d..95d7dc9e65c 100644 --- a/pkg/tests/api/plugins/data/expectedListResp.json +++ b/pkg/tests/api/plugins/data/expectedListResp.json @@ -13,8 +13,8 @@ "description": "Shows list of alerts and their current status", "links": null, "logos": { - "small": "/public/app/plugins/panel/alertlist/img/icn-singlestat-panel.svg", - "large": "/public/app/plugins/panel/alertlist/img/icn-singlestat-panel.svg" + "small": "public/app/plugins/panel/alertlist/img/icn-singlestat-panel.svg", + "large": "public/app/plugins/panel/alertlist/img/icn-singlestat-panel.svg" }, "build": {}, "screenshots": null, @@ -55,8 +55,8 @@ } ], "logos": { - "small": "/public/app/plugins/datasource/alertmanager/img/logo.svg", - "large": "/public/app/plugins/datasource/alertmanager/img/logo.svg" + "small": "public/app/plugins/datasource/alertmanager/img/logo.svg", + "large": "public/app/plugins/datasource/alertmanager/img/logo.svg" }, "build": {}, "screenshots": null, @@ -92,8 +92,8 @@ "description": "List annotations", "links": null, "logos": { - "small": "/public/app/plugins/panel/annolist/img/icn-annolist-panel.svg", - "large": "/public/app/plugins/panel/annolist/img/icn-annolist-panel.svg" + "small": "public/app/plugins/panel/annolist/img/icn-annolist-panel.svg", + "large": "public/app/plugins/panel/annolist/img/icn-annolist-panel.svg" }, "build": {}, "screenshots": null, @@ -138,22 +138,22 @@ } ], "logos": { - "small": "/public/app/plugins/datasource/azuremonitor/img/logo.jpg", - "large": "/public/app/plugins/datasource/azuremonitor/img/logo.jpg" + "small": "public/app/plugins/datasource/azuremonitor/img/logo.jpg", + "large": "public/app/plugins/datasource/azuremonitor/img/logo.jpg" }, "build": {}, "screenshots": [ { "name": "Azure Contoso Loans", - "path": "/public/app/plugins/datasource/azuremonitor/img/contoso_loans_grafana_dashboard.png" + "path": "public/app/plugins/datasource/azuremonitor/img/contoso_loans_grafana_dashboard.png" }, { "name": "Azure Monitor Network", - "path": "/public/app/plugins/datasource/azuremonitor/img/azure_monitor_network.png" + "path": "public/app/plugins/datasource/azuremonitor/img/azure_monitor_network.png" }, { "name": "Azure Monitor CPU", - "path": "/public/app/plugins/datasource/azuremonitor/img/azure_monitor_cpu.png" + "path": "public/app/plugins/datasource/azuremonitor/img/azure_monitor_cpu.png" } ], "version": "", @@ -188,8 +188,8 @@ "description": "Categorical charts with group support", "links": null, "logos": { - "small": "/public/app/plugins/panel/barchart/img/barchart.svg", - "large": "/public/app/plugins/panel/barchart/img/barchart.svg" + "small": "public/app/plugins/panel/barchart/img/barchart.svg", + "large": "public/app/plugins/panel/barchart/img/barchart.svg" }, "build": {}, "screenshots": null, @@ -225,8 +225,8 @@ "description": "Horizontal and vertical gauges", "links": null, "logos": { - "small": "/public/app/plugins/panel/bargauge/img/icon_bar_gauge.svg", - "large": "/public/app/plugins/panel/bargauge/img/icon_bar_gauge.svg" + "small": "public/app/plugins/panel/bargauge/img/icon_bar_gauge.svg", + "large": "public/app/plugins/panel/bargauge/img/icon_bar_gauge.svg" }, "build": {}, "screenshots": null, @@ -262,8 +262,8 @@ "description": "", "links": null, "logos": { - "small": "/public/app/plugins/panel/candlestick/img/candlestick.svg", - "large": "/public/app/plugins/panel/candlestick/img/candlestick.svg" + "small": "public/app/plugins/panel/candlestick/img/candlestick.svg", + "large": "public/app/plugins/panel/candlestick/img/candlestick.svg" }, "build": {}, "screenshots": null, @@ -299,8 +299,8 @@ "description": "Explicit element placement", "links": null, "logos": { - "small": "/public/app/plugins/panel/canvas/img/icn-canvas.svg", - "large": "/public/app/plugins/panel/canvas/img/icn-canvas.svg" + "small": "public/app/plugins/panel/canvas/img/icn-canvas.svg", + "large": "public/app/plugins/panel/canvas/img/icn-canvas.svg" }, "build": {}, "screenshots": null, @@ -336,8 +336,8 @@ "description": "Data source for Amazon AWS monitoring service", "links": null, "logos": { - "small": "/public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png", - "large": "/public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png" + "small": "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png", + "large": "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png" }, "build": {}, "screenshots": null, @@ -373,8 +373,8 @@ "description": "List of dynamic links to other dashboards", "links": null, "logos": { - "small": "/public/app/plugins/panel/dashlist/img/icn-dashlist-panel.svg", - "large": "/public/app/plugins/panel/dashlist/img/icn-dashlist-panel.svg" + "small": "public/app/plugins/panel/dashlist/img/icn-dashlist-panel.svg", + "large": "public/app/plugins/panel/dashlist/img/icn-dashlist-panel.svg" }, "build": {}, "screenshots": null, @@ -410,8 +410,8 @@ "description": "", "links": null, "logos": { - "small": "/public/app/plugins/panel/datagrid/img/icn-table-panel.svg", - "large": "/public/app/plugins/panel/datagrid/img/icn-table-panel.svg" + "small": "public/app/plugins/panel/datagrid/img/icn-table-panel.svg", + "large": "public/app/plugins/panel/datagrid/img/icn-table-panel.svg" }, "build": {}, "screenshots": null, @@ -452,8 +452,8 @@ } ], "logos": { - "small": "/public/app/plugins/datasource/elasticsearch/img/elasticsearch.svg", - "large": "/public/app/plugins/datasource/elasticsearch/img/elasticsearch.svg" + "small": "public/app/plugins/datasource/elasticsearch/img/elasticsearch.svg", + "large": "public/app/plugins/datasource/elasticsearch/img/elasticsearch.svg" }, "build": {}, "screenshots": null, @@ -489,8 +489,8 @@ "description": "", "links": null, "logos": { - "small": "/public/app/plugins/panel/flamegraph/img/icn-flamegraph.svg", - "large": "/public/app/plugins/panel/flamegraph/img/icn-flamegraph.svg" + "small": "public/app/plugins/panel/flamegraph/img/icn-flamegraph.svg", + "large": "public/app/plugins/panel/flamegraph/img/icn-flamegraph.svg" }, "build": {}, "screenshots": null, @@ -526,8 +526,8 @@ "description": "Standard gauge visualization", "links": null, "logos": { - "small": "/public/app/plugins/panel/gauge/img/icon_gauge.svg", - "large": "/public/app/plugins/panel/gauge/img/icon_gauge.svg" + "small": "public/app/plugins/panel/gauge/img/icon_gauge.svg", + "large": "public/app/plugins/panel/gauge/img/icon_gauge.svg" }, "build": {}, "screenshots": null, @@ -563,8 +563,8 @@ "description": "Geomap panel", "links": null, "logos": { - "small": "/public/app/plugins/panel/geomap/img/icn-geomap.svg", - "large": "/public/app/plugins/panel/geomap/img/icn-geomap.svg" + "small": "public/app/plugins/panel/geomap/img/icn-geomap.svg", + "large": "public/app/plugins/panel/geomap/img/icn-geomap.svg" }, "build": {}, "screenshots": null, @@ -600,8 +600,8 @@ "description": "", "links": null, "logos": { - "small": "/public/app/plugins/panel/gettingstarted/img/icn-dashlist-panel.svg", - "large": "/public/app/plugins/panel/gettingstarted/img/icn-dashlist-panel.svg" + "small": "public/app/plugins/panel/gettingstarted/img/icn-dashlist-panel.svg", + "large": "public/app/plugins/panel/gettingstarted/img/icn-dashlist-panel.svg" }, "build": {}, "screenshots": null, @@ -637,8 +637,8 @@ "description": "Data source for Google's monitoring service (formerly named Stackdriver)", "links": null, "logos": { - "small": "/public/app/plugins/datasource/cloud-monitoring/img/cloud_monitoring_logo.svg", - "large": "/public/app/plugins/datasource/cloud-monitoring/img/cloud_monitoring_logo.svg" + "small": "public/app/plugins/datasource/cloud-monitoring/img/cloud_monitoring_logo.svg", + "large": "public/app/plugins/datasource/cloud-monitoring/img/cloud_monitoring_logo.svg" }, "build": {}, "screenshots": null, @@ -679,8 +679,8 @@ } ], "logos": { - "small": "/public/app/plugins/datasource/grafana-pyroscope-datasource/img/grafana_pyroscope_icon.svg", - "large": "/public/app/plugins/datasource/grafana-pyroscope-datasource/img/grafana_pyroscope_icon.svg" + "small": "public/app/plugins/datasource/grafana-pyroscope-datasource/img/grafana_pyroscope_icon.svg", + "large": "public/app/plugins/datasource/grafana-pyroscope-datasource/img/grafana_pyroscope_icon.svg" }, "build": {}, "screenshots": null, @@ -716,8 +716,8 @@ "description": "The old default graph panel", "links": null, "logos": { - "small": "/public/app/plugins/panel/graph/img/icn-graph-panel.svg", - "large": "/public/app/plugins/panel/graph/img/icn-graph-panel.svg" + "small": "public/app/plugins/panel/graph/img/icn-graph-panel.svg", + "large": "public/app/plugins/panel/graph/img/icn-graph-panel.svg" }, "build": {}, "screenshots": null, @@ -762,8 +762,8 @@ } ], "logos": { - "small": "/public/app/plugins/datasource/graphite/img/graphite_logo.png", - "large": "/public/app/plugins/datasource/graphite/img/graphite_logo.png" + "small": "public/app/plugins/datasource/graphite/img/graphite_logo.png", + "large": "public/app/plugins/datasource/graphite/img/graphite_logo.png" }, "build": {}, "screenshots": null, @@ -799,8 +799,8 @@ "description": "Like a histogram over time", "links": null, "logos": { - "small": "/public/app/plugins/panel/heatmap/img/icn-heatmap-panel.svg", - "large": "/public/app/plugins/panel/heatmap/img/icn-heatmap-panel.svg" + "small": "public/app/plugins/panel/heatmap/img/icn-heatmap-panel.svg", + "large": "public/app/plugins/panel/heatmap/img/icn-heatmap-panel.svg" }, "build": {}, "screenshots": null, @@ -836,8 +836,8 @@ "description": "", "links": null, "logos": { - "small": "/public/app/plugins/panel/histogram/img/histogram.svg", - "large": "/public/app/plugins/panel/histogram/img/histogram.svg" + "small": "public/app/plugins/panel/histogram/img/histogram.svg", + "large": "public/app/plugins/panel/histogram/img/histogram.svg" }, "build": {}, "screenshots": null, @@ -873,8 +873,8 @@ "description": "Open source time series database", "links": null, "logos": { - "small": "/public/app/plugins/datasource/influxdb/img/influxdb_logo.svg", - "large": "/public/app/plugins/datasource/influxdb/img/influxdb_logo.svg" + "small": "public/app/plugins/datasource/influxdb/img/influxdb_logo.svg", + "large": "public/app/plugins/datasource/influxdb/img/influxdb_logo.svg" }, "build": {}, "screenshots": null, @@ -919,8 +919,8 @@ } ], "logos": { - "small": "/public/app/plugins/datasource/jaeger/img/jaeger_logo.svg", - "large": "/public/app/plugins/datasource/jaeger/img/jaeger_logo.svg" + "small": "public/app/plugins/datasource/jaeger/img/jaeger_logo.svg", + "large": "public/app/plugins/datasource/jaeger/img/jaeger_logo.svg" }, "build": {}, "screenshots": null, @@ -956,8 +956,8 @@ "description": "", "links": null, "logos": { - "small": "/public/app/plugins/panel/logs/img/icn-logs-panel.svg", - "large": "/public/app/plugins/panel/logs/img/icn-logs-panel.svg" + "small": "public/app/plugins/panel/logs/img/icn-logs-panel.svg", + "large": "public/app/plugins/panel/logs/img/icn-logs-panel.svg" }, "build": {}, "screenshots": null, @@ -1002,8 +1002,8 @@ } ], "logos": { - "small": "/public/app/plugins/datasource/loki/img/loki_icon.svg", - "large": "/public/app/plugins/datasource/loki/img/loki_icon.svg" + "small": "public/app/plugins/datasource/loki/img/loki_icon.svg", + "large": "public/app/plugins/datasource/loki/img/loki_icon.svg" }, "build": {}, "screenshots": null, @@ -1039,8 +1039,8 @@ "description": "Data source for Microsoft SQL Server compatible databases", "links": null, "logos": { - "small": "/public/app/plugins/datasource/mssql/img/sql_server_logo.svg", - "large": "/public/app/plugins/datasource/mssql/img/sql_server_logo.svg" + "small": "public/app/plugins/datasource/mssql/img/sql_server_logo.svg", + "large": "public/app/plugins/datasource/mssql/img/sql_server_logo.svg" }, "build": {}, "screenshots": null, @@ -1076,8 +1076,8 @@ "description": "Data source for MySQL databases", "links": null, "logos": { - "small": "/public/app/plugins/datasource/mysql/img/mysql_logo.svg", - "large": "/public/app/plugins/datasource/mysql/img/mysql_logo.svg" + "small": "public/app/plugins/datasource/mysql/img/mysql_logo.svg", + "large": "public/app/plugins/datasource/mysql/img/mysql_logo.svg" }, "build": {}, "screenshots": null, @@ -1113,8 +1113,8 @@ "description": "RSS feed reader", "links": null, "logos": { - "small": "/public/app/plugins/panel/news/img/news.svg", - "large": "/public/app/plugins/panel/news/img/news.svg" + "small": "public/app/plugins/panel/news/img/news.svg", + "large": "public/app/plugins/panel/news/img/news.svg" }, "build": {}, "screenshots": null, @@ -1150,8 +1150,8 @@ "description": "", "links": null, "logos": { - "small": "/public/app/plugins/panel/nodeGraph/img/icn-node-graph.svg", - "large": "/public/app/plugins/panel/nodeGraph/img/icn-node-graph.svg" + "small": "public/app/plugins/panel/nodeGraph/img/icn-node-graph.svg", + "large": "public/app/plugins/panel/nodeGraph/img/icn-node-graph.svg" }, "build": {}, "screenshots": null, @@ -1187,8 +1187,8 @@ "description": "Open source time series database", "links": null, "logos": { - "small": "/public/app/plugins/datasource/opentsdb/img/opentsdb_logo.png", - "large": "/public/app/plugins/datasource/opentsdb/img/opentsdb_logo.png" + "small": "public/app/plugins/datasource/opentsdb/img/opentsdb_logo.png", + "large": "public/app/plugins/datasource/opentsdb/img/opentsdb_logo.png" }, "build": {}, "screenshots": null, @@ -1229,8 +1229,8 @@ } ], "logos": { - "small": "/public/app/plugins/datasource/parca/img/logo-small.svg", - "large": "/public/app/plugins/datasource/parca/img/logo-small.svg" + "small": "public/app/plugins/datasource/parca/img/logo-small.svg", + "large": "public/app/plugins/datasource/parca/img/logo-small.svg" }, "build": {}, "screenshots": null, @@ -1266,8 +1266,8 @@ "description": "The new core pie chart visualization", "links": null, "logos": { - "small": "/public/app/plugins/panel/piechart/img/icon_piechart.svg", - "large": "/public/app/plugins/panel/piechart/img/icon_piechart.svg" + "small": "public/app/plugins/panel/piechart/img/icon_piechart.svg", + "large": "public/app/plugins/panel/piechart/img/icon_piechart.svg" }, "build": {}, "screenshots": null, @@ -1303,8 +1303,8 @@ "description": "Data source for PostgreSQL and compatible databases", "links": null, "logos": { - "small": "/public/app/plugins/datasource/grafana-postgresql-datasource/img/postgresql_logo.svg", - "large": "/public/app/plugins/datasource/grafana-postgresql-datasource/img/postgresql_logo.svg" + "small": "public/app/plugins/datasource/grafana-postgresql-datasource/img/postgresql_logo.svg", + "large": "public/app/plugins/datasource/grafana-postgresql-datasource/img/postgresql_logo.svg" }, "build": {}, "screenshots": null, @@ -1345,8 +1345,8 @@ } ], "logos": { - "small": "/public/app/plugins/datasource/prometheus/img/prometheus_logo.svg", - "large": "/public/app/plugins/datasource/prometheus/img/prometheus_logo.svg" + "small": "public/app/plugins/datasource/prometheus/img/prometheus_logo.svg", + "large": "public/app/plugins/datasource/prometheus/img/prometheus_logo.svg" }, "build": {}, "screenshots": null, @@ -1382,8 +1382,8 @@ "description": "Big stat values \u0026 sparklines", "links": null, "logos": { - "small": "/public/app/plugins/panel/stat/img/icn-singlestat-panel.svg", - "large": "/public/app/plugins/panel/stat/img/icn-singlestat-panel.svg" + "small": "public/app/plugins/panel/stat/img/icn-singlestat-panel.svg", + "large": "public/app/plugins/panel/stat/img/icn-singlestat-panel.svg" }, "build": {}, "screenshots": null, @@ -1419,8 +1419,8 @@ "description": "State changes and durations", "links": null, "logos": { - "small": "/public/app/plugins/panel/state-timeline/img/timeline.svg", - "large": "/public/app/plugins/panel/state-timeline/img/timeline.svg" + "small": "public/app/plugins/panel/state-timeline/img/timeline.svg", + "large": "public/app/plugins/panel/state-timeline/img/timeline.svg" }, "build": {}, "screenshots": null, @@ -1456,8 +1456,8 @@ "description": "Periodic status history", "links": null, "logos": { - "small": "/public/app/plugins/panel/status-history/img/status.svg", - "large": "/public/app/plugins/panel/status-history/img/status.svg" + "small": "public/app/plugins/panel/status-history/img/status.svg", + "large": "public/app/plugins/panel/status-history/img/status.svg" }, "build": {}, "screenshots": null, @@ -1493,8 +1493,8 @@ "description": "Supports many column styles", "links": null, "logos": { - "small": "/public/app/plugins/panel/table/img/icn-table-panel.svg", - "large": "/public/app/plugins/panel/table/img/icn-table-panel.svg" + "small": "public/app/plugins/panel/table/img/icn-table-panel.svg", + "large": "public/app/plugins/panel/table/img/icn-table-panel.svg" }, "build": {}, "screenshots": null, @@ -1530,8 +1530,8 @@ "description": "Table Panel for Grafana", "links": null, "logos": { - "small": "/public/app/plugins/panel/table-old/img/icn-table-panel.svg", - "large": "/public/app/plugins/panel/table-old/img/icn-table-panel.svg" + "small": "public/app/plugins/panel/table-old/img/icn-table-panel.svg", + "large": "public/app/plugins/panel/table-old/img/icn-table-panel.svg" }, "build": {}, "screenshots": null, @@ -1572,8 +1572,8 @@ } ], "logos": { - "small": "/public/app/plugins/datasource/tempo/img/tempo_logo.svg", - "large": "/public/app/plugins/datasource/tempo/img/tempo_logo.svg" + "small": "public/app/plugins/datasource/tempo/img/tempo_logo.svg", + "large": "public/app/plugins/datasource/tempo/img/tempo_logo.svg" }, "build": {}, "screenshots": null, @@ -1609,8 +1609,8 @@ "description": "Generates test data in different forms", "links": null, "logos": { - "small": "/public/app/plugins/datasource/grafana-testdata-datasource/img/testdata.svg", - "large": "/public/app/plugins/datasource/grafana-testdata-datasource/img/testdata.svg" + "small": "public/app/plugins/datasource/grafana-testdata-datasource/img/testdata.svg", + "large": "public/app/plugins/datasource/grafana-testdata-datasource/img/testdata.svg" }, "build": {}, "screenshots": null, @@ -1646,8 +1646,8 @@ "description": "Supports markdown and html content", "links": null, "logos": { - "small": "/public/app/plugins/panel/text/img/icn-text-panel.svg", - "large": "/public/app/plugins/panel/text/img/icn-text-panel.svg" + "small": "public/app/plugins/panel/text/img/icn-text-panel.svg", + "large": "public/app/plugins/panel/text/img/icn-text-panel.svg" }, "build": {}, "screenshots": null, @@ -1683,8 +1683,8 @@ "description": "Time based line, area and bar charts", "links": null, "logos": { - "small": "/public/app/plugins/panel/timeseries/img/icn-timeseries-panel.svg", - "large": "/public/app/plugins/panel/timeseries/img/icn-timeseries-panel.svg" + "small": "public/app/plugins/panel/timeseries/img/icn-timeseries-panel.svg", + "large": "public/app/plugins/panel/timeseries/img/icn-timeseries-panel.svg" }, "build": {}, "screenshots": null, @@ -1720,8 +1720,8 @@ "description": "", "links": null, "logos": { - "small": "/public/app/plugins/panel/traces/img/traces-panel.svg", - "large": "/public/app/plugins/panel/traces/img/traces-panel.svg" + "small": "public/app/plugins/panel/traces/img/traces-panel.svg", + "large": "public/app/plugins/panel/traces/img/traces-panel.svg" }, "build": {}, "screenshots": null, @@ -1757,8 +1757,8 @@ "description": "Like timeseries, but when x != time", "links": null, "logos": { - "small": "/public/app/plugins/panel/trend/img/trend.svg", - "large": "/public/app/plugins/panel/trend/img/trend.svg" + "small": "public/app/plugins/panel/trend/img/trend.svg", + "large": "public/app/plugins/panel/trend/img/trend.svg" }, "build": {}, "screenshots": null, @@ -1794,8 +1794,8 @@ "description": "", "links": null, "logos": { - "small": "/public/app/plugins/panel/welcome/img/icn-dashlist-panel.svg", - "large": "/public/app/plugins/panel/welcome/img/icn-dashlist-panel.svg" + "small": "public/app/plugins/panel/welcome/img/icn-dashlist-panel.svg", + "large": "public/app/plugins/panel/welcome/img/icn-dashlist-panel.svg" }, "build": {}, "screenshots": null, @@ -1831,8 +1831,8 @@ "description": "", "links": null, "logos": { - "small": "/public/app/plugins/panel/xychart/img/icn-xychart.svg", - "large": "/public/app/plugins/panel/xychart/img/icn-xychart.svg" + "small": "public/app/plugins/panel/xychart/img/icn-xychart.svg", + "large": "public/app/plugins/panel/xychart/img/icn-xychart.svg" }, "build": {}, "screenshots": null, @@ -1873,8 +1873,8 @@ } ], "logos": { - "small": "/public/app/plugins/datasource/zipkin/img/zipkin-logo.svg", - "large": "/public/app/plugins/datasource/zipkin/img/zipkin-logo.svg" + "small": "public/app/plugins/datasource/zipkin/img/zipkin-logo.svg", + "large": "public/app/plugins/datasource/zipkin/img/zipkin-logo.svg" }, "build": {}, "screenshots": null, @@ -1896,4 +1896,4 @@ "signatureOrg": "", "angularDetected": false } -] +] \ No newline at end of file diff --git a/public/app/features/plugins/loader/utils.test.ts b/public/app/features/plugins/loader/utils.test.ts new file mode 100644 index 00000000000..719e67d6d58 --- /dev/null +++ b/public/app/features/plugins/loader/utils.test.ts @@ -0,0 +1,31 @@ +import { config } from '@grafana/runtime'; + +import { resolveModulePath } from './utils'; + +describe('resolveModulePath', () => { + it.each` + value | expected + ${'http://localhost:3000/public/plugins/my-app-plugin/module.js'} | ${'http://localhost:3000/public/plugins/my-app-plugin/module.js'} + ${'/public/plugins/my-app-plugin/module.js'} | ${'/public/plugins/my-app-plugin/module.js'} + ${'public/plugins/my-app-plugin/module.js'} | ${'/public/plugins/my-app-plugin/module.js'} + `( + "Url correct formatting, when calling the rule with correct formatted value: '$value' then result should be '$expected'", + ({ value, expected }) => { + expect(resolveModulePath(value)).toBe(expected); + } + ); + + it.each` + value | expected + ${'http://localhost:3000/public/plugins/my-app-plugin/module.js'} | ${'http://localhost:3000/public/plugins/my-app-plugin/module.js'} + ${'/public/plugins/my-app-plugin/module.js'} | ${'/public/plugins/my-app-plugin/module.js'} + ${'public/plugins/my-app-plugin/module.js'} | ${'/grafana/public/plugins/my-app-plugin/module.js'} + `( + "Url correct formatting, when calling the rule with correct formatted value: '$value' then result should be '$expected'", + ({ value, expected }) => { + config.appSubUrl = '/grafana'; + + expect(resolveModulePath(value)).toBe(expected); + } + ); +}); diff --git a/public/app/features/plugins/loader/utils.ts b/public/app/features/plugins/loader/utils.ts index 470bc487331..bfc44bd44d8 100644 --- a/public/app/features/plugins/loader/utils.ts +++ b/public/app/features/plugins/loader/utils.ts @@ -28,3 +28,15 @@ export function buildImportMap(importMap: Record) { export function isHostedOnCDN(path: string) { return Boolean(config.pluginsCDNBaseURL) && path.startsWith(config.pluginsCDNBaseURL); } + +// This function is used to dynamically prepend the appSubUrl in the frontend. +// This is required because if serve_from_sub_path is false the Image Renderer sets the subpath +// to an empty string and sets appurl to localhost which causes plugins to fail to load. +// https://github.com/grafana/grafana/issues/76180 +export function resolveModulePath(path: string) { + if (path.startsWith('http') || path.startsWith('/')) { + return path; + } + + return `${config.appSubUrl ?? ''}/${path}`; +} diff --git a/public/app/features/plugins/plugin_loader.ts b/public/app/features/plugins/plugin_loader.ts index b4599eca1bc..c594b4f0a13 100644 --- a/public/app/features/plugins/plugin_loader.ts +++ b/public/app/features/plugins/plugin_loader.ts @@ -16,7 +16,7 @@ import { registerPluginInCache } from './loader/cache'; import { sharedDependenciesMap } from './loader/sharedDependencies'; import { decorateSystemJSFetch, decorateSystemJSResolve, decorateSystemJsOnload } from './loader/systemjsHooks'; import { SystemJSWithLoaderHooks } from './loader/types'; -import { buildImportMap } from './loader/utils'; +import { buildImportMap, resolveModulePath } from './loader/utils'; import { importPluginModuleInSandbox } from './sandbox/sandbox_plugin_loader'; import { isFrontendSandboxSupported } from './sandbox/utils'; @@ -67,12 +67,14 @@ export async function importPluginModule({ } } + let modulePath = resolveModulePath(path); + // the sandboxing environment code cannot work in nodejs and requires a real browser if (await isFrontendSandboxSupported({ isAngular, pluginId })) { return importPluginModuleInSandbox({ pluginId }); } - return SystemJS.import(path); + return SystemJS.import(modulePath); } export function importDataSourcePlugin(meta: DataSourcePluginMeta): Promise { diff --git a/public/app/features/plugins/sandbox/code_loader.ts b/public/app/features/plugins/sandbox/code_loader.ts index 7f22aafbeb2..3f2d614bf41 100644 --- a/public/app/features/plugins/sandbox/code_loader.ts +++ b/public/app/features/plugins/sandbox/code_loader.ts @@ -2,7 +2,7 @@ import { PluginMeta, patchArrayVectorProrotypeMethods } from '@grafana/data'; import { transformPluginSourceForCDN } from '../cdn/utils'; import { resolveWithCache } from '../loader/cache'; -import { isHostedOnCDN } from '../loader/utils'; +import { isHostedOnCDN, resolveModulePath } from '../loader/utils'; import { SandboxEnvironment } from './types'; @@ -60,9 +60,10 @@ export async function getPluginCode(meta: PluginMeta): Promise { }); return pluginCode; } else { - // local plugin. resolveWithCache will append a query parameter with its version - // to ensure correct cached version is served - const pluginCodeUrl = resolveWithCache(meta.module); + let modulePath = resolveModulePath(meta.module); + // resolveWithCache will append a query parameter with its version + // to ensure correct cached version is served for local plugins + const pluginCodeUrl = resolveWithCache(modulePath); const response = await fetch(pluginCodeUrl); let pluginCode = await response.text(); pluginCode = transformPluginSourceForCDN({