Plugins: Move plugin installing + uninstalling logic from CLI to plugins package (#33274)

* move guts from cli to server

* renaming + refactoring

* add pluginsDir arg

* arg fixes

* add support for repo URL override

* add funcs to interface

* use pluginID consistently

* swap args

* pass mandatory grafanaVersion field

* introduce logger interface

* create central logger for CLI

* add infra log wrapper

* re-add log initer step

* remove unused logger

* add checks for uninstalling

* improve debug blue

* make sure to close file

* fix linter issues

* remove space

* improve newline usage

* refactor packaging

* improve logger API

* fix interface func names

* close file and reformat zipslip catch

* handle G305 linter warning

* add helpful debug log
This commit is contained in:
Will Browne
2021-04-26 16:13:40 +02:00
committed by GitHub
parent d0239ac958
commit 8e6205c107
13 changed files with 874 additions and 16 deletions
+3 -1
View File
@@ -3,6 +3,8 @@ package commands
import (
"strings"
"github.com/fatih/color"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/cmd/grafana-cli/commands/datamigrations"
"github.com/grafana/grafana/pkg/cmd/grafana-cli/logger"
@@ -57,7 +59,7 @@ func runPluginCommand(command func(commandLine utils.CommandLine) error) func(co
return err
}
logger.Info("\nRestart Grafana after installing plugins. Refer to Grafana documentation for instructions if necessary.\n\n\n\n")
logger.Info(color.GreenString("Please restart Grafana after installing plugins. Refer to Grafana documentation for instructions if necessary.\n\n"))
return nil
}
}
@@ -14,12 +14,13 @@ import (
"strings"
"github.com/fatih/color"
"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"
"github.com/grafana/grafana/pkg/util/errutil"
"github.com/grafana/grafana/pkg/cmd/grafana-cli/logger"
"github.com/grafana/grafana/pkg/cmd/grafana-cli/models"
"github.com/grafana/grafana/pkg/cmd/grafana-cli/services"
)
func validateInput(c utils.CommandLine, pluginFolder string) error {
@@ -54,10 +55,12 @@ func (cmd Command) installCommand(c utils.CommandLine) error {
return err
}
pluginToInstall := c.Args().First()
pluginID := c.Args().First()
version := c.Args().Get(1)
skipTLSVerify := c.Bool("insecure")
return InstallPlugin(pluginToInstall, version, c, cmd.Client)
i := installer.New(skipTLSVerify, services.GrafanaVersion, services.Logger)
return i.Install(pluginID, version, c.PluginDirectory(), c.PluginURL(), c.PluginRepoURL())
}
// InstallPlugin downloads the plugin code as a zip file from the Grafana.com API
@@ -76,7 +79,7 @@ func InstallPlugin(pluginName, version string, c utils.CommandLine, client utils
// is up to the user to know what she is doing.
isInternal = true
}
plugin, err := client.GetPlugin(pluginName, c.RepoDirectory())
plugin, err := client.GetPlugin(pluginName, c.PluginRepoURL())
if err != nil {
return err
}
@@ -8,7 +8,7 @@ import (
// listRemoteCommand prints out all plugins in the remote repo with latest version supported on current platform.
// If there are no supported versions for plugin it is skipped.
func (cmd Command) listRemoteCommand(c utils.CommandLine) error {
plugin, err := cmd.Client.ListAllPlugins(c.RepoDirectory())
plugin, err := cmd.Client.ListAllPlugins(c.PluginRepoURL())
if err != nil {
return err
}
@@ -18,7 +18,7 @@ func (cmd Command) upgradeCommand(c utils.CommandLine) error {
return err
}
plugin, err2 := cmd.Client.GetPlugin(pluginName, c.RepoDirectory())
plugin, err2 := cmd.Client.GetPlugin(pluginName, c.PluginRepoURL())
if err2 != nil {
return err2
}
+74
View File
@@ -0,0 +1,74 @@
package logger
import (
"fmt"
"strings"
"github.com/fatih/color"
)
type CLILogger struct {
DebugMode bool
}
func New(debugMode bool) *CLILogger {
return &CLILogger{
DebugMode: debugMode,
}
}
func (l *CLILogger) Successf(format string, args ...interface{}) {
fmt.Printf(fmt.Sprintf("%s %s\n\n", color.GreenString("✔"), format), args...)
}
func (l *CLILogger) Failuref(format string, args ...interface{}) {
fmt.Printf(fmt.Sprintf("%s %s %s\n\n", color.RedString("Error"), color.RedString("✗"), format), args...)
}
func (l *CLILogger) Info(args ...interface{}) {
args = append(args, "\n\n")
fmt.Print(args...)
}
func (l *CLILogger) Infof(format string, args ...interface{}) {
fmt.Printf(addNewlines(format), args...)
}
func (l *CLILogger) Debug(args ...interface{}) {
args = append(args, "\n\n")
if l.DebugMode {
fmt.Print(color.HiBlueString(fmt.Sprint(args...)))
}
}
func (l *CLILogger) Debugf(format string, args ...interface{}) {
if l.DebugMode {
fmt.Print(color.HiBlueString(fmt.Sprintf(addNewlines(format), args...)))
}
}
func (l *CLILogger) Warn(args ...interface{}) {
args = append(args, "\n\n")
fmt.Print(args...)
}
func (l *CLILogger) Warnf(format string, args ...interface{}) {
fmt.Printf(addNewlines(format), args...)
}
func (l *CLILogger) Error(args ...interface{}) {
args = append(args, "\n\n")
fmt.Print(args...)
}
func (l *CLILogger) Errorf(format string, args ...interface{}) {
fmt.Printf(addNewlines(format), args...)
}
func addNewlines(str string) string {
var s strings.Builder
s.WriteString(str)
s.WriteString("\n\n")
return s.String()
}
+1 -1
View File
@@ -72,7 +72,7 @@ func main() {
}
app.Before = func(c *cli.Context) error {
services.Init(version, c.Bool("insecure"))
services.Init(version, c.Bool("insecure"), c.Bool("debug"))
return nil
}
+2 -2
View File
@@ -174,10 +174,10 @@ func createRequest(repoUrl string, subPaths ...string) (*http.Request, error) {
return nil, err
}
req.Header.Set("grafana-version", grafanaVersion)
req.Header.Set("grafana-version", GrafanaVersion)
req.Header.Set("grafana-os", runtime.GOOS)
req.Header.Set("grafana-arch", runtime.GOARCH)
req.Header.Set("User-Agent", "grafana "+grafanaVersion)
req.Header.Set("User-Agent", "grafana "+GrafanaVersion)
return req, err
}
+6 -3
View File
@@ -18,8 +18,9 @@ var (
IoHelper models.IoUtil = IoUtilImp{}
HttpClient http.Client
HttpClientNoTimeout http.Client
grafanaVersion string
GrafanaVersion string
ErrNotFoundError = errors.New("404 not found error")
Logger *logger.CLILogger
)
type BadRequestError struct {
@@ -34,11 +35,12 @@ func (e *BadRequestError) Error() string {
return e.Status
}
func Init(version string, skipTLSVerify bool) {
grafanaVersion = version
func Init(version string, skipTLSVerify bool, debugMode bool) {
GrafanaVersion = version
HttpClient = makeHttpClient(skipTLSVerify, 10*time.Second)
HttpClientNoTimeout = makeHttpClient(skipTLSVerify, 0)
Logger = logger.New(debugMode)
}
func makeHttpClient(skipTLSVerify bool, timeout time.Duration) http.Client {
@@ -113,5 +115,6 @@ func RemoveInstalledPlugin(pluginPath, pluginName string) error {
return err
}
logger.Debugf("Removing directory %v\n", pluginDir)
return IoHelper.RemoveAll(pluginDir)
}
+2 -2
View File
@@ -20,7 +20,7 @@ type CommandLine interface {
Generic(name string) interface{}
PluginDirectory() string
RepoDirectory() string
PluginRepoURL() string
PluginURL() string
}
@@ -54,7 +54,7 @@ func (c *ContextCommandLine) PluginDirectory() string {
return c.String("pluginsDir")
}
func (c *ContextCommandLine) RepoDirectory() string {
func (c *ContextCommandLine) PluginRepoURL() string {
return c.String("repo")
}