Add draft scripts
This commit is contained in:
parent
d5ec82b418
commit
a695324e38
4 changed files with 606 additions and 0 deletions
148
scripts/draft/llama-cpp-promote.sh
Normal file
148
scripts/draft/llama-cpp-promote.sh
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
#!/usr/bin/env bash
|
||||
# Built standing on the shoulders of billions of dwarves
|
||||
# Created by John A. Hoeven with the ethical assistance of Claude AI
|
||||
# Licence: The Unlicense — https://unlicense.org
|
||||
# ---------------------------------------------------------------------------
|
||||
# llama-cpp-promote.sh
|
||||
# /opt/llama-cpp/scripts/llama-cpp-promote.sh
|
||||
# Version: v0.0.1 | Status: DEVELOPMENT
|
||||
# Role: Orchestrator
|
||||
# ---------------------------------------------------------------------------
|
||||
# Purpose: Point the 'current' symlink at a given staged release and
|
||||
# restart llama-server. Used for BOTH forward promotion (new
|
||||
# monthly build) and rollback (point back at the previous tag) —
|
||||
# the operation is identical either way, only the target tag
|
||||
# differs. Verifies the API responds before declaring success;
|
||||
# auto-reverts the symlink if the new build fails to come up.
|
||||
# Target: BigBoy — AlmaLinux 10.2, systemd-managed llama-server.service
|
||||
# Entry: sudo ./llama-cpp-promote.sh <build-tag>
|
||||
# e.g. sudo ./llama-cpp-promote.sh b9985 (promote)
|
||||
# sudo ./llama-cpp-promote.sh b9840 (roll back)
|
||||
# Depends: curl, systemctl
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# No 'set -e' — every operation is checked explicitly (CE OS standard §1.8).
|
||||
|
||||
# ── Configuration ────────────────────────────────────────────────────────
|
||||
|
||||
LLAMA_ROOT="/opt/llama-cpp"
|
||||
RELEASES_DIR="${LLAMA_ROOT}/releases"
|
||||
CURRENT_LINK="${LLAMA_ROOT}/current"
|
||||
SERVICE_NAME="llama-server.service"
|
||||
API_PORT="8080"
|
||||
VERIFY_TIMEOUT_SECS=30
|
||||
LOG_DIR="${HOME}/.local/logs/bigboy-llama-update"
|
||||
LOG_FILE="${LOG_DIR}/promote-$(date '+%Y-%m-%d_%H%M%S').log"
|
||||
|
||||
TARGET_TAG="${1:-}"
|
||||
|
||||
# ── Logging ──────────────────────────────────────────────────────────────
|
||||
|
||||
mkdir -p "${LOG_DIR}"
|
||||
|
||||
_log() {
|
||||
local level="${1}"
|
||||
local msg="${2}"
|
||||
local ts
|
||||
ts="$(date '+%Y-%m-%d %H:%M:%S')"
|
||||
printf '[%s] [%s] %s\n' "${ts}" "${level}" "${msg}" | tee -a "${LOG_FILE}"
|
||||
}
|
||||
log_info() { _log "INFO " "${1}"; }
|
||||
log_warn() { _log "WARN " "${1}" >&2; }
|
||||
log_error() { _log "ERROR" "${1}" >&2; }
|
||||
|
||||
# ── Pre-flight checks ────────────────────────────────────────────────────
|
||||
|
||||
if [[ "${EUID}" -eq 0 ]]; then
|
||||
log_error "Do not run this script directly as root — it invokes sudo"
|
||||
log_error "only for the specific steps that need it."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "${TARGET_TAG}" ]]; then
|
||||
log_error "Usage: ${0} <build-tag>"
|
||||
log_error "Available staged releases:"
|
||||
ls -1 "${RELEASES_DIR}" 2>/dev/null | sed 's/^/ /' | tee -a "${LOG_FILE}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TARGET_PATH="${RELEASES_DIR}/${TARGET_TAG}"
|
||||
|
||||
if [[ ! -x "${TARGET_PATH}/build/bin/llama-server" ]]; then
|
||||
log_error "No valid build found at ${TARGET_PATH}/build/bin/llama-server"
|
||||
log_error "Run llama-cpp-update.sh ${TARGET_TAG} first if this is a new tag."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PREVIOUS_TAG=""
|
||||
if [[ -L "${CURRENT_LINK}" ]]; then
|
||||
PREVIOUS_TAG="$(basename "$(readlink -f "${CURRENT_LINK}")")"
|
||||
fi
|
||||
|
||||
if [[ "${PREVIOUS_TAG}" == "${TARGET_TAG}" ]]; then
|
||||
log_warn "current already points at ${TARGET_TAG} — nothing to do."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# ── Confirmation ─────────────────────────────────────────────────────────
|
||||
|
||||
printf '\nCurrent live release: %s\n' "${PREVIOUS_TAG:-none}"
|
||||
printf 'Switching to: %s\n' "${TARGET_TAG}"
|
||||
printf '%s will be restarted.\n' "${SERVICE_NAME}"
|
||||
printf '\nProceed? [y/N] '
|
||||
read -r response
|
||||
case "${response}" in
|
||||
[yY]|[yY][eE][sS]) ;;
|
||||
*) log_info "Aborted by user."; exit 0 ;;
|
||||
esac
|
||||
|
||||
# ── Step 1: swap symlink ─────────────────────────────────────────────────
|
||||
|
||||
log_info "Repointing ${CURRENT_LINK} -> ${TARGET_PATH}"
|
||||
if ! sudo ln -sfn "${TARGET_PATH}" "${CURRENT_LINK}"; then
|
||||
log_error "Failed to update symlink. Service left untouched — no restart attempted."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── Step 2: restart service ───────────────────────────────────────────────
|
||||
|
||||
log_info "Restarting ${SERVICE_NAME}"
|
||||
if ! sudo systemctl restart "${SERVICE_NAME}" >>"${LOG_FILE}" 2>&1; then
|
||||
log_error "Service failed to restart. Rolling symlink back to ${PREVIOUS_TAG}."
|
||||
if [[ -n "${PREVIOUS_TAG}" ]]; then
|
||||
sudo ln -sfn "${RELEASES_DIR}/${PREVIOUS_TAG}" "${CURRENT_LINK}"
|
||||
sudo systemctl restart "${SERVICE_NAME}" >>"${LOG_FILE}" 2>&1
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── Step 3: verify the API actually responds ─────────────────────────────
|
||||
|
||||
log_info "Waiting for API on port ${API_PORT} (up to ${VERIFY_TIMEOUT_SECS}s)"
|
||||
elapsed=0
|
||||
until curl -s -o /dev/null -w '%{http_code}' "http://127.0.0.1:${API_PORT}/health" \
|
||||
2>/dev/null | grep -q '200'; do
|
||||
sleep 2
|
||||
elapsed=$((elapsed + 2))
|
||||
if [[ "${elapsed}" -ge "${VERIFY_TIMEOUT_SECS}" ]]; then
|
||||
log_error "API did not respond within ${VERIFY_TIMEOUT_SECS}s."
|
||||
log_error "Auto-reverting to previous release: ${PREVIOUS_TAG:-none}"
|
||||
if [[ -n "${PREVIOUS_TAG}" ]]; then
|
||||
sudo ln -sfn "${RELEASES_DIR}/${PREVIOUS_TAG}" "${CURRENT_LINK}"
|
||||
sudo systemctl restart "${SERVICE_NAME}" >>"${LOG_FILE}" 2>&1
|
||||
log_warn "Reverted. Investigate ${TARGET_TAG} before retrying."
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
log_info "API confirmed healthy on ${TARGET_TAG}."
|
||||
log_info "Promotion complete: ${PREVIOUS_TAG:-none} -> ${TARGET_TAG}"
|
||||
log_info ""
|
||||
log_info "Previous release (${PREVIOUS_TAG:-none}) left in place at:"
|
||||
log_info " ${RELEASES_DIR}/${PREVIOUS_TAG}"
|
||||
log_info "Recommended: keep it for at least a week before removing, in case"
|
||||
log_info "an issue surfaces after a few days of real use rather than immediately."
|
||||
log_info ""
|
||||
log_info "To roll back at any point:"
|
||||
log_info " sudo ./llama-cpp-promote.sh ${PREVIOUS_TAG}"
|
||||
137
scripts/draft/llama-cpp-prune.sh
Normal file
137
scripts/draft/llama-cpp-prune.sh
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
#!/usr/bin/env bash
|
||||
# Built standing on the shoulders of billions of dwarves
|
||||
# Created by John A. Hoeven with the ethical assistance of Claude AI
|
||||
# Licence: The Unlicense — https://unlicense.org
|
||||
# ---------------------------------------------------------------------------
|
||||
# llama-cpp-prune.sh
|
||||
# /opt/llama-cpp/scripts/llama-cpp-prune.sh
|
||||
# Version: v0.0.1 | Status: DEVELOPMENT
|
||||
# Role: Orchestrator
|
||||
# ---------------------------------------------------------------------------
|
||||
# Purpose: Remove staged llama.cpp releases (and their matching pre-update
|
||||
# btrfs snapshots) beyond a configurable retention count. Never
|
||||
# removes the release currently pointed at by 'current', and
|
||||
# never removes anything without listing it and asking first.
|
||||
# Target: BigBoy — AlmaLinux 10.2, @llama-cpp btrfs subvolume
|
||||
# Entry: sudo ./llama-cpp-prune.sh [keep-count]
|
||||
# e.g. sudo ./llama-cpp-prune.sh (uses default: 6)
|
||||
# sudo ./llama-cpp-prune.sh 12 (keep last 12 instead)
|
||||
# Depends: btrfs-progs
|
||||
# Note: Disk math at 6 releases (~1-1.5GB shallow-clone build each) is
|
||||
# roughly 6-9GB against a 499GB OS partition — trivial. Raise
|
||||
# KEEP_DEFAULT freely; there is no disk-pressure reason to prune
|
||||
# aggressively on this hardware.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# No 'set -e' — every operation is checked explicitly (CE OS standard §1.8).
|
||||
|
||||
# ── Configuration ────────────────────────────────────────────────────────
|
||||
|
||||
LLAMA_ROOT="/opt/llama-cpp"
|
||||
RELEASES_DIR="${LLAMA_ROOT}/releases"
|
||||
CURRENT_LINK="${LLAMA_ROOT}/current"
|
||||
SNAPSHOT_DIR="/opt/.snapshots/llama-cpp"
|
||||
KEEP_DEFAULT=6
|
||||
LOG_DIR="${HOME}/.local/logs/bigboy-llama-update"
|
||||
LOG_FILE="${LOG_DIR}/prune-$(date '+%Y-%m-%d_%H%M%S').log"
|
||||
|
||||
KEEP_COUNT="${1:-${KEEP_DEFAULT}}"
|
||||
|
||||
# ── Logging ──────────────────────────────────────────────────────────────
|
||||
|
||||
mkdir -p "${LOG_DIR}"
|
||||
|
||||
_log() {
|
||||
local level="${1}"
|
||||
local msg="${2}"
|
||||
local ts
|
||||
ts="$(date '+%Y-%m-%d %H:%M:%S')"
|
||||
printf '[%s] [%s] %s\n' "${ts}" "${level}" "${msg}" | tee -a "${LOG_FILE}"
|
||||
}
|
||||
log_info() { _log "INFO " "${1}"; }
|
||||
log_warn() { _log "WARN " "${1}" >&2; }
|
||||
log_error() { _log "ERROR" "${1}" >&2; }
|
||||
|
||||
# ── Pre-flight checks ────────────────────────────────────────────────────
|
||||
|
||||
if [[ "${EUID}" -eq 0 ]]; then
|
||||
log_error "Do not run this script directly as root — it invokes sudo"
|
||||
log_error "only for the specific steps that need it."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [[ "${KEEP_COUNT}" =~ ^[0-9]+$ ]] || [[ "${KEEP_COUNT}" -lt 1 ]]; then
|
||||
log_error "keep-count must be a positive integer. Got: ${KEEP_COUNT}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CURRENT_TAG=""
|
||||
if [[ -L "${CURRENT_LINK}" ]]; then
|
||||
CURRENT_TAG="$(basename "$(readlink -f "${CURRENT_LINK}")")"
|
||||
fi
|
||||
|
||||
# ── Build the candidate list (oldest first, by directory mtime) ─────────
|
||||
|
||||
mapfile -t ALL_RELEASES < <(ls -1t "${RELEASES_DIR}" 2>/dev/null | tac)
|
||||
TOTAL="${#ALL_RELEASES[@]}"
|
||||
|
||||
if [[ "${TOTAL}" -le "${KEEP_COUNT}" ]]; then
|
||||
log_info "Only ${TOTAL} release(s) present, keep-count is ${KEEP_COUNT} — nothing to prune."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
PRUNE_COUNT=$((TOTAL - KEEP_COUNT))
|
||||
TO_PRUNE=("${ALL_RELEASES[@]:0:${PRUNE_COUNT}}")
|
||||
|
||||
# Never prune the currently live release, even if it's old — pull it out
|
||||
# of the candidate list and log that it's being kept for that reason.
|
||||
FILTERED_PRUNE=()
|
||||
for tag in "${TO_PRUNE[@]}"; do
|
||||
if [[ "${tag}" == "${CURRENT_TAG}" ]]; then
|
||||
log_warn "Skipping ${tag} — it is the currently live release."
|
||||
continue
|
||||
fi
|
||||
FILTERED_PRUNE+=("${tag}")
|
||||
done
|
||||
|
||||
if [[ "${#FILTERED_PRUNE[@]}" -eq 0 ]]; then
|
||||
log_info "Nothing eligible to prune after excluding the live release."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# ── Confirmation ─────────────────────────────────────────────────────────
|
||||
|
||||
printf '\nCurrently live release: %s (never pruned)\n' "${CURRENT_TAG:-none}"
|
||||
printf 'Keeping the %d most recent releases.\n' "${KEEP_COUNT}"
|
||||
printf '\nThe following %d release(s) and their matching snapshots will be removed:\n' \
|
||||
"${#FILTERED_PRUNE[@]}"
|
||||
for tag in "${FILTERED_PRUNE[@]}"; do
|
||||
printf ' - %s\n' "${tag}"
|
||||
done
|
||||
printf '\nProceed? [y/N] '
|
||||
read -r response
|
||||
case "${response}" in
|
||||
[yY]|[yY][eE][sS]) ;;
|
||||
*) log_info "Aborted by user."; exit 0 ;;
|
||||
esac
|
||||
|
||||
# ── Prune ────────────────────────────────────────────────────────────────
|
||||
|
||||
for tag in "${FILTERED_PRUNE[@]}"; do
|
||||
log_info "Removing release directory: ${RELEASES_DIR}/${tag}"
|
||||
if ! sudo rm -rf "${RELEASES_DIR:?}/${tag}" >>"${LOG_FILE}" 2>&1; then
|
||||
log_error "Failed to remove ${RELEASES_DIR}/${tag} — leaving it in place."
|
||||
continue
|
||||
fi
|
||||
|
||||
# Snapshots are named pre-<tag>-<date> — match by tag prefix.
|
||||
for snap in "${SNAPSHOT_DIR}"/pre-"${tag}"-*; do
|
||||
[[ -e "${snap}" ]] || continue
|
||||
log_info "Removing matching snapshot: ${snap}"
|
||||
if ! sudo btrfs subvolume delete "${snap}" >>"${LOG_FILE}" 2>&1; then
|
||||
log_error "Failed to remove snapshot ${snap} — leaving it in place."
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
log_info "Prune complete. Kept ${KEEP_COUNT} most recent release(s) plus the live one if older."
|
||||
146
scripts/draft/llama-cpp-publish.sh
Normal file
146
scripts/draft/llama-cpp-publish.sh
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
#!/usr/bin/env bash
|
||||
# Built standing on the shoulders of billions of dwarves
|
||||
# Created by John A. Hoeven with the ethical assistance of Claude AI
|
||||
# Licence: The Unlicense — https://unlicense.org
|
||||
# ---------------------------------------------------------------------------
|
||||
# llama-cpp-publish.sh
|
||||
# /opt/llama-cpp/scripts/llama-cpp-publish.sh
|
||||
# Version: v0.0.1 | Status: DEVELOPMENT
|
||||
# Role: Orchestrator
|
||||
# ---------------------------------------------------------------------------
|
||||
# Purpose: Push a llama.cpp tag that has already been built, validated, and
|
||||
# promoted live on BigBoy onward to the CE Forgejo mirror. This is
|
||||
# the vetting gate: client deployments clone the Forgejo mirror,
|
||||
# never GitHub directly, so they only ever see tags BigBoy has
|
||||
# already proven work on real hardware.
|
||||
#
|
||||
# This publishes SOURCE ONLY, not a compiled binary. Client
|
||||
# hardware varies (GPU architecture, or CPU-only) — each client
|
||||
# still builds locally from this tag with their own
|
||||
# CMAKE_CUDA_ARCHITECTURES. "Validated on BigBoy" means the
|
||||
# pinned source at this tag builds clean and behaves correctly
|
||||
# on real hardware once — it does not mean the binary is portable.
|
||||
#
|
||||
# Target: BigBoy — AlmaLinux 10.2
|
||||
# Entry: ./llama-cpp-publish.sh <build-tag>
|
||||
# e.g. ./llama-cpp-publish.sh b9985
|
||||
# Refuses to run unless <build-tag> is the currently LIVE release
|
||||
# (i.e. you promoted it first) — publishing is the last step,
|
||||
# not a shortcut around validation.
|
||||
# Depends: git, network access to FORGEJO_MIRROR_URL
|
||||
# Note: Shallow-cloned tags push fine to Forgejo for content purposes;
|
||||
# `git log` on the mirror will show truncated history for that
|
||||
# tag. This is cosmetic — the tree/blob content is complete.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# No 'set -e' — every operation is checked explicitly (CE OS standard §1.8).
|
||||
|
||||
# ── Configuration ────────────────────────────────────────────────────────
|
||||
|
||||
LLAMA_ROOT="/opt/llama-cpp"
|
||||
RELEASES_DIR="${LLAMA_ROOT}/releases"
|
||||
CURRENT_LINK="${LLAMA_ROOT}/current"
|
||||
UPSTREAM_URL="https://github.com/ggml-org/llama.cpp"
|
||||
|
||||
# TODO: confirm this path matches the actual repo you create on Forgejo.
|
||||
FORGEJO_MIRROR_URL="https://git.jhoeven.net/ceos/llama.cpp-vetted.git"
|
||||
|
||||
LOG_DIR="${HOME}/.local/logs/bigboy-llama-update"
|
||||
LOG_FILE="${LOG_DIR}/publish-$(date '+%Y-%m-%d_%H%M%S').log"
|
||||
|
||||
BUILD_TAG="${1:-}"
|
||||
|
||||
# ── Logging ──────────────────────────────────────────────────────────────
|
||||
|
||||
mkdir -p "${LOG_DIR}"
|
||||
|
||||
_log() {
|
||||
local level="${1}"
|
||||
local msg="${2}"
|
||||
local ts
|
||||
ts="$(date '+%Y-%m-%d %H:%M:%S')"
|
||||
printf '[%s] [%s] %s\n' "${ts}" "${level}" "${msg}" | tee -a "${LOG_FILE}"
|
||||
}
|
||||
log_info() { _log "INFO " "${1}"; }
|
||||
log_warn() { _log "WARN " "${1}" >&2; }
|
||||
log_error() { _log "ERROR" "${1}" >&2; }
|
||||
|
||||
# ── Cleanup ──────────────────────────────────────────────────────────────
|
||||
|
||||
PUBLISH_TMP=""
|
||||
|
||||
cleanup() {
|
||||
if [[ -n "${PUBLISH_TMP}" && -d "${PUBLISH_TMP}" ]]; then
|
||||
rm -rf "${PUBLISH_TMP}"
|
||||
fi
|
||||
log_info "Run finished. Log: ${LOG_FILE}"
|
||||
}
|
||||
trap cleanup EXIT INT TERM HUP
|
||||
|
||||
# ── Pre-flight checks ────────────────────────────────────────────────────
|
||||
|
||||
if [[ -z "${BUILD_TAG}" ]]; then
|
||||
log_error "Usage: ${0} <build-tag>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -d "${RELEASES_DIR}/${BUILD_TAG}" ]]; then
|
||||
log_error "No staged release found for ${BUILD_TAG} at ${RELEASES_DIR}/${BUILD_TAG}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CURRENT_TAG=""
|
||||
if [[ -L "${CURRENT_LINK}" ]]; then
|
||||
CURRENT_TAG="$(basename "$(readlink -f "${CURRENT_LINK}")")"
|
||||
fi
|
||||
|
||||
if [[ "${CURRENT_TAG}" != "${BUILD_TAG}" ]]; then
|
||||
log_error "${BUILD_TAG} is not the currently live release (live is: ${CURRENT_TAG:-none})."
|
||||
log_error "Publish is the LAST step — promote it with llama-cpp-promote.sh first,"
|
||||
log_error "and let it run long enough to confirm it's actually good before publishing."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── Confirmation ─────────────────────────────────────────────────────────
|
||||
|
||||
printf '\nThis will push tag %s to:\n %s\n' "${BUILD_TAG}" "${FORGEJO_MIRROR_URL}"
|
||||
printf 'This makes it available to client deployments that clone from Forgejo.\n'
|
||||
printf 'Confirm %s has been running live on BigBoy long enough to trust it.\n' "${BUILD_TAG}"
|
||||
printf '\nProceed? [y/N] '
|
||||
read -r response
|
||||
case "${response}" in
|
||||
[yY]|[yY][eE][sS]) ;;
|
||||
*) log_info "Aborted by user."; exit 0 ;;
|
||||
esac
|
||||
|
||||
# ── Push the tag (source only) to the Forgejo mirror ─────────────────────
|
||||
|
||||
PUBLISH_TMP="$(mktemp -d)"
|
||||
log_info "Preparing tag ${BUILD_TAG} for publish via ${PUBLISH_TMP}"
|
||||
|
||||
if ! git clone --quiet --depth 1 --branch "${BUILD_TAG}" \
|
||||
"${UPSTREAM_URL}" "${PUBLISH_TMP}/repo" >>"${LOG_FILE}" 2>&1; then
|
||||
log_error "Could not re-fetch ${BUILD_TAG} from upstream for publishing."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! (cd "${PUBLISH_TMP}/repo" && git remote add forgejo-mirror "${FORGEJO_MIRROR_URL}") \
|
||||
>>"${LOG_FILE}" 2>&1; then
|
||||
log_error "Failed to add Forgejo remote."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Pushing ${BUILD_TAG} to Forgejo mirror"
|
||||
if ! (cd "${PUBLISH_TMP}/repo" && git push forgejo-mirror "${BUILD_TAG}") \
|
||||
>>"${LOG_FILE}" 2>&1; then
|
||||
log_error "Push failed. Confirm the Forgejo repo exists at:"
|
||||
log_error " ${FORGEJO_MIRROR_URL}"
|
||||
log_error "and that this machine has push credentials configured."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Published: ${BUILD_TAG} is now available on the Forgejo mirror."
|
||||
log_info "Client deployments cloning ${FORGEJO_MIRROR_URL} can now build this tag."
|
||||
log_info ""
|
||||
log_info "Reminder: this is source only. Each client still builds locally"
|
||||
log_info "with CMAKE_CUDA_ARCHITECTURES matching their own hardware."
|
||||
175
scripts/draft/llama-cpp-update.sh
Normal file
175
scripts/draft/llama-cpp-update.sh
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
#!/usr/bin/env bash
|
||||
# Built standing on the shoulders of billions of dwarves
|
||||
# Created by John A. Hoeven with the ethical assistance of Claude AI
|
||||
# Licence: The Unlicense — https://unlicense.org
|
||||
# ---------------------------------------------------------------------------
|
||||
# llama-cpp-update.sh
|
||||
# /opt/llama-cpp/scripts/llama-cpp-update.sh
|
||||
# Version: v0.0.1 | Status: DEVELOPMENT
|
||||
# Role: Orchestrator
|
||||
# ---------------------------------------------------------------------------
|
||||
# Purpose: Build and stage a new pinned llama.cpp release on BigBoy, behind
|
||||
# a btrfs snapshot safety net and a versioned-symlink release
|
||||
# layout. Does NOT promote the new build automatically — that is
|
||||
# a separate, deliberate step (see llama-cpp-promote.sh) taken
|
||||
# only after Phase 12-style validation passes.
|
||||
# Target: BigBoy — AlmaLinux 10.2, @llama-cpp btrfs subvolume at
|
||||
# /opt/llama-cpp, NVIDIA RTX 5060 Ti (sm_120)
|
||||
# Entry: sudo ./llama-cpp-update.sh <build-tag>
|
||||
# e.g. sudo ./llama-cpp-update.sh b9985
|
||||
# Depends: git, cmake, gcc, nvcc (CUDA toolkit), btrfs-progs
|
||||
# Note: This is a standalone ops script for one Alma server, not part
|
||||
# of the CEOS multi-distro installer framework — so it does not
|
||||
# use ce_env.conf / pkg_* / CE_PRIV. Privilege is via sudo
|
||||
# directly, detected explicitly below rather than assumed.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# No 'set -e' — every operation is checked explicitly (CE OS standard §1.8).
|
||||
|
||||
# ── Configuration ────────────────────────────────────────────────────────
|
||||
|
||||
LLAMA_ROOT="/opt/llama-cpp"
|
||||
RELEASES_DIR="${LLAMA_ROOT}/releases"
|
||||
SNAPSHOT_DIR="/opt/.snapshots/llama-cpp"
|
||||
REPO_URL="https://github.com/ggml-org/llama.cpp"
|
||||
CUDA_ARCH="120" # RTX 5060 Ti — Blackwell sm_120
|
||||
LOG_DIR="${HOME}/.local/logs/bigboy-llama-update"
|
||||
LOG_FILE="${LOG_DIR}/update-$(date '+%Y-%m-%d_%H%M%S').log"
|
||||
|
||||
BUILD_TAG="${1:-}"
|
||||
|
||||
# ── Logging ──────────────────────────────────────────────────────────────
|
||||
|
||||
mkdir -p "${LOG_DIR}"
|
||||
|
||||
_log() {
|
||||
local level="${1}"
|
||||
local msg="${2}"
|
||||
local ts
|
||||
ts="$(date '+%Y-%m-%d %H:%M:%S')"
|
||||
printf '[%s] [%s] %s\n' "${ts}" "${level}" "${msg}" | tee -a "${LOG_FILE}"
|
||||
}
|
||||
log_info() { _log "INFO " "${1}"; }
|
||||
log_warn() { _log "WARN " "${1}" >&2; }
|
||||
log_error() { _log "ERROR" "${1}" >&2; }
|
||||
|
||||
# ── Cleanup ──────────────────────────────────────────────────────────────
|
||||
|
||||
BUILD_TMP=""
|
||||
|
||||
cleanup() {
|
||||
local exit_code="${?}"
|
||||
if [[ -n "${BUILD_TMP}" && -d "${BUILD_TMP}" && "${exit_code}" -ne 0 ]]; then
|
||||
log_warn "Non-zero exit — leaving ${BUILD_TMP} in place for inspection."
|
||||
log_warn "Remove it manually once reviewed: rm -rf ${BUILD_TMP}"
|
||||
fi
|
||||
log_info "Run finished. Log: ${LOG_FILE}"
|
||||
}
|
||||
trap cleanup EXIT INT TERM HUP
|
||||
|
||||
# ── Pre-flight checks ────────────────────────────────────────────────────
|
||||
|
||||
if [[ "${EUID}" -eq 0 ]]; then
|
||||
log_error "Do not run this script directly as root. Run as your normal"
|
||||
log_error "user; it will invoke sudo only for the specific steps that need it."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "${BUILD_TAG}" ]]; then
|
||||
log_error "Usage: ${0} <build-tag> e.g. ${0} b9985"
|
||||
log_error "Check https://github.com/ggml-org/llama.cpp/releases for current tags."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -d "${RELEASES_DIR}/${BUILD_TAG}" ]]; then
|
||||
log_error "Release ${BUILD_TAG} already exists at ${RELEASES_DIR}/${BUILD_TAG}"
|
||||
log_error "Remove it first if you intend to rebuild this tag."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for tool in git cmake nvcc; do
|
||||
if ! command -v "${tool}" >/dev/null 2>&1; then
|
||||
log_error "Required tool not found: ${tool}"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# ── Confirmation ─────────────────────────────────────────────────────────
|
||||
|
||||
printf '\nAbout to build llama.cpp %s into %s\n' "${BUILD_TAG}" "${RELEASES_DIR}/${BUILD_TAG}"
|
||||
printf 'A btrfs snapshot of %s will be taken first.\n' "${LLAMA_ROOT}"
|
||||
printf 'This will NOT restart the live service — that is a separate promote step.\n'
|
||||
printf '\nProceed? [y/N] '
|
||||
read -r response
|
||||
case "${response}" in
|
||||
[yY]|[yY][eE][sS]) ;;
|
||||
*) log_info "Aborted by user."; exit 0 ;;
|
||||
esac
|
||||
|
||||
# ── Step 1: btrfs snapshot (safety net) ──────────────────────────────────
|
||||
|
||||
mkdir -p "${SNAPSHOT_DIR}"
|
||||
SNAPSHOT_PATH="${SNAPSHOT_DIR}/pre-${BUILD_TAG}-$(date '+%Y%m%d')"
|
||||
|
||||
log_info "Taking btrfs snapshot: ${SNAPSHOT_PATH}"
|
||||
if ! sudo btrfs subvolume snapshot -r "${LLAMA_ROOT}" "${SNAPSHOT_PATH}" \
|
||||
>>"${LOG_FILE}" 2>&1; then
|
||||
log_error "Snapshot failed. Aborting before touching anything else."
|
||||
exit 1
|
||||
fi
|
||||
log_info "Snapshot confirmed at ${SNAPSHOT_PATH}"
|
||||
|
||||
# ── Step 2: clone and checkout pinned tag ────────────────────────────────
|
||||
|
||||
BUILD_TMP="$(mktemp -d)"
|
||||
log_info "Cloning llama.cpp (shallow, tag-only) into ${BUILD_TMP}"
|
||||
|
||||
# Shallow clone directly at the target tag — we only ever need this one
|
||||
# pinned commit, not full history. Cuts clone size roughly in half versus
|
||||
# a full clone + checkout, which matters once you're keeping many releases.
|
||||
if ! git clone --quiet --depth 1 --branch "${BUILD_TAG}" \
|
||||
"${REPO_URL}" "${BUILD_TMP}/llama.cpp" >>"${LOG_FILE}" 2>&1; then
|
||||
log_error "Shallow clone of tag ${BUILD_TAG} failed."
|
||||
log_error "Confirm the tag exists upstream: ${REPO_URL}/releases"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── Step 3: build (standard flags only — no exotic tuning, see notes) ────
|
||||
|
||||
log_info "Configuring CMake build (CUDA, sm_${CUDA_ARCH}, Release)"
|
||||
if ! (cd "${BUILD_TMP}/llama.cpp" && cmake -B build \
|
||||
-DGGML_CUDA=ON \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_CUDA_ARCHITECTURES="${CUDA_ARCH}") >>"${LOG_FILE}" 2>&1; then
|
||||
log_error "CMake configure failed. See ${LOG_FILE} for details."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Building — this takes a while, watch ${LOG_FILE} for progress"
|
||||
if ! (cd "${BUILD_TMP}/llama.cpp" && cmake --build build --config Release -j) \
|
||||
>>"${LOG_FILE}" 2>&1; then
|
||||
log_error "Build failed. See ${LOG_FILE} for details."
|
||||
log_error "Known issue: MXFP4 quant kernels can fail to compile on sm_120."
|
||||
log_error "This build does not require MXFP4 — check for unrelated errors first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -x "${BUILD_TMP}/llama.cpp/build/bin/llama-server" ]]; then
|
||||
log_error "Build reported success but llama-server binary is missing. Aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── Step 4: stage into versioned release directory ──────────────────────
|
||||
|
||||
log_info "Staging build into ${RELEASES_DIR}/${BUILD_TAG}"
|
||||
sudo mkdir -p "${RELEASES_DIR}"
|
||||
if ! sudo cp -a "${BUILD_TMP}/llama.cpp" "${RELEASES_DIR}/${BUILD_TAG}" \
|
||||
>>"${LOG_FILE}" 2>&1; then
|
||||
log_error "Failed to stage build into ${RELEASES_DIR}/${BUILD_TAG}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Build ${BUILD_TAG} staged successfully."
|
||||
log_info "Current live release is untouched — 'current' symlink not modified."
|
||||
log_info "Next step: run Phase 12 validation against this build, then:"
|
||||
log_info " sudo ./llama-cpp-promote.sh ${BUILD_TAG}"
|
||||
Loading…
Add table
Add a link
Reference in a new issue