mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-21 17:56:39 +00:00
Merge branch 'main' into feature/migrate-auto-groups-to-table
# Conflicts: # management/server/migration/migration.go # management/server/store/store.go
This commit is contained in:
@@ -393,7 +393,7 @@ func CreateIndexIfNotExists[T any](ctx context.Context, db *gorm.DB, indexName s
|
||||
return fmt.Errorf("failed to parse model schema: %w", err)
|
||||
}
|
||||
tableName := stmt.Schema.Table
|
||||
dialect := db.Dialector.Name()
|
||||
dialect := db.Name()
|
||||
|
||||
if db.Migrator().HasIndex(&model, indexName) {
|
||||
log.WithContext(ctx).Infof("index %s already exists on table %s", indexName, tableName)
|
||||
@@ -404,10 +404,11 @@ func CreateIndexIfNotExists[T any](ctx context.Context, db *gorm.DB, indexName s
|
||||
if dialect == "mysql" {
|
||||
var withLength []string
|
||||
for _, col := range columns {
|
||||
if col == "ip" || col == "dns_label" {
|
||||
withLength = append(withLength, fmt.Sprintf("%s(64)", col))
|
||||
quotedCol := fmt.Sprintf("`%s`", col)
|
||||
if col == "ip" || col == "dns_label" || col == "key" {
|
||||
withLength = append(withLength, fmt.Sprintf("%s(64)", quotedCol))
|
||||
} else {
|
||||
withLength = append(withLength, col)
|
||||
withLength = append(withLength, quotedCol)
|
||||
}
|
||||
}
|
||||
columnClause = strings.Join(withLength, ", ")
|
||||
@@ -488,6 +489,57 @@ func MigrateJsonToTable[T any](ctx context.Context, db *gorm.DB, columnName stri
|
||||
return nil
|
||||
}
|
||||
|
||||
func RemoveDuplicatePeerKeys(ctx context.Context, db *gorm.DB) error {
|
||||
if !db.Migrator().HasTable("peers") {
|
||||
log.WithContext(ctx).Debug("peers table does not exist, skipping duplicate key cleanup")
|
||||
return nil
|
||||
}
|
||||
|
||||
keyColumn := GetColumnName(db, "key")
|
||||
|
||||
var duplicates []struct {
|
||||
Key string
|
||||
Count int64
|
||||
}
|
||||
|
||||
if err := db.Table("peers").
|
||||
Select(keyColumn + ", COUNT(*) as count").
|
||||
Group(keyColumn).
|
||||
Having("COUNT(*) > 1").
|
||||
Find(&duplicates).Error; err != nil {
|
||||
return fmt.Errorf("find duplicate keys: %w", err)
|
||||
}
|
||||
|
||||
if len(duplicates) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
log.WithContext(ctx).Warnf("Found %d duplicate peer keys, cleaning up", len(duplicates))
|
||||
|
||||
for _, dup := range duplicates {
|
||||
var peerIDs []string
|
||||
if err := db.Table("peers").
|
||||
Select("id").
|
||||
Where(keyColumn+" = ?", dup.Key).
|
||||
Order("peer_status_last_seen DESC").
|
||||
Pluck("id", &peerIDs).Error; err != nil {
|
||||
return fmt.Errorf("get peers for key: %w", err)
|
||||
}
|
||||
|
||||
if len(peerIDs) <= 1 {
|
||||
continue
|
||||
}
|
||||
|
||||
idsToDelete := peerIDs[1:]
|
||||
|
||||
if err := db.Table("peers").Where("id IN ?", idsToDelete).Delete(nil).Error; err != nil {
|
||||
return fmt.Errorf("delete duplicate peers: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CleanupOrphanedIDs removes non-existent IDs from the JSON array column.
|
||||
// T is the type of the model that contains the list.
|
||||
// This migration cleans up the lists field by removing IDs that no longer exist in the target table.
|
||||
|
||||
Reference in New Issue
Block a user