diff --git a/cmd/migration/1_3.go b/cmd/migration/1_3.go new file mode 100644 index 0000000..0c4cdd3 --- /dev/null +++ b/cmd/migration/1_3.go @@ -0,0 +1,125 @@ +package migration + +import ( + "encoding/json" + "net/url" + "s-ui/database/model" + "strconv" + "strings" + + "gorm.io/gorm" +) + +func migrate_dns(db *gorm.DB) error { + var configStr string + err := db.Model(model.Setting{}).Select("value").Where("key = ?", "config").First(&configStr).Error + if err != nil { + return err + } + if configStr == "" { + return nil + } + var config map[string]interface{} + err = json.Unmarshal([]byte(configStr), &config) + if err != nil { + return err + } + if dnsConfig, ok := config["dns"].(map[string]interface{}); ok { + if dnsServers, ok := dnsConfig["servers"].([]interface{}); ok { + for index, dnsServer := range dnsServers { + if dnsServer, ok := dnsServer.(map[string]interface{}); ok { + if addr, ok := dnsServer["address"].(string); ok && addr != "" { + switch addr { + case "local": + delete(dnsServer, "address") + dnsServer["type"] = "local" + case "fakeip": + delete(dnsServer, "address") + dnsServer["type"] = "fakeip" + default: + addrParsed, err := url.Parse(addr) + if err != nil { + continue + } + switch addrParsed.Scheme { + case "": + dnsServer["type"] = "udp" + dnsServer["server"] = addr + case "udp", "tcp", "tls", "quic", "https", "h3": + dnsServer["type"] = addrParsed.Scheme + dnsServer["server"] = addrParsed.Host + case "dhcp": + dnsServer["type"] = addrParsed.Scheme + if addrParsed.Host != "auto" && addrParsed.Host != "" { + dnsServer["interface"] = addrParsed.Host + } + case "rcode": + dnsServer["type"] = "predefined" + dnsServer["responses"] = []map[string]string{ + { + "rcode": strings.ToUpper(addrParsed.Host), + }, + } + } + delete(dnsServer, "address") + if addrParsed.Port() != "" { + port, err := strconv.Atoi(addrParsed.Port()) + if err == nil { + dnsServer["server_port"] = port + } + } + if address_resolver, ok := dnsServer["address_resolver"].(string); ok && address_resolver != "" { + delete(dnsServer, "address_resolver") + dnsServer["domain_resolver"] = address_resolver + } + delete(dnsServer, "strategy") + } + dnsServers[index] = dnsServer + } + } + } + dnsConfig["servers"] = dnsServers + } + config["dns"] = dnsConfig + } else { + return nil + } + + // save changes + configs, err := json.MarshalIndent(config, "", " ") + if err != nil { + return err + } + + return db.Model(model.Setting{}).Where("key = ?", "config").Update("value", string(configs)).Error +} + +func remove_outbound_strategy(db *gorm.DB) error { + var outbounds []model.Outbound + err := db.Find(&outbounds).Where("json_extract(options, '$.domain_strategy') IS NOT NULL").Error + if err != nil { + return err + } + for _, outbound := range outbounds { + var restFields map[string]json.RawMessage + if err := json.Unmarshal(outbound.Options, &restFields); err != nil { + return err + } + delete(restFields, "domain_strategy") + outbound.Options, _ = json.MarshalIndent(restFields, "", " ") + db.Save(&outbound) + } + return nil +} + +func to1_3(db *gorm.DB) error { + err := migrate_dns(db) + if err != nil { + return err + } + err = remove_outbound_strategy(db) + if err != nil { + return err + } + return nil +} diff --git a/cmd/migration/main.go b/cmd/migration/main.go index 3291909..b9ea97a 100644 --- a/cmd/migration/main.go +++ b/cmd/migration/main.go @@ -56,10 +56,20 @@ func MigrateDb() { log.Fatal("Migration to 1.2 failed: ", err) return } + dbVersion = "1.2" + } + + // Before 1.3 + if dbVersion[0:3] == "1.2" { + err = to1_3(tx) + if err != nil { + log.Fatal("Migration to 1.3 failed: ", err) + return + } } // Set version - err = tx.Raw("UPDATE settings SET value = ? WHERE key = ?", currentVersion, "version").Error + err = tx.Exec("UPDATE settings SET value = ? WHERE key = ?", currentVersion, "version").Error if err != nil { log.Fatal("Update version failed: ", err) return