mirror of
https://github.com/grafana/grafana.git
synced 2024-11-27 19:30:36 -06:00
580cdc46fc
* change global flag to flagset * update pr with comments * replace flag.args by flagset * fix build * migrate the schema package to use cue 4.0 * fix the load package
95 lines
2.7 KiB
Go
95 lines
2.7 KiB
Go
package load
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"io/fs"
|
|
"path/filepath"
|
|
|
|
"cuelang.org/go/cue/cuecontext"
|
|
"cuelang.org/go/cue/load"
|
|
"github.com/grafana/grafana"
|
|
)
|
|
|
|
var ctx = cuecontext.New()
|
|
|
|
// Families can have variants, where more typing information narrows the
|
|
// possible values for certain keys in schemas. These are a meta-property
|
|
// of the schema, effectively encoded in these loaders.
|
|
//
|
|
// We can generally define three variants:
|
|
// - "Base": strictly core schema files, no plugins. (go:embed-able)
|
|
// - "Dist": "Base" + plugins that ship with vanilla Grafana (go:embed-able)
|
|
// - "Instance": "Dist" + the non-core plugins available in an actual, running Grafana
|
|
|
|
// BaseLoadPaths contains the configuration for loading a DistDashboard
|
|
type BaseLoadPaths struct {
|
|
// BaseCueFS should be rooted at a directory containing the filesystem layout
|
|
// expected to exist at github.com/grafana/grafana/cue.
|
|
BaseCueFS fs.FS
|
|
|
|
// DistPluginCueFS should point to some fs path (TBD) under which all core
|
|
// plugins live.
|
|
DistPluginCueFS fs.FS
|
|
|
|
// InstanceCueFS should point to a root dir in which non-core plugins live.
|
|
// Normal case will be that this only happens when an actual Grafana
|
|
// instance is making the call, and has a plugin dir to offer - though
|
|
// external tools could always create their own dirs shaped like a Grafana
|
|
// plugin dir, and point to those.
|
|
InstanceCueFS fs.FS
|
|
}
|
|
|
|
func GetDefaultLoadPaths() BaseLoadPaths {
|
|
return BaseLoadPaths{
|
|
BaseCueFS: grafana.CoreSchema,
|
|
DistPluginCueFS: grafana.PluginSchema,
|
|
}
|
|
}
|
|
|
|
// toOverlay converts all .cue files in the fs.FS into Source entries in an
|
|
// overlay map, as expected by load.Config.
|
|
//
|
|
// Each entry is placed in the map with the provided prefix - which must be an
|
|
// absolute path - ahead of the actual path of the added file within the fs.FS.
|
|
//
|
|
// The function writes into the provided overlay map, to facilitate the
|
|
// construction of a single overlay map from multiple fs.FS.
|
|
//
|
|
// All files reachable by walking the provided fs.FS are added to the overlay
|
|
// map, on the premise that control over the FS is sufficient to allow any
|
|
// desired filtering.
|
|
func toOverlay(prefix string, vfs fs.FS, overlay map[string]load.Source) error {
|
|
if !filepath.IsAbs(prefix) {
|
|
return fmt.Errorf("must provide absolute path prefix when generating cue overlay, got %q", prefix)
|
|
}
|
|
err := fs.WalkDir(vfs, ".", (func(path string, d fs.DirEntry, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if d.IsDir() {
|
|
return nil
|
|
}
|
|
|
|
f, err := vfs.Open(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
b, err := io.ReadAll(f)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
overlay[filepath.Join(prefix, path)] = load.FromBytes(b)
|
|
return nil
|
|
}))
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|