The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/pkg/plugins/repo/version.go

105 lines
2.8 KiB

package repo
import (
"strings"
"github.com/grafana/grafana/pkg/plugins/log"
)
type VersionData struct {
Version string
Checksum string
Arch map[string]ArchMeta
URL string
}
// SelectSystemCompatibleVersion selects the most appropriate plugin version based on os + architecture
// returns the specified version if supported.
// returns the latest version if no specific version is specified.
// returns error if the supplied version does not exist.
// returns error if supplied version exists but is not supported.
// NOTE: It expects plugin.Versions to be sorted so the newest version is first.
func SelectSystemCompatibleVersion(log log.PrettyLogger, versions []Version, pluginID, version string, compatOpts SystemCompatOpts) (VersionData, error) {
version = normalizeVersion(version)
var ver Version
latestForArch, exists := latestSupportedVersion(versions, compatOpts)
if !exists {
return VersionData{}, ErrArcNotFound(pluginID, compatOpts.OSAndArch())
}
if version == "" {
return VersionData{
Version: latestForArch.Version,
Checksum: checksum(latestForArch, compatOpts),
Arch: latestForArch.Arch,
URL: latestForArch.URL,
}, nil
}
for _, v := range versions {
if v.Version == version {
ver = v
break
}
}
if len(ver.Version) == 0 {
log.Debugf("Requested plugin version %s v%s not found but potential fallback version '%s' was found",
pluginID, version, latestForArch.Version)
return VersionData{}, ErrVersionNotFound(pluginID, version, compatOpts.OSAndArch())
}
if !supportsCurrentArch(ver, compatOpts) {
log.Debugf("Requested plugin version %s v%s is not supported on your system but potential fallback version '%s' was found",
pluginID, version, latestForArch.Version)
return VersionData{}, ErrVersionUnsupported(pluginID, version, compatOpts.OSAndArch())
}
return VersionData{
Version: ver.Version,
Checksum: checksum(ver, compatOpts),
Arch: ver.Arch,
URL: ver.URL,
}, nil
}
func checksum(v Version, compatOpts SystemCompatOpts) string {
if v.Arch != nil {
archMeta, exists := v.Arch[compatOpts.OSAndArch()]
if !exists {
archMeta = v.Arch["any"]
}
return archMeta.SHA256
}
return ""
}
func supportsCurrentArch(version Version, compatOpts SystemCompatOpts) bool {
if version.Arch == nil {
return true
}
for arch := range version.Arch {
if arch == compatOpts.OSAndArch() || arch == "any" {
return true
}
}
return false
}
func latestSupportedVersion(versions []Version, compatOpts SystemCompatOpts) (Version, bool) {
for _, v := range versions {
if supportsCurrentArch(v, compatOpts) {
return v, true
}
}
return Version{}, false
}
func normalizeVersion(version string) string {
normalized := strings.ReplaceAll(version, " ", "")
if strings.HasPrefix(normalized, "^") || strings.HasPrefix(normalized, "v") {
return normalized[1:]
}
return normalized
}