Release / release (push) Failing after 53s
The dev rig had grown across three home dirs (`/opt/ai/compose/`, `/opt/ai/github/`,
`/home/wasif/`) and three repos (single-3090, dual-3090, club-3090). Disk-out
on `/` (97% used) forced a cleanup; rather than just prune, we consolidated
the layout across the whole stack while we were at it. This commit captures
what landed inside this repo.
Services consolidation:
- services/{ollama,openwebui,litellm,qdrant,searxng}/ migrated in from
/opt/ai/compose/<svc>/ (zero functional change — same docker-compose.yml).
- services/litellm/config.yaml rewritten: explicit routes for current
primaries (qwen3.6-27b-autoround → :8010, gemma-4-31b-autoround → :8030).
Removed `* → ollama/*` wildcard.
- services/comfyui/ migrated in (was /opt/ai/compose/comfyui/) — wired into
gpu-mode with full mutex against vLLM/SGLang.
scripts/gpu-mode.sh under git:
- Was a loose /opt/ai/gpu-mode.sh outside any repo. Symlinked at
/usr/local/bin/gpu-mode.
- Five Gemma 4 31B modes added: gemma, gemma-dflash, gemma-int8,
gemma-dflash-int8, gemma-awq.
- One ComfyUI mode (mutex with all LLM serving).
- prune / prune-all subcommands (safe image prune; aggressive variant adds
build cache --keep-storage 5GB + dangling networks).
- gpu-mode status now shows Docker disk + /var/lib/docker + /tmp sizes.
- compose_at() passes --env-file <repo>/.env so MODEL_DIR resolves
regardless of which compose dir gpu-mode cd's into. Fixes the recurring
"MODEL_DIR not set, defaulting to ../../../../../models-cache" warning.
- stderr no longer swallowed by compose_at() (real errors surface).
- Cross-model VRAM mutex: every Qwen mode stop_all_gemma + stop_comfyui
and vice-versa.
scripts/maintenance/ — new hygiene-tools subdir:
- list-image-pins.sh: engine-agnostic pin auditor. Scans every compose's
`image:` line, groups by `<repo>:<tag>`, flags pin-drift (multiple tags
per repo), ranks composes by patch surface.
Pin tracking:
- docs/UPSTREAM.md gains a "Pinned images" section: table of every pinned
image, why each pin exists, retirement candidate criteria.
- docs/NIGHTLY_BUMP_RUNBOOK.md (new): 7-step procedure for bumping pinned
engine images (scope → branch → patch survival → boot → verify-full +
verify-stress → bench delta → land → retire). Engine-specific notes
for vLLM nightly hashes, llama.cpp digest pinning, SGLang variants.
Path updates from the engine + model dir consolidation:
- /opt/ai/vllm-src/ → /opt/ai/engines/vllm/primary/
(in setup.sh, INTERNALS.md, several patch READMEs, docs/HARDWARE.md,
docs/FAQ.md, docs/DUAL_CARD.md, docs/UPSTREAM.md, models/qwen3.6-27b/
CHANGELOG.md)
- /mnt/models/gguf/qwen3.6-27b/ → /mnt/models/huggingface/qwen3.6-27b-gguf/
(in models/qwen3.6-27b/llama-cpp/{compose/single/*.yml, recipes/*.sh,
README.md}, docs/engines/LLAMA_CPP.md)
CHANGELOG.md narrative gap fill:
- 2026-05-10 entry for this reorg.
- 2026-05-09 entry for compose convention formalization (topology
promoted to dir level, profile schema, Status enum + Caveats, cliff
CI swap, Discord launch).
- 2026-05-08 entry for Gemma 4 INT8 PTH unblock + 262K validation.
- 2026-05-07 entry for power-cap-sweep campaign + HARDWARE.md cross-rig
charts + cross-rig benchmark rows.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
137 lines
4.7 KiB
Bash
Executable File
137 lines
4.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# list-image-pins.sh — audit which container images each club-3090 compose pins,
|
|
# what patches each compose mounts, and which composes share a pin.
|
|
#
|
|
# Engine-agnostic — works for vLLM, llama.cpp, SGLang, Luce, xtransformers, or
|
|
# any engine whose composes use `image: <repo>:<tag>`. Output groups composes
|
|
# by `<repo>:<tag>` so you can see at a glance:
|
|
# - which composes share a pin (= safe to bump together)
|
|
# - which patches each compose adds (= migration cost per compose)
|
|
# - which engines have pin-drift (multiple tags of the same repo)
|
|
#
|
|
# Usage:
|
|
# bash scripts/maintenance/list-image-pins.sh # default: club-3090 root auto-detected
|
|
# REPO=/path/to/club-3090 bash scripts/maintenance/list-image-pins.sh
|
|
# bash scripts/maintenance/list-image-pins.sh --filter vllm # only show vllm/* repos
|
|
#
|
|
# When to run:
|
|
# - Before bumping an engine pin (see docs/NIGHTLY_BUMP_RUNBOOK.md)
|
|
# - After landing a new compose, to verify it joined an existing pin not a new one
|
|
# - Periodically to surface accumulated pin sprawl across engines
|
|
|
|
set -euo pipefail
|
|
|
|
REPO="${REPO:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
|
|
FILTER=""
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--filter) FILTER="$2"; shift 2 ;;
|
|
--filter=*) FILTER="${1#--filter=}"; shift ;;
|
|
-h|--help) sed -n '2,21p' "$0"; exit 0 ;;
|
|
*) echo "unknown arg: $1" >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
if [ ! -d "$REPO/models" ]; then
|
|
echo "error: $REPO does not look like a club-3090 repo (no models/ dir)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
CYAN=$'\033[0;36m'
|
|
GREEN=$'\033[0;32m'
|
|
YELLOW=$'\033[1;33m'
|
|
NC=$'\033[0m'
|
|
|
|
echo ""
|
|
if [ -n "$FILTER" ]; then
|
|
echo "${CYAN}═══ Image pins across ${REPO} (filter: $FILTER) ═══${NC}"
|
|
else
|
|
echo "${CYAN}═══ Image pins across ${REPO} ═══${NC}"
|
|
fi
|
|
echo ""
|
|
|
|
# Build temp file: image_repo_tag<TAB>compose-relpath<TAB>patch-list
|
|
tmp=$(mktemp)
|
|
trap 'rm -f "$tmp"' EXIT
|
|
|
|
shopt -s nullglob
|
|
# Walk all engine compose dirs: vllm, llama-cpp, sglang, luce, xtransformers, etc.
|
|
# Pattern: models/<model>/<engine>/compose/<topology>/<file>.yml
|
|
for f in "$REPO"/models/*/*/compose/*/*.yml "$REPO"/models/*/*/compose/*.yml; do
|
|
[ -f "$f" ] || continue
|
|
# Extract first `image: <repo>:<tag>` line. Match repo/tag flexibly so we
|
|
# cover stable tags (server-cuda), nightly hashes, semver, etc.
|
|
image=$(grep -E "^[[:space:]]*image:[[:space:]]+" "$f" 2>/dev/null \
|
|
| head -1 \
|
|
| sed -E 's/^[[:space:]]*image:[[:space:]]+//' \
|
|
| tr -d '"' | awk '{print $1}' || true)
|
|
if [ -z "$image" ]; then
|
|
continue # No image: line, skip (might be an override-only compose)
|
|
fi
|
|
# Apply filter if set
|
|
if [ -n "$FILTER" ] && [[ "$image" != *"$FILTER"* ]]; then
|
|
continue
|
|
fi
|
|
patches=$(grep -oE "patches/[a-zA-Z0-9_./-]+" "$f" 2>/dev/null \
|
|
| sed -E 's|^(patches/[a-zA-Z0-9_-]+).*|\1|' \
|
|
| sort -u | tr '\n' ',' | sed 's/,$//' || true)
|
|
rel="${f#$REPO/}"
|
|
printf "%s\t%s\t%s\n" "$image" "$rel" "${patches:-none}" >> "$tmp"
|
|
done
|
|
|
|
if [ ! -s "$tmp" ]; then
|
|
echo "${YELLOW}(no compose files matched)${NC}"
|
|
exit 0
|
|
fi
|
|
|
|
# Per-image summary, sorted by repo+tag
|
|
echo "${CYAN}── Pin distribution ──${NC}"
|
|
printf "%-72s %s\n" "Image" "Composes"
|
|
printf "%-72s %s\n" "-----" "--------"
|
|
awk -F'\t' '{print $1}' "$tmp" | sort | uniq -c | sort -rn \
|
|
| awk '{cnt=$1; $1=""; sub(/^ /, ""); printf "%-72s %d\n", $0, cnt}'
|
|
|
|
# Highlight engines with pin DRIFT (same repo, multiple tags)
|
|
echo ""
|
|
echo "${CYAN}── Pin-drift detection ──${NC}"
|
|
drift=$(awk -F'\t' '{print $1}' "$tmp" | awk -F: '{print $1}' | sort -u | while read repo; do
|
|
ntags=$(awk -F'\t' -v r="$repo" '$1 ~ "^"r":" {print $1}' "$tmp" | sort -u | wc -l)
|
|
if [ "$ntags" -gt 1 ]; then
|
|
printf " ${YELLOW}%s${NC} has %d distinct tags pinned\n" "$repo" "$ntags"
|
|
fi
|
|
done)
|
|
if [ -n "$drift" ]; then
|
|
echo "$drift"
|
|
echo " ${YELLOW}^^${NC} consider consolidating to one tag per repo (see docs/NIGHTLY_BUMP_RUNBOOK.md)"
|
|
else
|
|
echo " ${GREEN}✓ No drift — every repo pins exactly one tag.${NC}"
|
|
fi
|
|
|
|
# Per-pin compose breakdown
|
|
echo ""
|
|
echo "${CYAN}── Per-pin compose + patch breakdown ──${NC}"
|
|
images=$(awk -F'\t' '{print $1}' "$tmp" | sort -u)
|
|
for img in $images; do
|
|
echo ""
|
|
echo "${GREEN}● $img${NC}"
|
|
awk -F'\t' -v img="$img" '$1==img {
|
|
printf " %-58s patches=%s\n", $2, $3
|
|
}' "$tmp" | sort
|
|
done
|
|
|
|
# Patch surface ranking
|
|
echo ""
|
|
echo "${CYAN}── Patch surface (highest = most expensive to migrate when pin bumps) ──${NC}"
|
|
echo ""
|
|
awk -F'\t' '$3 != "none" {
|
|
n = split($3, a, ",")
|
|
print n "\t" $2 "\t" $3
|
|
}' "$tmp" | sort -rn | head -10 | awk -F'\t' '{
|
|
printf " %d patches %s\n (%s)\n", $1, $2, $3
|
|
}'
|
|
|
|
echo ""
|
|
echo "${YELLOW}Tip:${NC} See docs/NIGHTLY_BUMP_RUNBOOK.md for the bump procedure."
|
|
echo ""
|