mirror of
https://github.com/grafana/grafana.git
synced 2025-08-02 23:12:54 +08:00
Plugins: Add Plugin FS abstraction (#63734)
* unexport pluginDir from dto * first pass * tidy * naming + add mutex * add dupe checking * fix func typo * interface + move logic from renderer * remote finder * remote signing * fix tests * tidy up * tidy markdown logic * split changes * fix tests * slim interface down * fix status code * tidy exec path func * fixup * undo changes * remove unused func * remove unused func * fix goimports * fetch remotely * simultaneous support * fix linter * use var * add exception for gosec warning * fixup * fix tests * tidy * rework cfg pattern * simplify * PR feedback * fix dupe field * remove g304 nolint * apply PR feedback * remove unnecessary gosec nolint * fix finder loop and update comment * fix map alloc * fix test * remove commented code
This commit is contained in:
91
pkg/plugins/localfiles.go
Normal file
91
pkg/plugins/localfiles.go
Normal file
@ -0,0 +1,91 @@
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
var _ fs.FS = (*LocalFS)(nil)
|
||||
|
||||
type LocalFS struct {
|
||||
m map[string]*LocalFile
|
||||
basePath string
|
||||
}
|
||||
|
||||
func NewLocalFS(m map[string]struct{}, basePath string) LocalFS {
|
||||
pfs := make(map[string]*LocalFile, len(m))
|
||||
for k := range m {
|
||||
pfs[k] = &LocalFile{
|
||||
path: k,
|
||||
}
|
||||
}
|
||||
|
||||
return LocalFS{
|
||||
m: pfs,
|
||||
basePath: basePath,
|
||||
}
|
||||
}
|
||||
|
||||
func (f LocalFS) Open(name string) (fs.File, error) {
|
||||
cleanPath, err := util.CleanRelativePath(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if kv, exists := f.m[filepath.Join(f.basePath, cleanPath)]; exists {
|
||||
if kv.f != nil {
|
||||
return kv.f, nil
|
||||
}
|
||||
return os.Open(kv.path)
|
||||
}
|
||||
return nil, ErrFileNotExist
|
||||
}
|
||||
|
||||
func (f LocalFS) Base() string {
|
||||
return f.basePath
|
||||
}
|
||||
|
||||
func (f LocalFS) Files() []string {
|
||||
var files []string
|
||||
for p := range f.m {
|
||||
r, err := filepath.Rel(f.basePath, p)
|
||||
if strings.Contains(r, "..") || err != nil {
|
||||
continue
|
||||
}
|
||||
files = append(files, r)
|
||||
}
|
||||
|
||||
return files
|
||||
}
|
||||
|
||||
var _ fs.File = (*LocalFile)(nil)
|
||||
|
||||
type LocalFile struct {
|
||||
f *os.File
|
||||
path string
|
||||
}
|
||||
|
||||
func (p *LocalFile) Stat() (fs.FileInfo, error) {
|
||||
return os.Stat(p.path)
|
||||
}
|
||||
|
||||
func (p *LocalFile) Read(bytes []byte) (int, error) {
|
||||
var err error
|
||||
p.f, err = os.Open(p.path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return p.f.Read(bytes)
|
||||
}
|
||||
|
||||
func (p *LocalFile) Close() error {
|
||||
if p.f != nil {
|
||||
return p.f.Close()
|
||||
}
|
||||
p.f = nil
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user