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 }