| 108 | } |
| 109 | |
| 110 | func (c *cleaner) init(ctx context.Context) error { |
| 111 | var err error |
| 112 | dsn := os.Getenv(envCleanerDSN) |
| 113 | if dsn == "" { |
| 114 | return xerrors.Errorf("DSN not set via env %s: %w", envCleanerDSN, err) |
| 115 | } |
| 116 | parentUUIDStr := os.Getenv(envCleanerParentUUID) |
| 117 | c.parentUUID, err = uuid.Parse(parentUUIDStr) |
| 118 | if err != nil { |
| 119 | return xerrors.Errorf("failed to parse parent UUID '%s': %w", parentUUIDStr, err) |
| 120 | } |
| 121 | c.logger = slog.Make(sloghuman.Sink(os.Stderr)). |
| 122 | Named("dbtestcleaner"). |
| 123 | Leveled(slog.LevelDebug). |
| 124 | With(slog.F("parent_uuid", parentUUIDStr)) |
| 125 | |
| 126 | c.db, err = sql.Open("postgres", dsn) |
| 127 | if err != nil { |
| 128 | return xerrors.Errorf("couldn't open DB: %w", err) |
| 129 | } |
| 130 | for r := retry.New(10*time.Millisecond, 500*time.Millisecond); r.Wait(ctx); { |
| 131 | err = c.db.PingContext(ctx) |
| 132 | if err == nil { |
| 133 | return nil |
| 134 | } |
| 135 | c.logger.Error(ctx, "failed to ping DB", slog.Error(err)) |
| 136 | } |
| 137 | return ctx.Err() |
| 138 | } |
| 139 | |
| 140 | // waitAndClean waits for stdin to close then attempts to clean up any test databases with our parent's UUID. This |
| 141 | // is best-effort. If we hit an error we exit. |