diff --git a/pkg/services/pluginsintegration/plugininstaller/service.go b/pkg/services/pluginsintegration/plugininstaller/service.go index b83563893a4..543d354c425 100644 --- a/pkg/services/pluginsintegration/plugininstaller/service.go +++ b/pkg/services/pluginsintegration/plugininstaller/service.go @@ -101,7 +101,12 @@ func (s *Service) installPluginsWithTimeout(pluginsToInstall []setting.InstallPl } } -func (s *Service) shouldUpdate(ctx context.Context, pluginID, currentVersion string) bool { +func (s *Service) shouldUpdate(ctx context.Context, pluginID, currentVersion string, pluginURL string) bool { + // If the plugin is installed from a URL, we cannot check for updates as we do not have the version information + // from the repository. Therefore, we assume that the plugin should be updated if the URL is provided. + if pluginURL != "" { + return true + } info, err := s.pluginRepo.GetPluginArchiveInfo(ctx, pluginID, "", repo.NewCompatOpts(s.cfg.BuildVersion, runtime.GOOS, runtime.GOARCH)) if err != nil { s.log.Error("Failed to get plugin info", "pluginId", pluginID, "error", err) @@ -128,7 +133,7 @@ func (s *Service) installPlugins(ctx context.Context, pluginsToInstall []setting } // The plugin is installed but it's not pinned to a specific version // Check if there is a newer version available - if !s.shouldUpdate(ctx, installPlugin.ID, p.Info.Version) { + if !s.shouldUpdate(ctx, installPlugin.ID, p.Info.Version, installPlugin.URL) { continue } } diff --git a/pkg/services/pluginsintegration/plugininstaller/service_test.go b/pkg/services/pluginsintegration/plugininstaller/service_test.go index 25afcf94ba8..1d6c3059eac 100644 --- a/pkg/services/pluginsintegration/plugininstaller/service_test.go +++ b/pkg/services/pluginsintegration/plugininstaller/service_test.go @@ -144,6 +144,12 @@ func TestService_Run(t *testing.T) { pluginsToInstallSync: []setting.InstallPlugin{{ID: "myplugin"}}, pluginsToInstall: []setting.InstallPlugin{{ID: "myplugin2"}}, }, + { + name: "should install a plugin with a URL regardless of versioning", + shouldInstall: true, + pluginsToInstallSync: []setting.InstallPlugin{{ID: "our-plugin-datasource", URL: "https://s3.our.domain/grafana-plugins/our-plugin-datasource-1.2.1+linux.zip"}}, + existingPlugins: []*plugins.Plugin{{JSONData: plugins.JSONData{ID: "our-plugin-datasource", Info: plugins.Info{Version: "1.2.2"}}}}, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/setting/setting_plugins_test.go b/pkg/setting/setting_plugins_test.go index 4a5437548ed..af1d3f43561 100644 --- a/pkg/setting/setting_plugins_test.go +++ b/pkg/setting/setting_plugins_test.go @@ -394,6 +394,17 @@ func Test_migrateInstallPluginsToPreinstallPluginsSync(t *testing.T) { }, }, }, + {name: "parse private plugin", + installPluginsVal: "https://s3.our.domain/grafana-plugins/our-plugin-datasource-1.2.0+linux.zip;our-plugin-datasource 1.2.0", + preinstallPlugins: map[string]InstallPlugin{}, + expectedPlugins: map[string]InstallPlugin{ + "our-plugin-datasource": { + ID: "our-plugin-datasource", + Version: "1.2.0", + URL: "https://s3.our.domain/grafana-plugins/our-plugin-datasource-1.2.0+linux.zip", + }, + }, + }, } for _, tc := range tests {