2b37986218
Small Go tool + distroless container used as a K8s initContainer to block an app until its database (Postgres/MySQL) is reachable. Env-var configured (WAITFORDB_* + libpq PG* fallback), configurable timeout/interval, redacted logs, exit codes. Woodpecker CI publishes docker-internal/waitfordb on tag.
49 lines
1.2 KiB
Go
49 lines
1.2 KiB
Go
package driver
|
|
|
|
import (
|
|
"fmt"
|
|
"net/url"
|
|
"strconv"
|
|
|
|
"git.unkin.net/unkin/waitfordb/internal/config"
|
|
_ "github.com/jackc/pgx/v5/stdlib" // registers the "pgx" database/sql driver
|
|
)
|
|
|
|
func init() { register(postgres{}) }
|
|
|
|
type postgres struct{}
|
|
|
|
func (postgres) Name() string { return "postgres" }
|
|
|
|
func (postgres) Open(cfg config.Config) (Pinger, error) {
|
|
dsn := cfg.DSN
|
|
if dsn == "" {
|
|
dsn = postgresDSN(cfg)
|
|
}
|
|
return openSQL("pgx", dsn)
|
|
}
|
|
|
|
// postgresDSN builds a URL-style DSN. net/url escapes the userinfo and query so
|
|
// passwords with special characters are handled safely.
|
|
func postgresDSN(cfg config.Config) string {
|
|
u := url.URL{
|
|
Scheme: "postgres",
|
|
Host: fmt.Sprintf("%s:%s", cfg.Host, cfg.Port),
|
|
Path: "/" + cfg.Database,
|
|
}
|
|
if cfg.User != "" {
|
|
u.User = url.UserPassword(cfg.User, cfg.Password)
|
|
}
|
|
q := url.Values{}
|
|
if cfg.SSLMode != "" {
|
|
q.Set("sslmode", cfg.SSLMode)
|
|
}
|
|
// connect_timeout is a per-attempt safety net in addition to the context
|
|
// deadline the wait loop applies; it is in whole seconds.
|
|
if secs := int(cfg.ConnectTimeout.Seconds()); secs > 0 {
|
|
q.Set("connect_timeout", strconv.Itoa(secs))
|
|
}
|
|
u.RawQuery = q.Encode()
|
|
return u.String()
|
|
}
|