Files
filefast/backend/internal/storage/shared.go
2026-03-28 15:43:18 +08:00

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
}