mirror of
https://github.com/juanfont/headscale.git
synced 2026-10-27 08:46:49 +09:00
db: check errors in openDB
On the SQLite path openDB called db.DB() and configured the pool before looking at the error from gorm.Open, and both backends discarded the error from db.DB(). A failed open returned a half-initialised *gorm.DB alongside the error, and a nil *sql.DB from db.DB() would have been dereferenced. Return early on either error so callers get a nil handle and the original error.
This commit is contained in:
1 parent
7414c276f6
commit
8d65201a93
2 files changed
+65
-3
No files matched your search
+14
-3
@@ -446,16 +446,23 @@ func openDB(cfg types.DatabaseConfig) (*gorm.DB, error) {
|
|||||||
Logger: dbLogger,
|
Logger: dbLogger,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// The pure Go SQLite library does not handle locking in
|
// The pure Go SQLite library does not handle locking in
|
||||||
// the same way as the C based one and we can't use the gorm
|
// the same way as the C based one and we can't use the gorm
|
||||||
// connection pool as of 2022/02/23.
|
// connection pool as of 2022/02/23.
|
||||||
sqlDB, _ := db.DB()
|
sqlDB, err := db.DB()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
sqlDB.SetMaxIdleConns(1)
|
sqlDB.SetMaxIdleConns(1)
|
||||||
sqlDB.SetMaxOpenConns(1)
|
sqlDB.SetMaxOpenConns(1)
|
||||||
sqlDB.SetConnMaxIdleTime(time.Hour)
|
sqlDB.SetConnMaxIdleTime(time.Hour)
|
||||||
|
|
||||||
return db, err
|
return db, nil
|
||||||
|
|
||||||
case types.DatabasePostgres:
|
case types.DatabasePostgres:
|
||||||
dbString := fmt.Sprintf(
|
dbString := fmt.Sprintf(
|
||||||
@@ -493,7 +500,11 @@ func openDB(cfg types.DatabaseConfig) (*gorm.DB, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlDB, _ := db.DB()
|
sqlDB, err := db.DB()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
sqlDB.SetMaxIdleConns(cfg.Postgres.MaxIdleConnections)
|
sqlDB.SetMaxIdleConns(cfg.Postgres.MaxIdleConnections)
|
||||||
sqlDB.SetMaxOpenConns(cfg.Postgres.MaxOpenConnections)
|
sqlDB.SetMaxOpenConns(cfg.Postgres.MaxOpenConnections)
|
||||||
sqlDB.SetConnMaxIdleTime(
|
sqlDB.SetConnMaxIdleTime(
|
||||||
|
|||||||
@@ -910,3 +910,54 @@ func TestInterruptedInitSchemaRecovers(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOpenDBReturnsOpenError(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
cfg func(t *testing.T) types.DatabaseConfig
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "sqlite-path-is-a-directory",
|
||||||
|
cfg: func(t *testing.T) types.DatabaseConfig {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
return types.DatabaseConfig{
|
||||||
|
Type: types.DatabaseSqlite,
|
||||||
|
Sqlite: types.SqliteConfig{Path: t.TempDir()},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "postgres-unreachable-host",
|
||||||
|
cfg: func(t *testing.T) types.DatabaseConfig {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
return types.DatabaseConfig{
|
||||||
|
Type: types.DatabasePostgres,
|
||||||
|
Postgres: types.PostgresConfig{
|
||||||
|
Host: "127.0.0.1",
|
||||||
|
Port: 1,
|
||||||
|
Name: "headscale",
|
||||||
|
User: "headscale",
|
||||||
|
Ssl: "false",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
var (
|
||||||
|
db *gorm.DB
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
require.NotPanics(t, func() {
|
||||||
|
db, err = openDB(tt.cfg(t))
|
||||||
|
})
|
||||||
|
require.Error(t, err)
|
||||||
|
assert.Nil(t, db)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user