78 lines
4.0 KiB
Bash
78 lines
4.0 KiB
Bash
#!/bin/sh
|
|
# ════════════════════════════════════════════════════════════════════════════
|
|
# Обновление dsh внутри работающего контейнера — «как плагины», без пересборки.
|
|
#
|
|
# Механизм: management console платформы, канал experimental — ставит npm-версию
|
|
# @deepseek-ai/dsh в /data/platform ( персистентный volume), с пробацией и
|
|
# автоматическим откатом при неудаче. Код dsh переживает пересоздание контейнера.
|
|
#
|
|
# Использование:
|
|
# scripts/update-dsh.sh # до npm dist-tag latest
|
|
# scripts/update-dsh.sh check # только показать текущую/доступную версии
|
|
# scripts/update-dsh.sh --container X # другое имя контейнера (по умолчанию dsh)
|
|
#
|
|
# Примечания:
|
|
# - experimental ставит ТОЛЬКО npm dist-tag latest (вверх). Конкретная версия —
|
|
# scripts/build-image.sh <версия> + смена DSH_IMAGE в .env.
|
|
# - Плагины профиля web (/data/dsh) не трогаются и переживают обновление.
|
|
# ════════════════════════════════════════════════════════════════════════════
|
|
set -eu
|
|
|
|
CONTAINER=dsh
|
|
ACTION=update
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--container) CONTAINER="$2"; shift 2 ;;
|
|
check) ACTION=check; shift ;;
|
|
*) echo "unknown arg: $1" >&2; exit 64 ;;
|
|
esac
|
|
done
|
|
|
|
say() { printf '\n=== %s\n' "$*"; }
|
|
|
|
docker inspect -f '{{.State.Running}}' "$CONTAINER" >/dev/null 2>&1 || {
|
|
echo "Контейнер '$CONTAINER' не запущен. Сначала: docker compose -p dsh up -d" >&2; exit 1; }
|
|
|
|
say "Текущая версия"
|
|
CURRENT=$(docker exec "$CONTAINER" dsh --version)
|
|
echo "installed: $CURRENT"
|
|
|
|
say "Доступно на npm"
|
|
TARGET=$(docker exec "$CONTAINER" node -e "fetch('https://registry.npmjs.org/-/package/@deepseek-ai%2Fdsh/dist-tags').then(r=>r.json()).then(d=>console.log(d.latest)).catch(e=>{console.error(e.message);process.exit(1)})")
|
|
echo "npm latest: $TARGET"
|
|
|
|
[ "$ACTION" = check ] && exit 0
|
|
|
|
if [ "$CURRENT" = "$TARGET" ]; then
|
|
echo "Уже актуально ($CURRENT). Выход."; exit 0
|
|
fi
|
|
|
|
say "Переключаю канал на experimental"
|
|
docker exec "$CONTAINER" dsh-platform channel experimental
|
|
|
|
say "Запускаю обновление (скачивание+установка+рестарт рантайма; это минуты)"
|
|
if ! docker exec "$CONTAINER" dsh-platform update --wait; then
|
|
echo "ОШИБКА: обновление не прошло. Диагностика:" >&2
|
|
docker exec "$CONTAINER" dsh-platform status || true
|
|
docker exec "$CONTAINER" dsh-platform logs --source updater --limit 50 || true
|
|
echo "Платформа обычно сама откатилась к $CURRENT. Повтор: scripts/update-dsh.sh" >&2
|
|
exit 1
|
|
fi
|
|
|
|
PROBATION=$(docker exec "$CONTAINER" printenv DSH_EXPERIMENTAL_PROBATION_SECONDS || echo 120)
|
|
say "Пробация ${PROBATION}s — жду автоподтверждение"
|
|
WAIT=$((PROBATION + 180)); I=0
|
|
while [ "$I" -lt "$WAIT" ]; do
|
|
NEW=$(docker exec "$CONTAINER" dsh --version 2>/dev/null || echo '?')
|
|
if [ "$NEW" = "$TARGET" ]; then
|
|
say "Готово: dsh $NEW (было $CURRENT)"
|
|
docker exec "$CONTAINER" dsh-platform status || true
|
|
exit 0
|
|
fi
|
|
sleep 15; I=$((I + 15))
|
|
done
|
|
|
|
echo "Таймаут ожидания. Текущая версия: $(docker exec "$CONTAINER" dsh --version 2>/dev/null || echo '?')." >&2
|
|
echo "Проверьте вручную: docker exec $CONTAINER dsh-platform status" >&2
|
|
exit 1
|