6a849dc1ec
update.sh installed `[search]` only, so the release that added agent connections shipped without asyncssh and the feature offered an install hint on a machine that had just been told to install it. The extras are now one variable, spelled the same way in install.sh and update.sh, with a comment in both saying they have to stay in step. That is the whole failure mode: an extra added to one of them is an extra existing deployments silently miss. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
91 lines
3.7 KiB
Bash
Executable File
91 lines
3.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Pull the latest LLeMbas into the deployment and restart the service.
|
|
#
|
|
# Run this after pushing. It fetches, hard-resets the deployment checkout to the
|
|
# remote branch, reinstalls dependencies if they changed, and restarts. Nothing
|
|
# is ever edited in place under the deployment prefix, so a hard reset is safe
|
|
# and avoids merge conflicts from a dirty tree.
|
|
set -euo pipefail
|
|
|
|
SERVICE_USER="${SERVICE_USER:-lembas}"
|
|
PREFIX="${PREFIX:-/srv/lembas}"
|
|
BRANCH="${LEMBAS_BRANCH:-main}"
|
|
|
|
APP="$PREFIX/app"
|
|
VENV="$PREFIX/venv"
|
|
|
|
if [[ ! -d "$APP/.git" ]]; then
|
|
echo "No deployment at $APP. Run deploy/install.sh first." >&2
|
|
exit 1
|
|
fi
|
|
|
|
git_as() { sudo -u "$SERVICE_USER" git -C "$APP" "$@"; }
|
|
|
|
before=$(git_as rev-parse HEAD)
|
|
|
|
echo "== fetching =="
|
|
git_as fetch --quiet origin "$BRANCH"
|
|
git_as reset --hard --quiet "origin/$BRANCH"
|
|
|
|
after=$(git_as rev-parse HEAD)
|
|
|
|
if [[ "$before" == "$after" ]]; then
|
|
echo " already at ${after:0:7}, nothing to pull"
|
|
else
|
|
echo " ${before:0:7} -> ${after:0:7}"
|
|
git_as --no-pager log --oneline "$before..$after" | sed 's/^/ /'
|
|
fi
|
|
|
|
# Cheap and idempotent; catches a dependency added since the last deploy.
|
|
# The extras a deployment gets. `search` because DuckDuckGo is the default web
|
|
# search provider and is meant to need no setup; `ssh` because agent chats reach
|
|
# their machine over it and a deployment without it offers the feature with an
|
|
# install hint instead. Listed here AND in install.sh -- an extra added to only
|
|
# one of them means existing deployments silently miss it.
|
|
LEMBAS_EXTRAS="${LEMBAS_EXTRAS:-search,ssh}"
|
|
echo "== dependencies =="
|
|
sudo -u "$SERVICE_USER" "$VENV/bin/pip" install --quiet -e "$APP[$LEMBAS_EXTRAS]"
|
|
|
|
# The unit is NOT reinstalled automatically. An installed unit usually carries
|
|
# host-specific lines the template cannot know about -- an ordering dependency
|
|
# on whatever serves the models, a note about how the prefix is mounted -- and
|
|
# overwriting those on every update would be a worse surprise than drifting.
|
|
#
|
|
# So this compares the *template* against the one last applied here, not the
|
|
# template against the installed file. Comparing the files would warn forever
|
|
# about the local lines, and a warning that always fires is one nobody reads.
|
|
#
|
|
# The drift is worth catching: a change in the unit can be what makes a release
|
|
# work at all. Dropping ProtectKernelTunables is why an agent chat can start a
|
|
# sandbox, and a host that pulled the code without it would run the new version
|
|
# under the old confinement and fail confusingly.
|
|
STAMP="$PREFIX/.unit-applied"
|
|
current=$(sha256sum "$APP/deploy/lembas.service" | cut -d' ' -f1)
|
|
if [[ -f "$STAMP" && "$(cat "$STAMP")" != "$current" ]]; then
|
|
echo "== systemd unit ==" >&2
|
|
echo " deploy/lembas.service has changed since it was last applied here." >&2
|
|
echo " Review it and merge by hand, keeping this host's own lines:" >&2
|
|
echo " diff /etc/systemd/system/lembas.service <(sed \\" >&2
|
|
echo " -e 's|__PREFIX__|$PREFIX|g' -e 's|__SERVICE_USER__|$SERVICE_USER|g' \\" >&2
|
|
echo " $APP/deploy/lembas.service)" >&2
|
|
echo " Then: sudo systemctl daemon-reload && sudo systemctl restart lembas" >&2
|
|
echo " And record it as applied: echo $current | sudo tee $STAMP" >&2
|
|
elif [[ ! -f "$STAMP" ]]; then
|
|
# First run after this check was added. Assume what is installed is current;
|
|
# there is nothing to compare against and crying wolf on every host once is
|
|
# not worth it.
|
|
echo "$current" | sudo tee "$STAMP" >/dev/null
|
|
fi
|
|
|
|
echo "== restart =="
|
|
sudo systemctl restart lembas
|
|
sleep 2
|
|
|
|
if systemctl is-active --quiet lembas; then
|
|
echo " lembas is running"
|
|
else
|
|
echo " lembas FAILED to start:" >&2
|
|
sudo journalctl -u lembas -n 30 --no-pager >&2
|
|
exit 1
|
|
fi
|