From b4ac8cd9a3e5ab4597d90246b41c56c9c6638775 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 7 Feb 2025 10:22:23 +0100 Subject: [PATCH] hscontrol/db: add migration setting non existing pak on nodes to null (#2412) Signed-off-by: Kristoffer Dalby --- hscontrol/db/db.go | 32 +++++++++++++++--- hscontrol/db/db_test.go | 20 +++++++++++ .../failing-node-preauth-constraint.sqlite | Bin 0 -> 65536 bytes 3 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 hscontrol/db/testdata/failing-node-preauth-constraint.sqlite diff --git a/hscontrol/db/db.go b/hscontrol/db/db.go index 591c1c92..7f4ecb32 100644 --- a/hscontrol/db/db.go +++ b/hscontrol/db/db.go @@ -512,7 +512,7 @@ COMMIT; err := tx.AutoMigrate(&types.User{}) if err != nil { - return err + return fmt.Errorf("automigrating types.User: %w", err) } return nil @@ -527,7 +527,7 @@ COMMIT; Migrate: func(tx *gorm.DB) error { err := tx.AutoMigrate(&types.User{}) if err != nil { - return err + return fmt.Errorf("automigrating types.User: %w", err) } // Set up indexes and unique constraints outside of GORM, it does not support @@ -575,7 +575,7 @@ COMMIT; err := tx.AutoMigrate(&types.Route{}) if err != nil { - return err + return fmt.Errorf("automigrating types.Route: %w", err) } return nil @@ -589,11 +589,33 @@ COMMIT; Migrate: func(tx *gorm.DB) error { err := tx.AutoMigrate(&types.PreAuthKey{}) if err != nil { - return err + return fmt.Errorf("automigrating types.PreAuthKey: %w", err) } err = tx.AutoMigrate(&types.Node{}) if err != nil { - return err + return fmt.Errorf("automigrating types.Node: %w", err) + } + + return nil + }, + Rollback: func(db *gorm.DB) error { return nil }, + }, + // Ensure there are no nodes refering to a deleted preauthkey. + { + ID: "202502070949", + Migrate: func(tx *gorm.DB) error { + if tx.Migrator().HasTable(&types.PreAuthKey{}) { + err := tx.Exec(` +UPDATE nodes +SET auth_key_id = NULL +WHERE auth_key_id IS NOT NULL +AND auth_key_id NOT IN ( + SELECT id FROM pre_auth_keys +); + `).Error + if err != nil { + return fmt.Errorf("setting auth_key to null on nodes with non-existing keys: %w", err) + } } return nil diff --git a/hscontrol/db/db_test.go b/hscontrol/db/db_test.go index 8ca77303..079f632f 100644 --- a/hscontrol/db/db_test.go +++ b/hscontrol/db/db_test.go @@ -201,6 +201,26 @@ func TestMigrationsSQLite(t *testing.T) { } }, }, + { + dbPath: "testdata/failing-node-preauth-constraint.sqlite", + wantFunc: func(t *testing.T, h *HSDatabase) { + nodes, err := Read(h.DB, func(rx *gorm.DB) (types.Nodes, error) { + return ListNodes(rx) + }) + require.NoError(t, err) + + for _, node := range nodes { + assert.Falsef(t, node.MachineKey.IsZero(), "expected non zero machinekey") + assert.Contains(t, node.MachineKey.String(), "mkey:") + assert.Falsef(t, node.NodeKey.IsZero(), "expected non zero nodekey") + assert.Contains(t, node.NodeKey.String(), "nodekey:") + assert.Falsef(t, node.DiscoKey.IsZero(), "expected non zero discokey") + assert.Contains(t, node.DiscoKey.String(), "discokey:") + assert.Nil(t, node.AuthKey) + assert.Nil(t, node.AuthKeyID) + } + }, + }, } for _, tt := range tests { diff --git a/hscontrol/db/testdata/failing-node-preauth-constraint.sqlite b/hscontrol/db/testdata/failing-node-preauth-constraint.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..911c243461e93af35070ac5fb8c0208891a175ee GIT binary patch literal 65536 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 literal 0 HcmV?d00001