| 152 | } |
| 153 | |
| 154 | func openEmbeddedPostgres() (string, func(), error) { |
| 155 | listener, err := net.Listen("tcp4", "127.0.0.1:0") |
| 156 | if err != nil { |
| 157 | return "", nil, xerrors.Errorf("find ephemeral port: %w", err) |
| 158 | } |
| 159 | tcpAddr, ok := listener.Addr().(*net.TCPAddr) |
| 160 | if !ok { |
| 161 | _ = listener.Close() |
| 162 | return "", nil, xerrors.New("listener returned non-TCP addr") |
| 163 | } |
| 164 | port := tcpAddr.Port |
| 165 | _ = listener.Close() |
| 166 | |
| 167 | cacheRoot, err := os.UserCacheDir() |
| 168 | if err != nil { |
| 169 | cacheRoot = os.TempDir() |
| 170 | } |
| 171 | cacheDir := filepath.Join(cacheRoot, "coder", "dbdump-postgres") |
| 172 | |
| 173 | runtimeDir, err := os.MkdirTemp("", "coder-dbdump-postgres-") |
| 174 | if err != nil { |
| 175 | return "", nil, xerrors.Errorf("create runtime dir: %w", err) |
| 176 | } |
| 177 | |
| 178 | const password = "postgres" |
| 179 | ep := embeddedpostgres.NewDatabase( |
| 180 | embeddedpostgres.DefaultConfig(). |
| 181 | Version(embeddedpostgres.V13). |
| 182 | // repo1.maven.org is flaky; matches cli/server.go and scripts/embedded-pg/main.go. |
| 183 | BinaryRepositoryURL("https://repo.maven.apache.org/maven2"). |
| 184 | BinariesPath(filepath.Join(cacheDir, "bin")). |
| 185 | CachePath(filepath.Join(cacheDir, "cache")). |
| 186 | DataPath(filepath.Join(runtimeDir, "data")). |
| 187 | RuntimePath(filepath.Join(runtimeDir, "runtime")). |
| 188 | Port(uint32(port)). //nolint:gosec // port from listener, fits uint32. |
| 189 | Username("postgres"). |
| 190 | Password(password). |
| 191 | Database("postgres"). |
| 192 | // Postgres canonicalizes timestamptz DEFAULT expressions at |
| 193 | // parse time using the server timezone GUC, then stores the |
| 194 | // canonical form in pg_attrdef. Without UTC, the host's TZ |
| 195 | // leaks into dump.sql as values like '0001-12-31 23:06:32+00 BC'. |
| 196 | StartParameters(map[string]string{"timezone": "UTC"}). |
| 197 | Logger(nil), |
| 198 | ) |
| 199 | |
| 200 | _, _ = fmt.Fprintln(os.Stderr, "starting embedded postgres (first run may download binaries)...") |
| 201 | if err := ep.Start(); err != nil { |
| 202 | _ = os.RemoveAll(runtimeDir) |
| 203 | return "", nil, xerrors.Errorf("start embedded postgres: %w", err) |
| 204 | } |
| 205 | |
| 206 | dsn := dbtestutil.ConnectionParams{ |
| 207 | Username: "postgres", |
| 208 | Password: password, |
| 209 | Host: "127.0.0.1", |
| 210 | Port: strconv.Itoa(port), |
| 211 | DBName: "postgres", |