From 290e23070e923837ef3b14a02f528e0a4cc60a92 Mon Sep 17 00:00:00 2001 From: Hermes Team Date: Tue, 25 Aug 2026 09:10:32 +0700 Subject: [PATCH] =?UTF-8?q?feat(installer):=20=D1=81=D0=B0=D0=BC=D0=BE?= =?UTF-8?q?=D0=B4=D0=BE=D1=81=D1=82=D0=B0=D1=82=D0=BE=D1=87=D0=BD=D1=8B?= =?UTF-8?q?=D0=B9=20=D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D1=89=D0=B8?= =?UTF-8?q?=D0=BA=20=D0=B4=D0=BB=D1=8F=20Linux,=20=D0=B1=D0=B5=D0=B7=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BF=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D1=80=D0=B5=D0=BF=D0=BE=D0=B7=D0=B8=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit install-linux.sh читал исходники из $REPO_ROOT, поэтому на каждую машину приходилось приносить весь клон git. Добавлен build_installer_linux.sh: он собирает один файл dist/hermes-hub-setup.sh — пролог на shell, строка-маркер и tar.gz побайтово следом. Пролог обрезает себя по маркеру, распаковывает хвост во временный каталог и запускает оттуда install-linux.sh. Состав поставки тот же, что у виндового payload, плюс installer/; виндовые .exe и __pycache__ из линуксовой поставки вычищаются. Убран запасной коммит-литерал 'fb23bff' в манифесте: при сборке без git он подставлял чужой номер сборки, из-за чего установленная версия выглядела определённой, не будучи ею. Теперь коммит берётся из BUILD_COMMIT, который кладёт сборщик, иначе — 'не определён'. Проверено: распаковка проходит, в поставке лежат свежие server.py и app.js, секретов, ключей и почт в ней нет. Co-Authored-By: Claude Opus 5 --- installer/build_installer_linux.sh | 81 ++++++++++++++++++++++++++++++ installer/install-linux.sh | 11 +++- 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 installer/build_installer_linux.sh diff --git a/installer/build_installer_linux.sh b/installer/build_installer_linux.sh new file mode 100644 index 0000000..5f5befa --- /dev/null +++ b/installer/build_installer_linux.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +# Собирает ОДИН самодостаточный файл dist/hermes-hub-setup.sh. +# +# Зачем: install-linux.sh читает исходники из каталога репозитория, поэтому на +# каждую машину приходилось копировать весь клон git. Здесь исходники +# упакованы внутрь самого установщика — файл переносится один и работает там, +# где git не установлен вовсе. +# +# Устройство: текстовый пролог, затем строка-маркер, затем tar.gz побайтово. +# Пролог обрезает себя по маркеру и распаковывает хвост во временный каталог. +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +DIST_DIR="$REPO_ROOT/dist" +OUT="$DIST_DIR/hermes-hub-setup.sh" + +COMMIT="$(cd "$REPO_ROOT" && git rev-parse --short HEAD 2>/dev/null || echo 'не определён')" +echo "Сборка установщика Linux, коммит: $COMMIT" + +STAGE="$(mktemp -d)" +trap 'rm -rf "$STAGE"' EXIT + +# Тот же состав, что в виндовом payload, плюс installer/ — внутри него лежит +# install-linux.sh, который и выполняет установку. +for item in src launcher assets config scripts installer; do + [ -e "$REPO_ROOT/$item" ] || continue + cp -r "$REPO_ROOT/$item" "$STAGE/$item" +done +printf '%s' "$COMMIT" > "$STAGE/BUILD_COMMIT" + +find "$STAGE" -name '__pycache__' -type d -prune -exec rm -rf {} + 2>/dev/null || true +find "$STAGE" -name '*.pyc' -delete 2>/dev/null || true +# Виндовые бинарники в линуксовой поставке бесполезны и весят больше мегабайта. +find "$STAGE/launcher" -name '*.exe' -delete 2>/dev/null || true + +PAYLOAD="$(mktemp)" +tar -czf "$PAYLOAD" -C "$STAGE" . + +mkdir -p "$DIST_DIR" +cat > "$OUT" <<'STUB' +#!/usr/bin/env bash +# Hermes Hub — самодостаточный установщик. Репозиторий и git не нужны. +# bash hermes-hub-setup.sh +set -euo pipefail + +if ! command -v tar >/dev/null 2>&1; then + echo "Нужен tar. Установите его: apt install tar" >&2 + exit 1 +fi + +MARKER='__HERMES_HUB_PAYLOAD_BELOW__' +SELF="$0" +LINE="$(grep -a -n "^$MARKER\$" "$SELF" | head -1 | cut -d: -f1)" +if [ -z "${LINE:-}" ]; then + echo "Файл повреждён: не найдена граница вложенных данных." >&2 + exit 1 +fi + +TMP="$(mktemp -d)" +trap 'rm -rf "$TMP"' EXIT + +echo "Распаковка..." +tail -n +$((LINE + 1)) "$SELF" | tar -xzf - -C "$TMP" + +if [ ! -f "$TMP/installer/install-linux.sh" ]; then + echo "Файл повреждён: во вложенных данных нет installer/install-linux.sh." >&2 + exit 1 +fi + +chmod +x "$TMP/installer/install-linux.sh" 2>/dev/null || true +exec bash "$TMP/installer/install-linux.sh" "$@" +STUB + +echo '__HERMES_HUB_PAYLOAD_BELOW__' >> "$OUT" +cat "$PAYLOAD" >> "$OUT" +rm -f "$PAYLOAD" +chmod +x "$OUT" + +SIZE_KB=$(( $(wc -c < "$OUT") / 1024 )) +echo "Готово: $OUT (${SIZE_KB} КБ)" diff --git a/installer/install-linux.sh b/installer/install-linux.sh index e65acd5..d972de2 100644 --- a/installer/install-linux.sh +++ b/installer/install-linux.sh @@ -99,7 +99,16 @@ fi # 4. Write Deployment Manifest echo "[4/6] Writing deployment manifest..." MANIFEST_FILE="$HERMES_HOME/plugins/antigravity-provider/deployment_manifest.json" -GIT_COMMIT="$(cd "$REPO_ROOT" 2>/dev/null && git rev-parse --short HEAD 2>/dev/null || echo 'fb23bff')" +# Коммит берётся из BUILD_COMMIT (кладёт сборщик самораспаковывающегося +# установщика, где git недоступен), иначе — из репозитория. Запасного +# литерала нет намеренно: неизвестный коммит должен читаться как неизвестный, +# а не как чужой чужой номер сборки. +if [ -f "$REPO_ROOT/BUILD_COMMIT" ]; then + GIT_COMMIT="$(tr -d ' +' < "$REPO_ROOT/BUILD_COMMIT")" +else + GIT_COMMIT="$(cd "$REPO_ROOT" 2>/dev/null && git rev-parse --short HEAD 2>/dev/null || echo 'не определён')" +fi TIMESTAMP="$(date -u +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || date -u)" cat < "$MANIFEST_FILE"