feat: map GF_INSTALL_PLUGINS to use preinstall plugins feature (#105145)

* feat: map GF_INSTALL_PLUGINS to use preinstall plugins feature

* ref: process GF_INSTALL_PLUGINS as sync install

* fix: check GF_INSTALL_PLUGINS_FORCE in the docker run

* ref: use preinstall_sync for GF_INSTALL_PLUGINS

* ref: logs and deprecation msg for GF_INSTALL_PLUGINS

* chore: deprecated log formatting
This commit is contained in:
Syerikjan Kh
2025-05-22 08:23:33 -04:00
committed by GitHub
parent 267e3ffb7c
commit e05ccb822a
5 changed files with 225 additions and 21 deletions
+56 -4
View File
@@ -1,6 +1,8 @@
package setting
import (
"os"
"regexp"
"strings"
"gopkg.in/ini.v1"
@@ -34,13 +36,62 @@ func extractPluginSettings(sections []*ini.Section) PluginSettings {
var (
defaultPreinstallPlugins = map[string]InstallPlugin{
// Default preinstalled plugins
"grafana-lokiexplore-app": {"grafana-lokiexplore-app", "", ""},
"grafana-pyroscope-app": {"grafana-pyroscope-app", "", ""},
"grafana-exploretraces-app": {"grafana-exploretraces-app", "", ""},
"grafana-metricsdrilldown-app": {"grafana-metricsdrilldown-app", "", ""},
"grafana-lokiexplore-app": {ID: "grafana-lokiexplore-app"},
"grafana-pyroscope-app": {ID: "grafana-pyroscope-app"},
"grafana-exploretraces-app": {ID: "grafana-exploretraces-app"},
"grafana-metricsdrilldown-app": {ID: "grafana-metricsdrilldown-app"},
}
)
func (cfg *Cfg) migrateInstallPluginsToPreinstallPluginsSync(rawInstallPlugins, installPluginsForce string, preinstallPluginsSync map[string]InstallPlugin) {
if strings.ToLower(installPluginsForce) == "true" || rawInstallPlugins == "" {
cfg.Logger.Debug("GF_INSTALL_PLUGINS_FORCE is set to true, skipping migration of GF_INSTALL_PLUGINS to GF_PLUGINS_PREINSTALL_SYNC")
return
}
installPluginsEntries := strings.Split(rawInstallPlugins, ",")
// Format 1: ID only (e.g., "grafana-clock-panel")
// Format 2: ID with version (e.g., "grafana-clock-panel 1.0.1")
// Format 3: URL with folder (e.g., "https://grafana.com/api/plugins/grafana-clock-panel/versions/latest/download;grafana-clock-panel")
pluginRegex := regexp.MustCompile(`(?:([^;]+);)?([^;\s]+)(?:\s+(.+))?`)
for _, entry := range installPluginsEntries {
trimmedEntry := strings.TrimSpace(entry)
if trimmedEntry == "" {
continue
}
matches := pluginRegex.FindStringSubmatch(trimmedEntry)
if matches == nil {
cfg.Logger.Debug("No match found for entry: ", trimmedEntry)
continue
}
url := ""
if len(matches) > 1 {
url = strings.TrimSpace(matches[1])
}
id := ""
if len(matches) > 2 {
id = strings.TrimSpace(matches[2])
}
if _, exists := preinstallPluginsSync[id]; exists {
continue
}
version := ""
if len(matches) > 3 {
version = strings.TrimSpace(matches[3])
}
if id != "" {
preinstallPluginsSync[id] = InstallPlugin{ID: id, Version: version, URL: url}
} else {
cfg.Logger.Debug("No ID found for entry: ", trimmedEntry, "matches: ", matches)
}
}
}
func (cfg *Cfg) processPreinstallPlugins(rawInstallPlugins []string, preinstallPlugins map[string]InstallPlugin) {
// Add the plugins defined in the configuration
for _, plugin := range rawInstallPlugins {
@@ -88,6 +139,7 @@ func (cfg *Cfg) readPluginSettings(iniFile *ini.File) error {
rawInstallPluginsSync := util.SplitString(pluginsSection.Key("preinstall_sync").MustString(""))
preinstallPluginsSync := make(map[string]InstallPlugin)
cfg.processPreinstallPlugins(rawInstallPluginsSync, preinstallPluginsSync)
cfg.migrateInstallPluginsToPreinstallPluginsSync(os.Getenv("GF_INSTALL_PLUGINS"), os.Getenv("GF_INSTALL_PLUGINS_FORCE"), preinstallPluginsSync)
// Remove from the list the plugins that have been disabled
for _, disabledPlugin := range cfg.DisablePlugins {
delete(preinstallPluginsAsync, disabledPlugin)