fix: stabilize development config and account settings
This commit is contained in:
@@ -3,6 +3,7 @@ package database
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/golang-migrate/migrate/v4"
|
||||
_ "github.com/golang-migrate/migrate/v4/database/postgres"
|
||||
@@ -10,6 +11,17 @@ import (
|
||||
_ "github.com/golang-migrate/migrate/v4/source/file"
|
||||
)
|
||||
|
||||
var unsupportedPQEnvironmentKeys = []string{"PGSERVICE", "PGSERVICEFILE", "PGREALM"}
|
||||
|
||||
// SanitizePostgresEnvironment removes libpq service-file settings that are
|
||||
// incompatible with GoChat's explicit database configuration and can make
|
||||
// both pgx and lib/pq ignore or reject the configured host/user/database.
|
||||
func SanitizePostgresEnvironment() {
|
||||
for _, key := range unsupportedPQEnvironmentKeys {
|
||||
_ = os.Unsetenv(key)
|
||||
}
|
||||
}
|
||||
|
||||
// RunMigrations applies all pending database migrations from the given path.
|
||||
// dbURL should be a database connection string (PostgreSQL or SQLite).
|
||||
// migrationsPath should be a file path to the migrations directory (e.g. "migrations").
|
||||
@@ -20,6 +32,12 @@ import (
|
||||
// - A migration fails to apply
|
||||
// - The database is in a dirty state (a previous migration partially failed)
|
||||
func RunMigrations(dbURL string, migrationsPath string) error {
|
||||
return withSanitizedPQEnvironment(func() error {
|
||||
return runMigrations(dbURL, migrationsPath)
|
||||
})
|
||||
}
|
||||
|
||||
func runMigrations(dbURL string, migrationsPath string) error {
|
||||
m, err := migrate.New(
|
||||
fmt.Sprintf("file://%s", migrationsPath),
|
||||
dbURL,
|
||||
@@ -45,6 +63,36 @@ func RunMigrations(dbURL string, migrationsPath string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// withSanitizedPQEnvironment prevents lib/pq from panicking when PostgreSQL
|
||||
// service-file variables are inherited from the user's shell. GoChat passes a
|
||||
// complete connection URL to golang-migrate, and lib/pq does not support these
|
||||
// libpq service variables. Restore them after the migration operation so this
|
||||
// workaround remains scoped to the legacy migration driver.
|
||||
func withSanitizedPQEnvironment(fn func() error) error {
|
||||
type savedValue struct {
|
||||
value string
|
||||
set bool
|
||||
}
|
||||
saved := make(map[string]savedValue, len(unsupportedPQEnvironmentKeys))
|
||||
for _, key := range unsupportedPQEnvironmentKeys {
|
||||
value, set := os.LookupEnv(key)
|
||||
saved[key] = savedValue{value: value, set: set}
|
||||
_ = os.Unsetenv(key)
|
||||
}
|
||||
defer func() {
|
||||
for _, key := range unsupportedPQEnvironmentKeys {
|
||||
previous := saved[key]
|
||||
if previous.set {
|
||||
_ = os.Setenv(key, previous.value)
|
||||
} else {
|
||||
_ = os.Unsetenv(key)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return fn()
|
||||
}
|
||||
|
||||
// MigrateSteps applies N migration steps (positive = up, negative = down).
|
||||
func MigrateSteps(dbURL string, migrationsPath string, steps int) error {
|
||||
m, err := migrate.New(
|
||||
@@ -128,4 +176,4 @@ func CurrentVersion(dbURL string, migrationsPath string) (uint, bool, error) {
|
||||
}
|
||||
|
||||
return version, dirty, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestWithSanitizedPQEnvironment(t *testing.T) {
|
||||
t.Setenv("PGSERVICE", "local-service")
|
||||
t.Setenv("PGSERVICEFILE", "/tmp/pg_service.conf")
|
||||
t.Setenv("PGREALM", "local-realm")
|
||||
|
||||
err := withSanitizedPQEnvironment(func() error {
|
||||
for _, key := range []string{"PGSERVICE", "PGSERVICEFILE", "PGREALM"} {
|
||||
_, exists := os.LookupEnv(key)
|
||||
require.False(t, exists, "%s should be unset during migration", key)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "local-service", os.Getenv("PGSERVICE"))
|
||||
require.Equal(t, "/tmp/pg_service.conf", os.Getenv("PGSERVICEFILE"))
|
||||
require.Equal(t, "local-realm", os.Getenv("PGREALM"))
|
||||
}
|
||||
|
||||
func TestSanitizePostgresEnvironment(t *testing.T) {
|
||||
t.Setenv("PGSERVICE", "local-service")
|
||||
t.Setenv("PGSERVICEFILE", "/tmp/pg_service.conf")
|
||||
t.Setenv("PGREALM", "local-realm")
|
||||
|
||||
SanitizePostgresEnvironment()
|
||||
|
||||
for _, key := range unsupportedPQEnvironmentKeys {
|
||||
_, exists := os.LookupEnv(key)
|
||||
require.False(t, exists, "%s should be removed at application startup", key)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user