Skip to content

Commit 48ee80a

Browse files
authored
fix(cli): prevent sqlDB leaks in ConnectToPostgres (#10072)
1 parent 5d5a7da commit 48ee80a

File tree

1 file changed

+21
-18
lines changed

1 file changed

+21
-18
lines changed

cli/server.go

+21-18
Original file line numberDiff line numberDiff line change
@@ -1875,45 +1875,49 @@ func BuildLogger(inv *clibase.Invocation, cfg *codersdk.DeploymentValues) (slog.
18751875
}, nil
18761876
}
18771877

1878-
func ConnectToPostgres(ctx context.Context, logger slog.Logger, driver string, dbURL string) (*sql.DB, error) {
1878+
func ConnectToPostgres(ctx context.Context, logger slog.Logger, driver string, dbURL string) (sqlDB *sql.DB, err error) {
18791879
logger.Debug(ctx, "connecting to postgresql")
18801880

18811881
// Try to connect for 30 seconds.
18821882
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
18831883
defer cancel()
18841884

1885-
var (
1886-
sqlDB *sql.DB
1887-
err error
1888-
ok = false
1889-
tries int
1890-
)
1885+
defer func() {
1886+
if err == nil {
1887+
return
1888+
}
1889+
if sqlDB != nil {
1890+
_ = sqlDB.Close()
1891+
sqlDB = nil
1892+
}
1893+
logger.Error(ctx, "connect to postgres failed", slog.Error(err))
1894+
}()
1895+
1896+
var tries int
18911897
for r := retry.New(time.Second, 3*time.Second); r.Wait(ctx); {
18921898
tries++
18931899

18941900
sqlDB, err = sql.Open(driver, dbURL)
18951901
if err != nil {
1896-
logger.Warn(ctx, "connect to postgres; retrying", slog.Error(err), slog.F("try", tries))
1902+
logger.Warn(ctx, "connect to postgres: retrying", slog.Error(err), slog.F("try", tries))
18971903
continue
18981904
}
18991905

19001906
err = pingPostgres(ctx, sqlDB)
19011907
if err != nil {
1902-
logger.Warn(ctx, "ping postgres; retrying", slog.Error(err), slog.F("try", tries))
1908+
logger.Warn(ctx, "ping postgres: retrying", slog.Error(err), slog.F("try", tries))
1909+
_ = sqlDB.Close()
1910+
sqlDB = nil
19031911
continue
19041912
}
19051913

19061914
break
19071915
}
1908-
// Make sure we close the DB in case it opened but the ping failed for some
1909-
// reason.
1910-
defer func() {
1911-
if !ok && sqlDB != nil {
1912-
_ = sqlDB.Close()
1913-
}
1914-
}()
1916+
if err == nil {
1917+
err = ctx.Err()
1918+
}
19151919
if err != nil {
1916-
return nil, xerrors.Errorf("connect to postgres; tries %d; last error: %w", tries, err)
1920+
return nil, xerrors.Errorf("unable to connect after %d tries; last error: %w", tries, err)
19171921
}
19181922

19191923
// Ensure the PostgreSQL version is >=13.0.0!
@@ -1958,7 +1962,6 @@ func ConnectToPostgres(ctx context.Context, logger slog.Logger, driver string, d
19581962
// of connection churn.
19591963
sqlDB.SetMaxIdleConns(3)
19601964

1961-
ok = true
19621965
return sqlDB, nil
19631966
}
19641967

0 commit comments

Comments
 (0)