mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-26 20:26:39 +00:00
Implement SQLite Store using gorm and relational approach (#1065)
Restructure data handling for improved performance and flexibility. Introduce 'G'-prefixed fields to represent Gorm relations, simplifying resource management. Eliminate complexity in lookup tables for enhanced query and write speed. Enable independent operations on data structures, requiring adjustments in the Store interface and Account Manager.
This commit is contained in:
@@ -126,7 +126,7 @@ var (
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
store, err := server.NewFileStore(config.Datadir, appMetrics)
|
||||
store, err := server.NewStore(config.StoreKind, config.Datadir, appMetrics)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed creating Store: %s: %v", config.Datadir, err)
|
||||
}
|
||||
|
||||
66
management/cmd/migration_down.go
Normal file
66
management/cmd/migration_down.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server"
|
||||
"github.com/netbirdio/netbird/util"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var shortDown = "Rollback SQLite store to JSON file store. Please make a backup of the SQLite file before running this command."
|
||||
|
||||
var downCmd = &cobra.Command{
|
||||
Use: "downgrade [--datadir directory] [--log-file console]",
|
||||
Aliases: []string{"down"},
|
||||
Short: shortDown,
|
||||
Long: shortDown +
|
||||
"\n\n" +
|
||||
"This command reads the content of {datadir}/store.db and migrates it to {datadir}/store.json that can be used by File store driver.",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
flag.Parse()
|
||||
err := util.InitLog(logLevel, logFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed initializing log %v", err)
|
||||
}
|
||||
|
||||
sqliteStorePath := path.Join(mgmtDataDir, "store.db")
|
||||
if _, err := os.Stat(sqliteStorePath); errors.Is(err, os.ErrNotExist) {
|
||||
return fmt.Errorf("%s doesn't exist, couldn't continue the operation", sqliteStorePath)
|
||||
}
|
||||
|
||||
fileStorePath := path.Join(mgmtDataDir, "store.json")
|
||||
if _, err := os.Stat(fileStorePath); err == nil {
|
||||
return fmt.Errorf("%s already exists, couldn't continue the operation", fileStorePath)
|
||||
}
|
||||
|
||||
sqlstore, err := server.NewSqliteStore(mgmtDataDir, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed creating file store: %s: %v", mgmtDataDir, err)
|
||||
}
|
||||
|
||||
sqliteStoreAccounts := len(sqlstore.GetAllAccounts())
|
||||
log.Infof("%d account will be migrated from sqlite store %s to file store %s",
|
||||
sqliteStoreAccounts, sqliteStorePath, fileStorePath)
|
||||
|
||||
store, err := server.NewFilestoreFromSqliteStore(sqlstore, mgmtDataDir, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed creating file store: %s: %v", mgmtDataDir, err)
|
||||
}
|
||||
|
||||
fsStoreAccounts := len(store.GetAllAccounts())
|
||||
if fsStoreAccounts != sqliteStoreAccounts {
|
||||
return fmt.Errorf("failed to migrate accounts from sqlite to file[]. Expected accounts: %d, got: %d",
|
||||
sqliteStoreAccounts, fsStoreAccounts)
|
||||
}
|
||||
|
||||
log.Info("Migration finished successfully")
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
66
management/cmd/migration_up.go
Normal file
66
management/cmd/migration_up.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server"
|
||||
"github.com/netbirdio/netbird/util"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var shortUp = "Migrate JSON file store to SQLite store. Please make a backup of the JSON file before running this command."
|
||||
|
||||
var upCmd = &cobra.Command{
|
||||
Use: "upgrade [--datadir directory] [--log-file console]",
|
||||
Aliases: []string{"up"},
|
||||
Short: shortUp,
|
||||
Long: shortUp +
|
||||
"\n\n" +
|
||||
"This command reads the content of {datadir}/store.json and migrates it to {datadir}/store.db that can be used by SQLite store driver.",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
flag.Parse()
|
||||
err := util.InitLog(logLevel, logFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed initializing log %v", err)
|
||||
}
|
||||
|
||||
fileStorePath := path.Join(mgmtDataDir, "store.json")
|
||||
if _, err := os.Stat(fileStorePath); errors.Is(err, os.ErrNotExist) {
|
||||
return fmt.Errorf("%s doesn't exist, couldn't continue the operation", fileStorePath)
|
||||
}
|
||||
|
||||
sqlStorePath := path.Join(mgmtDataDir, "store.db")
|
||||
if _, err := os.Stat(sqlStorePath); err == nil {
|
||||
return fmt.Errorf("%s already exists, couldn't continue the operation", sqlStorePath)
|
||||
}
|
||||
|
||||
fstore, err := server.NewFileStore(mgmtDataDir, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed creating file store: %s: %v", mgmtDataDir, err)
|
||||
}
|
||||
|
||||
fsStoreAccounts := len(fstore.GetAllAccounts())
|
||||
log.Infof("%d account will be migrated from file store %s to sqlite store %s",
|
||||
fsStoreAccounts, fileStorePath, sqlStorePath)
|
||||
|
||||
store, err := server.NewSqliteStoreFromFileStore(fstore, mgmtDataDir, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed creating file store: %s: %v", mgmtDataDir, err)
|
||||
}
|
||||
|
||||
sqliteStoreAccounts := len(store.GetAllAccounts())
|
||||
if fsStoreAccounts != sqliteStoreAccounts {
|
||||
return fmt.Errorf("failed to migrate accounts from file to sqlite. Expected accounts: %d, got: %d",
|
||||
fsStoreAccounts, sqliteStoreAccounts)
|
||||
}
|
||||
|
||||
log.Info("Migration finished successfully")
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
@@ -34,6 +34,12 @@ var (
|
||||
SilenceUsage: true,
|
||||
}
|
||||
|
||||
migrationCmd = &cobra.Command{
|
||||
Use: "sqlite-migration",
|
||||
Short: "Contains sub-commands to perform JSON file store to SQLite store migration and rollback",
|
||||
Long: "",
|
||||
SilenceUsage: true,
|
||||
}
|
||||
// Execution control channel for stopCh signal
|
||||
stopCh chan int
|
||||
)
|
||||
@@ -63,6 +69,14 @@ func init() {
|
||||
rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "")
|
||||
rootCmd.PersistentFlags().StringVar(&logFile, "log-file", defaultLogFile, "sets Netbird log path. If console is specified the the log will be output to stdout")
|
||||
rootCmd.AddCommand(mgmtCmd)
|
||||
|
||||
migrationCmd.PersistentFlags().StringVar(&mgmtDataDir, "datadir", defaultMgmtDataDir, "server data directory location")
|
||||
migrationCmd.MarkFlagRequired("datadir") //nolint
|
||||
|
||||
migrationCmd.AddCommand(upCmd)
|
||||
migrationCmd.AddCommand(downCmd)
|
||||
|
||||
rootCmd.AddCommand(migrationCmd)
|
||||
}
|
||||
|
||||
// SetupCloseHandler handles SIGTERM signal and exits with success
|
||||
|
||||
Reference in New Issue
Block a user