126 lines
3.4 KiB
Go
126 lines
3.4 KiB
Go
package storage
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"filefast/backend/internal/model"
|
|
)
|
|
|
|
const (
|
|
runtimeConfigKey = "transfer_policy"
|
|
)
|
|
|
|
type runtimeConfigPayload struct {
|
|
MaxMinIOFallbackSizeBytes *int64 `json:"max_minio_fallback_size_bytes"`
|
|
MaxMinIOFallbackGB *int64 `json:"max_minio_fallback_gb"`
|
|
MinIOCapacityBytes *int64 `json:"minio_capacity_bytes"`
|
|
MinIOCapacityGB *int64 `json:"minio_capacity_gb"`
|
|
MinIORetentionHours *int `json:"minio_retention_hours"`
|
|
MinIOUsageAlertPercent *int `json:"minio_usage_alert_percent"`
|
|
P2PConnectTimeoutSec *int `json:"p2p_connect_timeout_sec"`
|
|
TURNConnectTimeoutSec *int `json:"turn_connect_timeout_sec"`
|
|
MinIOFallbackEnabled *bool `json:"minio_fallback_enabled"`
|
|
TURNURLs []string `json:"turn_urls"`
|
|
TURNUsername *string `json:"turn_username"`
|
|
TURNPassword *string `json:"turn_password"`
|
|
}
|
|
|
|
func decodeRuntimeConfig(raw []byte, fallback model.RuntimeConfig) (model.RuntimeConfig, error) {
|
|
cfg := fallback
|
|
if len(raw) == 0 {
|
|
return cfg, nil
|
|
}
|
|
|
|
var payload runtimeConfigPayload
|
|
if err := json.Unmarshal(raw, &payload); err != nil {
|
|
return model.RuntimeConfig{}, err
|
|
}
|
|
|
|
if payload.MaxMinIOFallbackSizeBytes != nil {
|
|
cfg.MaxMinIOFallbackSizeBytes = *payload.MaxMinIOFallbackSizeBytes
|
|
} else if payload.MaxMinIOFallbackGB != nil {
|
|
cfg.MaxMinIOFallbackSizeBytes = *payload.MaxMinIOFallbackGB * 1024 * 1024 * 1024
|
|
}
|
|
if payload.MinIOCapacityBytes != nil {
|
|
cfg.MinIOCapacityBytes = *payload.MinIOCapacityBytes
|
|
} else if payload.MinIOCapacityGB != nil {
|
|
cfg.MinIOCapacityBytes = *payload.MinIOCapacityGB * 1024 * 1024 * 1024
|
|
}
|
|
if payload.MinIORetentionHours != nil {
|
|
cfg.MinIORetentionHours = *payload.MinIORetentionHours
|
|
}
|
|
if payload.MinIOUsageAlertPercent != nil {
|
|
cfg.MinIOUsageAlertPercent = *payload.MinIOUsageAlertPercent
|
|
}
|
|
if payload.P2PConnectTimeoutSec != nil {
|
|
cfg.P2PConnectTimeoutSec = *payload.P2PConnectTimeoutSec
|
|
}
|
|
if payload.TURNConnectTimeoutSec != nil {
|
|
cfg.TURNConnectTimeoutSec = *payload.TURNConnectTimeoutSec
|
|
}
|
|
if payload.MinIOFallbackEnabled != nil {
|
|
cfg.MinIOFallbackEnabled = *payload.MinIOFallbackEnabled
|
|
}
|
|
if payload.TURNURLs != nil {
|
|
cfg.TURNURLs = payload.TURNURLs
|
|
}
|
|
if payload.TURNUsername != nil {
|
|
cfg.TURNUsername = *payload.TURNUsername
|
|
}
|
|
if payload.TURNPassword != nil {
|
|
cfg.TURNPassword = *payload.TURNPassword
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|
|
|
|
func readFirstExistingFile(paths ...string) ([]byte, error) {
|
|
candidates := make([]string, 0, len(paths)*8)
|
|
seen := make(map[string]struct{})
|
|
|
|
cwd, err := os.Getwd()
|
|
if err == nil {
|
|
current := cwd
|
|
for {
|
|
for _, path := range paths {
|
|
candidate := filepath.Clean(filepath.Join(current, path))
|
|
if _, ok := seen[candidate]; ok {
|
|
continue
|
|
}
|
|
seen[candidate] = struct{}{}
|
|
candidates = append(candidates, candidate)
|
|
}
|
|
|
|
parent := filepath.Dir(current)
|
|
if parent == current {
|
|
break
|
|
}
|
|
current = parent
|
|
}
|
|
}
|
|
|
|
for _, path := range paths {
|
|
candidate := filepath.Clean(path)
|
|
if _, ok := seen[candidate]; ok {
|
|
continue
|
|
}
|
|
seen[candidate] = struct{}{}
|
|
candidates = append(candidates, candidate)
|
|
}
|
|
|
|
for _, candidate := range candidates {
|
|
data, err := os.ReadFile(candidate)
|
|
if err == nil {
|
|
return data, nil
|
|
}
|
|
if !errors.Is(err, os.ErrNotExist) {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return nil, os.ErrNotExist
|
|
}
|