(ctx context.Context, logger slog.Logger, cfg *devConfig, pgURL *string)
| 541 | } |
| 542 | |
| 543 | func startTempPostgresSetURL(ctx context.Context, logger slog.Logger, cfg *devConfig, pgURL *string) (func(), error) { |
| 544 | pgDir := filepath.Join(cfg.configDir, "postgres") |
| 545 | cleanStalePIDFile(filepath.Join(pgDir, "data")) |
| 546 | |
| 547 | passwordBytes, err := os.ReadFile(filepath.Join(pgDir, "password")) |
| 548 | if err != nil { |
| 549 | return nil, xerrors.Errorf("read postgres password: %w", err) |
| 550 | } |
| 551 | password := strings.TrimSpace(string(passwordBytes)) |
| 552 | |
| 553 | listener, err := net.Listen("tcp4", "127.0.0.1:0") |
| 554 | if err != nil { |
| 555 | return nil, xerrors.Errorf("find ephemeral port: %w", err) |
| 556 | } |
| 557 | tcpAddr, ok := listener.Addr().(*net.TCPAddr) |
| 558 | if !ok { |
| 559 | return nil, xerrors.New("listener returned non-TCP addr") |
| 560 | } |
| 561 | port := tcpAddr.Port |
| 562 | _ = listener.Close() |
| 563 | |
| 564 | ep := embeddedpostgres.NewDatabase( |
| 565 | embeddedpostgres.DefaultConfig(). |
| 566 | Version(embeddedpostgres.V13). |
| 567 | BinariesPath(filepath.Join(pgDir, "bin")). |
| 568 | CachePath(filepath.Join(pgDir, "cache")). |
| 569 | DataPath(filepath.Join(pgDir, "data")). |
| 570 | RuntimePath(filepath.Join(pgDir, "runtime")). |
| 571 | Port(uint32(port)). //nolint:gosec // port from listener, fits uint32. |
| 572 | Username("coder"). |
| 573 | Password(password). |
| 574 | Database("coder"). |
| 575 | Logger(nil), |
| 576 | ) |
| 577 | |
| 578 | logger.Info(ctx, "starting temporary postgres for migration check", |
| 579 | slog.F("port", port)) |
| 580 | if err := ep.Start(); err != nil { |
| 581 | return nil, xerrors.Errorf("start embedded postgres: %w", err) |
| 582 | } |
| 583 | |
| 584 | *pgURL = fmt.Sprintf( |
| 585 | "postgres://coder@localhost:%d/coder?sslmode=disable&password=%s", |
| 586 | port, url.QueryEscape(password)) |
| 587 | |
| 588 | return func() { |
| 589 | if err := ep.Stop(); err != nil { |
| 590 | logger.Warn(ctx, "failed to stop temporary postgres", |
| 591 | slog.Error(err)) |
| 592 | } |
| 593 | }, nil |
| 594 | } |
| 595 | |
| 596 | func cleanStalePIDFile(dataDir string) { |
| 597 | pidPath := filepath.Join(dataDir, "postmaster.pid") |
no test coverage detected