CLI: Reduce memory usage for plugin installation (#19639)
* grafana-cli: use tmp file when downloading plugin install file
This commit is contained in:
committed by
Arve Knudsen
parent
46a4118461
commit
b4712ec4b9
@@ -1,12 +1,14 @@
|
||||
package commandstest
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/grafana/grafana/pkg/cmd/grafana-cli/models"
|
||||
)
|
||||
|
||||
type FakeGrafanaComClient struct {
|
||||
GetPluginFunc func(pluginId, repoUrl string) (models.Plugin, error)
|
||||
DownloadFileFunc func(pluginName, filePath, url string, checksum string) (content []byte, err error)
|
||||
DownloadFileFunc func(pluginName string, tmpFile *os.File, url string, checksum string) (err error)
|
||||
ListAllPluginsFunc func(repoUrl string) (models.PluginRepo, error)
|
||||
}
|
||||
|
||||
@@ -18,12 +20,12 @@ func (client *FakeGrafanaComClient) GetPlugin(pluginId, repoUrl string) (models.
|
||||
return models.Plugin{}, nil
|
||||
}
|
||||
|
||||
func (client *FakeGrafanaComClient) DownloadFile(pluginName, filePath, url string, checksum string) (content []byte, err error) {
|
||||
func (client *FakeGrafanaComClient) DownloadFile(pluginName string, tmpFile *os.File, url string, checksum string) (err error) {
|
||||
if client.DownloadFileFunc != nil {
|
||||
return client.DownloadFileFunc(pluginName, filePath, url, checksum)
|
||||
return client.DownloadFileFunc(pluginName, tmpFile, url, checksum)
|
||||
}
|
||||
|
||||
return make([]byte, 0), nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client *FakeGrafanaComClient) ListAllPlugins(repoUrl string) (models.PluginRepo, error) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -107,12 +108,24 @@ func InstallPlugin(pluginName, version string, c utils.CommandLine) error {
|
||||
logger.Infof("into: %v\n", pluginFolder)
|
||||
logger.Info("\n")
|
||||
|
||||
content, err := c.ApiClient().DownloadFile(pluginName, pluginFolder, downloadURL, checksum)
|
||||
// Create temp file for downloading zip file
|
||||
tmpFile, err := ioutil.TempFile("", "*.zip")
|
||||
if err != nil {
|
||||
return errutil.Wrap("Failed to create temporary file", err)
|
||||
}
|
||||
defer os.Remove(tmpFile.Name())
|
||||
|
||||
err = c.ApiClient().DownloadFile(pluginName, tmpFile, downloadURL, checksum)
|
||||
if err != nil {
|
||||
tmpFile.Close()
|
||||
return errutil.Wrap("Failed to download plugin archive", err)
|
||||
}
|
||||
err = tmpFile.Close()
|
||||
if err != nil {
|
||||
return errutil.Wrap("Failed to close tmp file", err)
|
||||
}
|
||||
|
||||
err = extractFiles(content, pluginName, pluginFolder, isInternal)
|
||||
err = extractFiles(tmpFile.Name(), pluginName, pluginFolder, isInternal)
|
||||
if err != nil {
|
||||
return errutil.Wrap("Failed to extract plugin archive", err)
|
||||
}
|
||||
@@ -197,8 +210,10 @@ func RemoveGitBuildFromName(pluginName, filename string) string {
|
||||
|
||||
var permissionsDeniedMessage = "Could not create %s. Permission denied. Make sure you have write access to plugindir"
|
||||
|
||||
func extractFiles(body []byte, pluginName string, filePath string, allowSymlinks bool) error {
|
||||
r, err := zip.NewReader(bytes.NewReader(body), int64(len(body)))
|
||||
func extractFiles(archiveFile string, pluginName string, filePath string, allowSymlinks bool) error {
|
||||
logger.Debugf("Extracting archive %v to %v...\n", archiveFile, filePath)
|
||||
|
||||
r, err := zip.OpenReader(archiveFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
@@ -52,10 +52,8 @@ func TestExtractFiles(t *testing.T) {
|
||||
pluginDir, del := setupFakePluginsDir(t)
|
||||
defer del()
|
||||
|
||||
body, err := ioutil.ReadFile("testdata/grafana-simple-json-datasource-ec18fa4da8096a952608a7e4c7782b4260b41bcf.zip")
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = extractFiles(body, "grafana-simple-json-datasource", pluginDir, false)
|
||||
archive := "testdata/grafana-simple-json-datasource-ec18fa4da8096a952608a7e4c7782b4260b41bcf.zip"
|
||||
err := extractFiles(archive, "grafana-simple-json-datasource", pluginDir, false)
|
||||
assert.Nil(t, err)
|
||||
|
||||
//File in zip has permissions 755
|
||||
@@ -83,10 +81,7 @@ func TestExtractFiles(t *testing.T) {
|
||||
pluginDir, del := setupFakePluginsDir(t)
|
||||
defer del()
|
||||
|
||||
body, err := ioutil.ReadFile("testdata/plugin-with-symlink.zip")
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = extractFiles(body, "plugin-with-symlink", pluginDir, false)
|
||||
err := extractFiles("testdata/plugin-with-symlink.zip", "plugin-with-symlink", pluginDir, false)
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, err = os.Stat(pluginDir + "/plugin-with-symlink/text.txt")
|
||||
@@ -100,10 +95,7 @@ func TestExtractFiles(t *testing.T) {
|
||||
pluginDir, del := setupFakePluginsDir(t)
|
||||
defer del()
|
||||
|
||||
body, err := ioutil.ReadFile("testdata/plugin-with-symlink.zip")
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = extractFiles(body, "plugin-with-symlink", pluginDir, true)
|
||||
err := extractFiles("testdata/plugin-with-symlink.zip", "plugin-with-symlink", pluginDir, true)
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, err = os.Stat(pluginDir + "/plugin-with-symlink/symlink_to_txt")
|
||||
@@ -228,13 +220,15 @@ func setupPluginInstallCmd(t *testing.T, pluginDir string) utils.CommandLine {
|
||||
return plugin, nil
|
||||
}
|
||||
|
||||
client.DownloadFileFunc = func(pluginName, filePath, url string, checksum string) (content []byte, err error) {
|
||||
client.DownloadFileFunc = func(pluginName string, tmpFile *os.File, url string, checksum string) (err error) {
|
||||
assert.Equal(t, "test-plugin-panel", pluginName)
|
||||
assert.Equal(t, "/test-plugin-panel/versions/1.0.0/download", url)
|
||||
assert.Equal(t, "test", checksum)
|
||||
body, err := ioutil.ReadFile("testdata/grafana-simple-json-datasource-ec18fa4da8096a952608a7e4c7782b4260b41bcf.zip")
|
||||
f, err := os.Open("testdata/grafana-simple-json-datasource-ec18fa4da8096a952608a7e4c7782b4260b41bcf.zip")
|
||||
assert.Nil(t, err)
|
||||
return body, nil
|
||||
_, err = io.Copy(tmpFile, f)
|
||||
assert.Nil(t, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
cmd.Client = client
|
||||
|
||||
Reference in New Issue
Block a user