68 lines
1.7 KiB
Go
68 lines
1.7 KiB
Go
package app
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
func transportMaybeMigrateSingBoxDNSConfig(client TransportClient) (string, error) {
|
|
if client.Kind != TransportClientSingBox {
|
|
return "", nil
|
|
}
|
|
if !transportSingBoxDNSMigrationEnabled(client) {
|
|
return "", nil
|
|
}
|
|
path := transportSingBoxConfigPath(client)
|
|
if path == "" {
|
|
return "", nil
|
|
}
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return "", fmt.Errorf("read singbox config failed: %w", err)
|
|
}
|
|
var root map[string]any
|
|
if err := json.Unmarshal(data, &root); err != nil {
|
|
return "", fmt.Errorf("parse singbox config failed: %w", err)
|
|
}
|
|
|
|
changed, warnings := transportMigrateSingBoxDNSConfigMap(root)
|
|
if !changed {
|
|
if len(warnings) == 0 {
|
|
return "", nil
|
|
}
|
|
return "", errors.New(strings.Join(warnings, "; "))
|
|
}
|
|
|
|
backup := path + ".legacy-dns.bak"
|
|
if _, err := os.Stat(backup); os.IsNotExist(err) {
|
|
if writeErr := os.WriteFile(backup, data, 0o644); writeErr != nil {
|
|
return "", fmt.Errorf("write backup failed: %w", writeErr)
|
|
}
|
|
}
|
|
|
|
out, err := json.MarshalIndent(root, "", " ")
|
|
if err != nil {
|
|
return "", fmt.Errorf("marshal migrated config failed: %w", err)
|
|
}
|
|
tmp := path + ".tmp"
|
|
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
|
return "", fmt.Errorf("ensure config dir failed: %w", err)
|
|
}
|
|
if err := os.WriteFile(tmp, append(out, '\n'), 0o644); err != nil {
|
|
return "", fmt.Errorf("write migrated config failed: %w", err)
|
|
}
|
|
if err := os.Rename(tmp, path); err != nil {
|
|
return "", fmt.Errorf("replace migrated config failed: %w", err)
|
|
}
|
|
|
|
msg := "singbox dns migrated to new server format"
|
|
if len(warnings) > 0 {
|
|
return msg, errors.New(strings.Join(warnings, "; "))
|
|
}
|
|
return msg, nil
|
|
}
|