mirror of
https://github.com/grafana/grafana.git
synced 2025-02-09 23:16:16 -06:00
* WIP * Set public_suffix to a pre Ruby 2.6 version * we don't need to install python * Stretch->Buster * Bump versions in lib.star * Manually update linter Sort of messy, but the .mod-file need to contain all dependencies that use 1.16+ features, otherwise they're assumed to be compiled with -lang=go1.16 and cannot access generics et al. Bingo doesn't seem to understand that, but it's possible to manually update things to get Bingo happy. * undo reformatting * Various lint improvements * More from the linter * goimports -w ./pkg/ * Disable gocritic * Add/modify linter exceptions * lint + flatten nested list Go 1.19 doesn't support nested lists, and there wasn't an obvious workaround. https://go.dev/doc/comment#lists
119 lines
3.0 KiB
Go
119 lines
3.0 KiB
Go
package plugins
|
|
|
|
import (
|
|
"context"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/grafana/grafana/pkg/build/errutil"
|
|
"github.com/grafana/grafana/pkg/build/syncutil"
|
|
)
|
|
|
|
// logCloseError executes the closeFunc; if it returns an error, it is logged by the log package.
|
|
func logCloseError(closeFunc func() error) {
|
|
if err := closeFunc(); err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
|
|
// logCloseError executes the closeFunc; if it returns an error, it is logged by the log package.
|
|
func logError(err error) {
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
|
|
// pluginManifest has details of an external plugin package.
|
|
type pluginManifest struct {
|
|
Name string `json:"name"`
|
|
Version string `json:"version"`
|
|
Checksum string `json:"checksum"`
|
|
}
|
|
|
|
// pluginsManifest represents a manifest of Grafana's external plugins.
|
|
type pluginsManifest struct {
|
|
Plugins []pluginManifest `json:"plugins"`
|
|
}
|
|
|
|
// downloadPlugins downloads Grafana plugins that should be bundled into packages.
|
|
//
|
|
// The plugin archives are downloaded into <grafanaDir>/plugins-bundled.
|
|
func Download(ctx context.Context, grafanaDir string, p syncutil.WorkerPool) error {
|
|
g, _ := errutil.GroupWithContext(ctx)
|
|
|
|
log.Println("Downloading external plugins...")
|
|
|
|
var m pluginsManifest
|
|
manifestPath := filepath.Join(grafanaDir, "plugins-bundled", "external.json")
|
|
//nolint:gosec
|
|
manifestB, err := os.ReadFile(manifestPath)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to open plugins manifest %q: %w", manifestPath, err)
|
|
}
|
|
if err := json.Unmarshal(manifestB, &m); err != nil {
|
|
return err
|
|
}
|
|
|
|
for i := range m.Plugins {
|
|
pm := m.Plugins[i]
|
|
p.Schedule(g.Wrap(func() error {
|
|
tgt := filepath.Join(grafanaDir, "plugins-bundled", fmt.Sprintf("%s-%s.zip", pm.Name, pm.Version))
|
|
//nolint:gosec
|
|
out, err := os.Create(tgt)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer logCloseError(out.Close)
|
|
|
|
u := fmt.Sprintf("http://storage.googleapis.com/plugins-ci/plugins/%s/%s-%s.zip", pm.Name, pm.Name,
|
|
pm.Version)
|
|
log.Printf("Downloading plugin %q to %q...", u, tgt)
|
|
// nolint:gosec
|
|
resp, err := http.Get(u)
|
|
if err != nil {
|
|
return fmt.Errorf("downloading %q failed: %w", u, err)
|
|
}
|
|
defer logError(resp.Body.Close())
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return fmt.Errorf("failed to download %q, status code %d", u, resp.StatusCode)
|
|
}
|
|
|
|
if _, err := io.Copy(out, resp.Body); err != nil {
|
|
return fmt.Errorf("downloading %q failed: %w", u, err)
|
|
}
|
|
if err := out.Close(); err != nil {
|
|
return fmt.Errorf("downloading %q failed: %w", u, err)
|
|
}
|
|
|
|
//nolint:gosec
|
|
fd, err := os.Open(tgt)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer logCloseError(fd.Close)
|
|
|
|
h := sha256.New()
|
|
if _, err := io.Copy(h, fd); err != nil {
|
|
return err
|
|
}
|
|
|
|
chksum := hex.EncodeToString(h.Sum(nil))
|
|
if chksum != pm.Checksum {
|
|
return fmt.Errorf("plugin %q has bad checksum: %s (expected %s)", u, chksum, pm.Checksum)
|
|
}
|
|
|
|
return Unzip(tgt, filepath.Join(grafanaDir, "plugins-bundled"))
|
|
}))
|
|
}
|
|
|
|
return g.Wait()
|
|
}
|