mirror of
https://github.com/juanfont/headscale.git
synced 2026-10-27 00:36: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,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 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
|
||||
// connection pool as of 2022/02/23.
|
||||
sqlDB, _ := db.DB()
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sqlDB.SetMaxIdleConns(1)
|
||||
sqlDB.SetMaxOpenConns(1)
|
||||
sqlDB.SetConnMaxIdleTime(time.Hour)
|
||||
|
||||
return db, err
|
||||
return db, nil
|
||||
|
||||
case types.DatabasePostgres:
|
||||
dbString := fmt.Sprintf(
|
||||
@@ -493,7 +500,11 @@ func openDB(cfg types.DatabaseConfig) (*gorm.DB, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sqlDB, _ := db.DB()
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sqlDB.SetMaxIdleConns(cfg.Postgres.MaxIdleConnections)
|
||||
sqlDB.SetMaxOpenConns(cfg.Postgres.MaxOpenConnections)
|
||||
sqlDB.SetConnMaxIdleTime(
|
||||
|
||||
@@ -910,3 +910,54 @@ func TestInterruptedInitSchemaRecovers(t *testing.T) {
|
||||
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