mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
114 lines
2.9 KiB
Go
114 lines
2.9 KiB
Go
// SPDX-License-Identifier: AGPL-3.0-only
|
|
// Provenance-includes-location: https://github.com/kubernetes-sigs/apiserver-runtime/blob/main/pkg/experimental/storage/filepath/jsonfile_rest.go
|
|
// Provenance-includes-license: Apache-2.0
|
|
// Provenance-includes-copyright: The Kubernetes Authors.
|
|
|
|
package file
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
)
|
|
|
|
func (s *Storage) filePath(key string) string {
|
|
// Replace backslashes with underscores to avoid creating bogus subdirectories
|
|
key = strings.Replace(key, "\\", "_", -1)
|
|
fileName := filepath.Join(s.root, filepath.Clean(key+".json"))
|
|
return fileName
|
|
}
|
|
|
|
// this is for constructing dirPath in a sanitized way provided you have
|
|
// already calculated the key. In order to go in the other direction, from a file path
|
|
// key to its dir, use the go standard library: filepath.Dir
|
|
func (s *Storage) dirPath(key string) string {
|
|
return dirPath(s.root, key)
|
|
}
|
|
|
|
func writeFile(codec runtime.Codec, path string, obj runtime.Object) error {
|
|
buf := new(bytes.Buffer)
|
|
if err := codec.Encode(obj, buf); err != nil {
|
|
return err
|
|
}
|
|
return os.WriteFile(path, buf.Bytes(), 0600)
|
|
}
|
|
|
|
func readFile(codec runtime.Codec, path string, newFunc func() runtime.Object) (runtime.Object, error) {
|
|
content, err := os.ReadFile(filepath.Clean(path))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
newObj := newFunc()
|
|
decodedObj, _, err := codec.Decode(content, nil, newObj)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return decodedObj, nil
|
|
}
|
|
|
|
func readDirRecursive(codec runtime.Codec, path string, newFunc func() runtime.Object) ([]runtime.Object, error) {
|
|
var objs []runtime.Object
|
|
err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if info.IsDir() || filepath.Ext(path) != ".json" {
|
|
return nil
|
|
}
|
|
obj, err := readFile(codec, path, newFunc)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
objs = append(objs, obj)
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
if errors.Is(err, os.ErrNotExist) {
|
|
return objs, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
return objs, nil
|
|
}
|
|
|
|
func deleteFile(path string) error {
|
|
return os.Remove(path)
|
|
}
|
|
|
|
func exists(filepath string) bool {
|
|
_, err := os.Stat(filepath)
|
|
return err == nil
|
|
}
|
|
|
|
func dirPath(root string, key string) string {
|
|
// Replace backslashes with underscores to avoid creating bogus subdirectories
|
|
key = strings.Replace(key, "\\", "_", -1)
|
|
dirName := filepath.Join(root, filepath.Clean(key))
|
|
return dirName
|
|
}
|
|
|
|
func ensureDir(dirname string) error {
|
|
if !exists(dirname) {
|
|
return os.MkdirAll(dirname, 0700)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func isUnchanged(codec runtime.Codec, obj runtime.Object, newObj runtime.Object) (bool, error) {
|
|
buf := new(bytes.Buffer)
|
|
if err := codec.Encode(obj, buf); err != nil {
|
|
return false, err
|
|
}
|
|
|
|
newBuf := new(bytes.Buffer)
|
|
if err := codec.Encode(newObj, newBuf); err != nil {
|
|
return false, err
|
|
}
|
|
|
|
return bytes.Equal(buf.Bytes(), newBuf.Bytes()), nil
|
|
}
|