mirror of
https://github.com/grafana/grafana.git
synced 2025-07-29 10:32:29 +08:00

Earlier we only allowed symlinks in plugins starting with grafana- in zip archives when installing plugins using the grafana-cli. This changes so that symlinks in zip archives containing relative links to files in the zip archive are always allowed when installing plugins. The reasoning behind this is that Grafana per default doesn't load a plugin that has an invalid plugin signature meaning that any symlink must be included in the plugin signature manifest. Co-authored-by: Will Browne <will.browne@grafana.com> Co-authored-by: Will Browne <wbrowne@users.noreply.github.com>
90 lines
2.1 KiB
Go
90 lines
2.1 KiB
Go
package commands
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"runtime"
|
|
"strings"
|
|
|
|
"github.com/grafana/grafana/pkg/cmd/grafana-cli/models"
|
|
"github.com/grafana/grafana/pkg/cmd/grafana-cli/services"
|
|
"github.com/grafana/grafana/pkg/cmd/grafana-cli/utils"
|
|
"github.com/grafana/grafana/pkg/plugins/manager/installer"
|
|
)
|
|
|
|
func validateInput(c utils.CommandLine, pluginFolder string) error {
|
|
arg := c.Args().First()
|
|
if arg == "" {
|
|
return errors.New("please specify plugin to install")
|
|
}
|
|
|
|
pluginsDir := c.PluginDirectory()
|
|
if pluginsDir == "" {
|
|
return errors.New("missing pluginsDir flag")
|
|
}
|
|
|
|
fileInfo, err := os.Stat(pluginsDir)
|
|
if err != nil {
|
|
if err = os.MkdirAll(pluginsDir, os.ModePerm); err != nil {
|
|
return fmt.Errorf("pluginsDir (%s) is not a writable directory", pluginsDir)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
if !fileInfo.IsDir() {
|
|
return errors.New("path is not a directory")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (cmd Command) installCommand(c utils.CommandLine) error {
|
|
pluginFolder := c.PluginDirectory()
|
|
if err := validateInput(c, pluginFolder); err != nil {
|
|
return err
|
|
}
|
|
|
|
pluginID := c.Args().First()
|
|
version := c.Args().Get(1)
|
|
return InstallPlugin(pluginID, version, c)
|
|
}
|
|
|
|
// InstallPlugin downloads the plugin code as a zip file from the Grafana.com API
|
|
// and then extracts the zip into the plugins directory.
|
|
func InstallPlugin(pluginID, version string, c utils.CommandLine) error {
|
|
skipTLSVerify := c.Bool("insecure")
|
|
|
|
i := installer.New(skipTLSVerify, services.GrafanaVersion, services.Logger)
|
|
return i.Install(context.Background(), pluginID, version, c.PluginDirectory(), c.PluginURL(), c.PluginRepoURL())
|
|
}
|
|
|
|
func osAndArchString() string {
|
|
osString := strings.ToLower(runtime.GOOS)
|
|
arch := runtime.GOARCH
|
|
return osString + "-" + arch
|
|
}
|
|
|
|
func supportsCurrentArch(version *models.Version) bool {
|
|
if version.Arch == nil {
|
|
return true
|
|
}
|
|
for arch := range version.Arch {
|
|
if arch == osAndArchString() || arch == "any" {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func latestSupportedVersion(plugin *models.Plugin) *models.Version {
|
|
for _, v := range plugin.Versions {
|
|
ver := v
|
|
if supportsCurrentArch(&ver) {
|
|
return &ver
|
|
}
|
|
}
|
|
return nil
|
|
}
|