The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/pkg/plugins/manager/sources/source_local_disk.go

70 lines
1.6 KiB

package sources
import (
"context"
"errors"
"os"
"path/filepath"
"slices"
"github.com/grafana/grafana/pkg/plugins"
)
type LocalSource struct {
paths []string
class plugins.Class
}
func NewLocalSource(class plugins.Class, paths []string) *LocalSource {
return &LocalSource{
class: class,
paths: paths,
}
}
func (s *LocalSource) PluginClass(_ context.Context) plugins.Class {
return s.class
}
func (s *LocalSource) PluginURIs(_ context.Context) []string {
return s.paths
}
func (s *LocalSource) DefaultSignature(_ context.Context) (plugins.Signature, bool) {
switch s.class {
case plugins.ClassCore:
return plugins.Signature{
Status: plugins.SignatureStatusInternal,
}, true
default:
return plugins.Signature{}, false
}
}
func DirAsLocalSources(pluginsPath string, class plugins.Class) ([]*LocalSource, error) {
if pluginsPath == "" {
return []*LocalSource{}, errors.New("plugins path not configured")
}
// It's safe to ignore gosec warning G304 since the variable part of the file path comes from a configuration
// variable.
// nolint:gosec
d, err := os.ReadDir(pluginsPath)
if err != nil {
return []*LocalSource{}, errors.New("failed to open plugins path")
}
var pluginDirs []string
for _, dir := range d {
if dir.IsDir() || dir.Type()&os.ModeSymlink == os.ModeSymlink {
pluginDirs = append(pluginDirs, filepath.Join(pluginsPath, dir.Name()))
}
}
slices.Sort(pluginDirs)
var sources []*LocalSource
for _, dir := range pluginDirs {
sources = append(sources, NewLocalSource(class, []string{dir}))
}
return sources, nil
}