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
|
||||
func (s *Safety) checkPostgresDatabaseExists(ctx context.Context, dbName string) (bool, error) {
|
||||
cmd := exec.CommandContext(ctx,
|
||||
"psql",
|
||||
"-h", s.cfg.Host,
|
||||
args := []string{
|
||||
"-p", fmt.Sprintf("%d", s.cfg.Port),
|
||||
"-U", s.cfg.User,
|
||||
"-d", "postgres",
|
||||
"-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))
|
||||
}
|
||||
|
||||
output, err := cmd.Output()
|
||||
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 := "SELECT datname FROM pg_database WHERE datistemplate = false AND datname != 'postgres' ORDER BY datname"
|
||||
|
||||
cmd := exec.CommandContext(ctx,
|
||||
"psql",
|
||||
"-h", s.cfg.Host,
|
||||
args := []string{
|
||||
"-p", fmt.Sprintf("%d", s.cfg.Port),
|
||||
"-U", s.cfg.User,
|
||||
"-d", "postgres",
|
||||
"-tA", // Tuples only, unaligned
|
||||
"-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))
|
||||
}
|
||||
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user