@biffo/cli 0.258.1 → 0.258.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +422 -295
- package/package.json +1 -1
- package/scripts/pg-test-db.sh +79 -3
package/package.json
CHANGED
package/scripts/pg-test-db.sh
CHANGED
|
@@ -250,10 +250,28 @@ if [ "$BIFFO_PG_REAP_HOURS" -gt 0 ] 2>/dev/null && command -v docker >/dev/null
|
|
|
250
250
|
say "cannot compute a reap cutoff on this date(1); skipping container reaping"
|
|
251
251
|
else
|
|
252
252
|
_reaped=0
|
|
253
|
-
|
|
253
|
+
_considered=0
|
|
254
|
+
# TWO filters, not one literal name (#1383). The label is what containers
|
|
255
|
+
# created from here now carry; the name prefix keeps covering every one
|
|
256
|
+
# created before the label existed, which is all of them on any workstation
|
|
257
|
+
# that has run this before. `sort -u` because a container matching both
|
|
258
|
+
# filters is listed by both.
|
|
259
|
+
_reapable=$(
|
|
260
|
+
{
|
|
261
|
+
docker ps -a --filter "name=biffo-pg-test-" --format '{{.Names}}' 2>/dev/null
|
|
262
|
+
docker ps -a --filter "label=biffo.ephemeral=1" --format '{{.Names}}' 2>/dev/null
|
|
263
|
+
} | sort -u
|
|
264
|
+
)
|
|
265
|
+
# A space-separated copy, purely for the `case` membership test below. The
|
|
266
|
+
# newline-separated form cannot be tested with *" $_c "* -- the separator is
|
|
267
|
+
# a newline, so only the first and last entries would ever match, and every
|
|
268
|
+
# container this script owns would be re-reported as one it does not.
|
|
269
|
+
_reapable_flat=" $(printf '%s ' $_reapable)"
|
|
270
|
+
for _c in $_reapable; do
|
|
254
271
|
[ "$_c" = "$CONTAINER" ] && continue
|
|
255
272
|
_made=$(docker inspect -f '{{.Created}}' "$_c" 2>/dev/null | cut -c1-19)
|
|
256
273
|
[ -z "$_made" ] && continue
|
|
274
|
+
_considered=$((_considered + 1))
|
|
257
275
|
# Both are UTC ISO-8601 to the second, so a string compare IS a time
|
|
258
276
|
# compare -- no epoch conversion, and portable across date(1) flavours.
|
|
259
277
|
if awk -v a="$_made" -v b="$_reap_cutoff" 'BEGIN { exit !(a < b) }'; then
|
|
@@ -261,7 +279,60 @@ if [ "$BIFFO_PG_REAP_HOURS" -gt 0 ] 2>/dev/null && command -v docker >/dev/null
|
|
|
261
279
|
fi
|
|
262
280
|
done
|
|
263
281
|
[ "$_reaped" -gt 0 ] &&
|
|
264
|
-
say "reaped $_reaped container(s) unused for over ${BIFFO_PG_REAP_HOURS}h (set BIFFO_PG_REAP_HOURS=0 to disable)"
|
|
282
|
+
say "reaped $_reaped of $_considered container(s) unused for over ${BIFFO_PG_REAP_HOURS}h (set BIFFO_PG_REAP_HOURS=0 to disable)"
|
|
283
|
+
|
|
284
|
+
# ── What the reaper can SEE but must not touch ──────────────────────────
|
|
285
|
+
#
|
|
286
|
+
# The defect in #1383 was not that stale containers survived; it was that
|
|
287
|
+
# they were outside the denominator, so a clean reaper run was a true
|
|
288
|
+
# statement about a set that silently excluded them. Three Postgres
|
|
289
|
+
# containers up for DAYS -- one of them six -- sat beside a perfectly tidy
|
|
290
|
+
# `biffo-pg-test-*` family, and a `tabsii-rls-local` two days stale is
|
|
291
|
+
# already measured in docs/guides/development-practices.md as costing ~20m
|
|
292
|
+
# of chasing failures that belonged to nobody.
|
|
293
|
+
#
|
|
294
|
+
# They are REPORTED, never removed, and that is a deliberate departure from
|
|
295
|
+
# the issue's preferred fix ("reap any container on the Postgres test image
|
|
296
|
+
# with no client connections"). The reaper's own licence to delete rests on
|
|
297
|
+
# "reaping something still wanted is cheap and self-correcting" -- true only
|
|
298
|
+
# of containers THIS script creates, because this script recreates them. A
|
|
299
|
+
# hand-run container may hold hand-loaded data that nothing here can
|
|
300
|
+
# reconstruct, and an idle one is exactly the case a connection check
|
|
301
|
+
# cannot distinguish from an abandoned one. Widening the deletion set to
|
|
302
|
+
# every `postgres:`/`postgis:` image would trade an invisible mess for an
|
|
303
|
+
# unrecoverable one.
|
|
304
|
+
#
|
|
305
|
+
# So: name them, price them, and let a human decide. That is what would have
|
|
306
|
+
# made this visible six days earlier instead of during an unrelated cleanup.
|
|
307
|
+
# One `docker ps` for names AND images, so the image filter costs nothing;
|
|
308
|
+
# only the handful that survive it are worth an `inspect` for the timestamp.
|
|
309
|
+
# This runs on every pg-lane invocation, so a per-container inspect over the
|
|
310
|
+
# whole daemon would put ~1s on a hot path to print a housekeeping note.
|
|
311
|
+
# Neither field can contain a space, so a space separator needs no IFS
|
|
312
|
+
# games -- and `IFS=$'\t'` would not have worked anyway: these scripts run
|
|
313
|
+
# under dash, where that splits on the four characters $ ' \ t.
|
|
314
|
+
_unclaimed=''
|
|
315
|
+
docker ps -a --format '{{.Names}} {{.Image}}' 2>/dev/null | {
|
|
316
|
+
while read -r _c _img; do
|
|
317
|
+
[ "$_c" = "$CONTAINER" ] && continue
|
|
318
|
+
case "$_reapable_flat" in *" $_c "*) continue ;; esac
|
|
319
|
+
# Both images this script can choose (see IMAGE above), matched by
|
|
320
|
+
# repository rather than tag so a BIFFO_PG_IMAGE override still lands.
|
|
321
|
+
case "$_img" in postgres:* | postgis/*) ;; *) continue ;; esac
|
|
322
|
+
_made=$(docker inspect -f '{{.Created}}' "$_c" 2>/dev/null | cut -c1-19)
|
|
323
|
+
[ -z "$_made" ] && continue
|
|
324
|
+
awk -v a="$_made" -v b="$_reap_cutoff" 'BEGIN { exit !(a < b) }' &&
|
|
325
|
+
_unclaimed="$_unclaimed $_c($_img)"
|
|
326
|
+
done
|
|
327
|
+
# Reported inside the subshell the pipeline created: `_unclaimed` set in a
|
|
328
|
+
# piped `while` does not survive it in a POSIX shell.
|
|
329
|
+
if [ -n "$_unclaimed" ]; then
|
|
330
|
+
say "NOT reaped -- Postgres containers over ${BIFFO_PG_REAP_HOURS}h old that this script did not create:"
|
|
331
|
+
for _u in $_unclaimed; do say " $_u"; done
|
|
332
|
+
say " A stale one costs test failures that belong to nobody (#1383). Remove by hand"
|
|
333
|
+
say " (docker rm -f <name>), or start it with --label biffo.ephemeral=1 to have it reaped."
|
|
334
|
+
fi
|
|
335
|
+
}
|
|
265
336
|
fi
|
|
266
337
|
fi
|
|
267
338
|
|
|
@@ -276,7 +347,12 @@ if ! psql_admin -c 'SELECT 1' >/dev/null 2>&1; then
|
|
|
276
347
|
docker start "$CONTAINER" >/dev/null
|
|
277
348
|
else
|
|
278
349
|
say "creating container $CONTAINER ($IMAGE) on port $PORT"
|
|
279
|
-
|
|
350
|
+
# The label is what makes this container reapable by a property rather than
|
|
351
|
+
# by the name it happens to carry (#1383). The name prefix still works and
|
|
352
|
+
# is still scanned, but it only ever described containers this script named;
|
|
353
|
+
# anything started under another name was outside the reaper's denominator
|
|
354
|
+
# entirely. A label travels with the container whatever it is called.
|
|
355
|
+
docker run -d --name "$CONTAINER" --label biffo.ephemeral=1 \
|
|
280
356
|
-e POSTGRES_PASSWORD="$PASS" -p "$PORT:5432" "$IMAGE" >/dev/null
|
|
281
357
|
fi
|
|
282
358
|
# Polled, not slept: a cold image pull and a warm restart differ by an order of
|