Fix: Database listing now works with peer authentication
Issue: Interactive cluster restore preview showed 'Cannot list databases: exit status 2' when trying to detect existing databases. This happened because the safety check functions always used '-h hostname' flag with psql, which breaks peer authentication. Root cause: - listPostgresUserDatabases() and checkPostgresDatabaseExists() always included -h flag - For localhost peer auth, psql should connect via Unix socket (no -h flag) - Adding -h localhost forces TCP connection which fails with peer authentication Solution: Match the pattern used throughout the codebase: - Only add -h flag when host is NOT localhost/127.0.0.1/empty - For localhost, skip -h flag to use Unix socket - Set PGPASSWORD only if password is provided Fixed functions in internal/restore/safety.go: - listPostgresUserDatabases() - checkPostgresDatabaseExists() Now interactive mode correctly shows existing databases count and list when running as postgres user with peer authentication.
This commit is contained in:
@@ -297,16 +297,24 @@ func (s *Safety) CheckDatabaseExists(ctx context.Context, dbName string) (bool,
|
|||||||
|
|
||||||
// checkPostgresDatabaseExists checks if PostgreSQL database exists
|
// checkPostgresDatabaseExists checks if PostgreSQL database exists
|
||||||
func (s *Safety) checkPostgresDatabaseExists(ctx context.Context, dbName string) (bool, error) {
|
func (s *Safety) checkPostgresDatabaseExists(ctx context.Context, dbName string) (bool, error) {
|
||||||
cmd := exec.CommandContext(ctx,
|
args := []string{
|
||||||
"psql",
|
|
||||||
"-h", s.cfg.Host,
|
|
||||||
"-p", fmt.Sprintf("%d", s.cfg.Port),
|
"-p", fmt.Sprintf("%d", s.cfg.Port),
|
||||||
"-U", s.cfg.User,
|
"-U", s.cfg.User,
|
||||||
"-d", "postgres",
|
"-d", "postgres",
|
||||||
"-tAc", fmt.Sprintf("SELECT 1 FROM pg_database WHERE datname='%s'", dbName),
|
"-tAc", fmt.Sprintf("SELECT 1 FROM pg_database WHERE datname='%s'", dbName),
|
||||||
)
|
}
|
||||||
|
|
||||||
|
// Only add -h flag if host is not localhost (to use Unix socket for peer auth)
|
||||||
|
if s.cfg.Host != "localhost" && s.cfg.Host != "127.0.0.1" && s.cfg.Host != "" {
|
||||||
|
args = append([]string{"-h", s.cfg.Host}, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.CommandContext(ctx, "psql", args...)
|
||||||
|
|
||||||
|
// Set password if provided
|
||||||
|
if s.cfg.Password != "" {
|
||||||
cmd.Env = append(os.Environ(), fmt.Sprintf("PGPASSWORD=%s", s.cfg.Password))
|
cmd.Env = append(os.Environ(), fmt.Sprintf("PGPASSWORD=%s", s.cfg.Password))
|
||||||
|
}
|
||||||
|
|
||||||
output, err := cmd.Output()
|
output, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -354,17 +362,25 @@ func (s *Safety) listPostgresUserDatabases(ctx context.Context) ([]string, error
|
|||||||
// Query to get non-template databases excluding 'postgres' system DB
|
// Query to get non-template databases excluding 'postgres' system DB
|
||||||
query := "SELECT datname FROM pg_database WHERE datistemplate = false AND datname != 'postgres' ORDER BY datname"
|
query := "SELECT datname FROM pg_database WHERE datistemplate = false AND datname != 'postgres' ORDER BY datname"
|
||||||
|
|
||||||
cmd := exec.CommandContext(ctx,
|
args := []string{
|
||||||
"psql",
|
|
||||||
"-h", s.cfg.Host,
|
|
||||||
"-p", fmt.Sprintf("%d", s.cfg.Port),
|
"-p", fmt.Sprintf("%d", s.cfg.Port),
|
||||||
"-U", s.cfg.User,
|
"-U", s.cfg.User,
|
||||||
"-d", "postgres",
|
"-d", "postgres",
|
||||||
"-tA", // Tuples only, unaligned
|
"-tA", // Tuples only, unaligned
|
||||||
"-c", query,
|
"-c", query,
|
||||||
)
|
}
|
||||||
|
|
||||||
|
// Only add -h flag if host is not localhost (to use Unix socket for peer auth)
|
||||||
|
if s.cfg.Host != "localhost" && s.cfg.Host != "127.0.0.1" && s.cfg.Host != "" {
|
||||||
|
args = append([]string{"-h", s.cfg.Host}, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.CommandContext(ctx, "psql", args...)
|
||||||
|
|
||||||
|
// Set password if provided
|
||||||
|
if s.cfg.Password != "" {
|
||||||
cmd.Env = append(os.Environ(), fmt.Sprintf("PGPASSWORD=%s", s.cfg.Password))
|
cmd.Env = append(os.Environ(), fmt.Sprintf("PGPASSWORD=%s", s.cfg.Password))
|
||||||
|
}
|
||||||
|
|
||||||
output, err := cmd.Output()
|
output, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user