multi: ensure kvdb -> SQL mig uses correct db folders

The kvdb accounts db is specifically set to be created in the same
folder as the macaroon path, while the sessions and rules db are created
in the network folder.

That means that users which have set a custom macaroon path, can have
an accounts db in a separate folder than the sessions and rules db.
In order to ensure that the migration from kvdb to SQL uses the correct
db folders, we need to make sure that the migration code uses the same
logic as the creation of the db logic.
This commit is contained in:
Viktor Torstensson 2026-06-02 00:02:33 +02:00
parent 93f6aa9e2c
commit d1cc192434
No known key found for this signature in database
GPG key ID: 961CC8259AE675D4
4 changed files with 30 additions and 22 deletions

View file

@ -6,7 +6,6 @@ import (
"encoding/binary"
"errors"
"fmt"
"path/filepath"
"time"
"github.com/golang-migrate/migrate/v4"
@ -24,7 +23,7 @@ import (
// entry containing the kvdb to SQL migration for all of litd's database stores.
func Mig6ProgrammaticMigration(ctx context.Context,
basicClient lnrpc.LightningClient, db *sqldb.BaseDB,
macPath string, clock clock.Clock,
accountsDir, networkDir string, clock clock.Clock,
migVersion uint) migrate.ProgrammaticMigrEntry {
mig6queries := sqlcmig6.NewForType(db, db.BackendType)
@ -46,8 +45,8 @@ func Mig6ProgrammaticMigration(ctx context.Context,
"for migration version %d", migVersion)
return kvdbToSqlProgrammaticMigration(
ctx, basicClient, macPath, db, clock,
q6,
ctx, basicClient, accountsDir,
networkDir, db, clock, q6,
)
}, sqldb.NoOpReset,
)
@ -66,7 +65,7 @@ func Mig6ProgrammaticMigration(ctx context.Context,
// We still want the failure to be highly visible because the
// legacy bbolt files were not tombstoned and may therefore
// still be opened unexpectedly.
err = deprecateKVDBStores(filepath.Dir(macPath))
err = deprecateKVDBStores(accountsDir, networkDir)
if err != nil {
log.Errorf("CRITICAL: kvdb -> SQL migration "+
"succeeded, but the legacy bbolt databases "+
@ -85,14 +84,14 @@ func Mig6ProgrammaticMigration(ctx context.Context,
}
func kvdbToSqlProgrammaticMigration(ctx context.Context,
basicClient lnrpc.LightningClient, macPath string, _ *sqldb.BaseDB,
clock clock.Clock, q *sqlcmig6.Queries) error {
basicClient lnrpc.LightningClient, accountsDir, networkDir string,
_ *sqldb.BaseDB, clock clock.Clock, q *sqlcmig6.Queries) error {
start := time.Now()
log.Infof("Starting KVDB to SQL migration for all stores")
accountStore, err := accounts.NewBoltStoreForMigration(
filepath.Dir(macPath), accounts.DBFilename, clock,
accountsDir, accounts.DBFilename, clock,
)
if err != nil {
return err
@ -113,7 +112,7 @@ func kvdbToSqlProgrammaticMigration(ctx context.Context,
}
sessionStore, err := session.NewDBForMigration(
filepath.Dir(macPath), session.DBFilename,
networkDir, session.DBFilename,
clock, accountStore,
)
if err != nil {
@ -135,7 +134,7 @@ func kvdbToSqlProgrammaticMigration(ctx context.Context,
}
firewallStore, err := firewalldb.NewBoltDBForMigration(
filepath.Dir(macPath), firewalldb.DBFilename,
networkDir, firewalldb.DBFilename,
sessionStore, accountStore, clock,
)
if err != nil {
@ -218,20 +217,20 @@ func kvdbToSqlProgrammaticMigration(ctx context.Context,
// migration committed successfully. We do this after the SQL transaction is
// committed so a failed SQL migration cannot strand the user with an unusable
// kvdb backend.
func deprecateKVDBStores(dbDir string) error {
accountsErr := accounts.DeprecateKVDB(dbDir)
func deprecateKVDBStores(accountsDir, networkDir string) error {
accountsErr := accounts.DeprecateKVDB(accountsDir)
if accountsErr != nil {
accountsErr = fmt.Errorf("error deprecating accounts kvdb: %w",
accountsErr)
}
sessionErr := session.DeprecateKVDB(dbDir)
sessionErr := session.DeprecateKVDB(networkDir)
if sessionErr != nil {
sessionErr = fmt.Errorf("error deprecating session kvdb: %w",
sessionErr)
}
firewallErr := firewalldb.DeprecateKVDB(dbDir)
firewallErr := firewalldb.DeprecateKVDB(networkDir)
if firewallErr != nil {
firewallErr = fmt.Errorf("error deprecating firewall kvdb: %w",
firewallErr)

View file

@ -4,6 +4,7 @@ package migsets
import (
"context"
"path/filepath"
"github.com/golang-migrate/migrate/v4"
"github.com/golang-migrate/migrate/v4/database/pgx/v5"
@ -15,7 +16,11 @@ import (
// MakeMigrationSets creates the migration sets for production environments.
func MakeMigrationSets(ctx context.Context, basicClient lnrpc.LightningClient,
macPath string, clock clock.Clock) []sqldb.MigrationSet {
macPath, litDir, network string,
clock clock.Clock) []sqldb.MigrationSet {
accountsDir := filepath.Dir(macPath)
networkDir := filepath.Join(litDir, network)
// migSet defines the SQL migration set used to create and upgrade LiT's
// SQL schema.
@ -42,8 +47,8 @@ func MakeMigrationSets(ctx context.Context, basicClient lnrpc.LightningClient,
res := make(map[uint]migrate.ProgrammaticMigrEntry)
res[db.KVDBtoSQLMigVersion] = Mig6ProgrammaticMigration(
ctx, basicClient, baseDB, macPath, clock,
db.KVDBtoSQLMigVersion,
ctx, basicClient, baseDB, accountsDir,
networkDir, clock, db.KVDBtoSQLMigVersion,
)
return res, nil

View file

@ -4,6 +4,7 @@ package migsets
import (
"context"
"path/filepath"
"github.com/golang-migrate/migrate/v4"
"github.com/golang-migrate/migrate/v4/database/pgx/v5"
@ -15,9 +16,12 @@ import (
// MakeMigrationSets creates the migration sets for the dev environments.
func MakeMigrationSets(ctx context.Context,
basicClient lnrpc.LightningClient, macPath string,
basicClient lnrpc.LightningClient, macPath, litDir, network string,
clock clock.Clock) []sqldb.MigrationSet {
accountsDir := filepath.Dir(macPath)
networkDir := filepath.Join(litDir, network)
// Create the prod migration set.
migSet := sqldb.MigrationSet{
TrackingTableName: pgx.DefaultMigrationsTable,
@ -42,8 +46,8 @@ func MakeMigrationSets(ctx context.Context,
res := make(map[uint]migrate.ProgrammaticMigrEntry)
res[db.KVDBtoSQLMigVersion] = Mig6ProgrammaticMigration(
ctx, basicClient, baseDB, macPath, clock,
db.KVDBtoSQLMigVersion,
ctx, basicClient, baseDB, accountsDir,
networkDir, clock, db.KVDBtoSQLMigVersion,
)
return res, nil