| package agent
|
|
|
| import (
|
| "errors"
|
| "fmt"
|
| "os"
|
| "path/filepath"
|
| "runtime"
|
|
|
| "github.com/henrygd/beszel/agent/utils"
|
| )
|
|
|
|
|
|
|
|
|
| func GetDataDir(dataDirs ...string) (string, error) {
|
| if len(dataDirs) > 0 {
|
| return testDataDirs(dataDirs)
|
| }
|
|
|
| dataDir, _ := utils.GetEnv("DATA_DIR")
|
| if dataDir != "" {
|
| dataDirs = append(dataDirs, dataDir)
|
| }
|
|
|
| if runtime.GOOS == "windows" {
|
| dataDirs = append(dataDirs,
|
| filepath.Join(os.Getenv("APPDATA"), "beszel-agent"),
|
| filepath.Join(os.Getenv("LOCALAPPDATA"), "beszel-agent"),
|
| )
|
| } else {
|
| dataDirs = append(dataDirs, "/var/lib/beszel-agent")
|
| if homeDir, err := os.UserHomeDir(); err == nil {
|
| dataDirs = append(dataDirs, filepath.Join(homeDir, ".config", "beszel"))
|
| }
|
| }
|
| return testDataDirs(dataDirs)
|
| }
|
|
|
| func testDataDirs(paths []string) (string, error) {
|
|
|
| for _, path := range paths {
|
| if valid, _ := isValidDataDir(path, false); valid {
|
| return path, nil
|
| }
|
| }
|
|
|
| for _, path := range paths {
|
| exists, _ := directoryExists(path)
|
| if exists {
|
| continue
|
| }
|
|
|
| if err := os.MkdirAll(path, 0755); err != nil {
|
| continue
|
| }
|
|
|
|
|
| writable, _ := directoryIsWritable(path)
|
| if !writable {
|
| continue
|
| }
|
|
|
| return path, nil
|
| }
|
|
|
| return "", errors.New("data directory not found")
|
| }
|
|
|
| func isValidDataDir(path string, createIfNotExists bool) (bool, error) {
|
| exists, err := directoryExists(path)
|
| if err != nil {
|
| return false, err
|
| }
|
|
|
| if !exists {
|
| if !createIfNotExists {
|
| return false, nil
|
| }
|
| if err = os.MkdirAll(path, 0755); err != nil {
|
| return false, err
|
| }
|
| }
|
|
|
|
|
| writable, err := directoryIsWritable(path)
|
| if err != nil {
|
| return false, err
|
| }
|
| return writable, nil
|
| }
|
|
|
|
|
| func directoryExists(path string) (bool, error) {
|
|
|
| stat, err := os.Stat(path)
|
| if err != nil {
|
| if os.IsNotExist(err) {
|
| return false, nil
|
| }
|
| return false, err
|
| }
|
| if !stat.IsDir() {
|
| return false, fmt.Errorf("%s is not a directory", path)
|
| }
|
| return true, nil
|
| }
|
|
|
|
|
| func directoryIsWritable(path string) (bool, error) {
|
| testFile := filepath.Join(path, ".write-test")
|
| file, err := os.Create(testFile)
|
| if err != nil {
|
| return false, err
|
| }
|
| defer file.Close()
|
| defer os.Remove(testFile)
|
| return true, nil
|
| }
|
|
|