e0d1f9aedc
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>
(cherry picked from commit b47ec36d0d)
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
|
|
}
|