fix(community): PRO helper logs full prelude; safe GH token env; prelude ;

Redirect helper stdout/err to install log; pass PAT via spawn env (-e VAR),
fix prelude chaining; clearer missing bash/curl exit.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Андрей Бобырев
2026-05-15 01:44:17 +03:00
parent 9f5aa3929f
commit 0213003ff9
3 changed files with 26 additions and 12 deletions

View File

@@ -123,7 +123,7 @@ curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web/main/scrip
### В `community-install-last.log`: **`curl: command not found`**, **`tar: invalid magic`**, **`code=2` сразу после helper ### В `community-install-last.log`: **`curl: command not found`**, **`tar: invalid magic`**, **`code=2` сразу после helper
Образ **`docker:26-cli`** на Alpine обычно **без `bash` и без `curl`**. PRO `install.sh` с **`#!/usr/bin/env bash`** и загрузкой архива через **`curl | tar`** без них не стартуют (**`curl: command not found`**, **`tar: invalid magic`**). Если helper успевает записать строку про «одноразовый установщик», а дальше сразу **`--- завершено … code=2 ---`** через ~секунду — чаще всего **не нашли `bash`** (или **`apk`** не смог ставить пакеты — сеть/политики). В актуальном коде helper перед `install.sh` ставит **`bash`/`curl`/ca-cert**. Если **`apk`/`apt-get`** с хоста недоступны из контейнера — свой образ в **`COMMUNITY_PRO_INSTALL_HELPER_IMAGE`** (со **`bash`** и **`curl`**), другой сетап в PRO-скрипте (`wget`, **`#!/bin/sh`**). Отключить подготовку: **`COMMUNITY_HELPER_SKIP_PREPARE_TOOLS=1`**. Образ **`docker:26-cli`** на Alpine обычно **без `bash` и без `curl`**. PRO `install.sh` с **`#!/usr/bin/env bash`** и загрузкой архива через **`curl | tar`** без них не стартуют (**`curl: command not found`**, **`tar: invalid magic`**). Если после строки «одноразовый установщик» почти сразу **`--- завершено … code=2`** — возможны ошибка сборки prelude в **`sh`**, ошибка **`docker run … -e TOKEN=…`** из‑за спецсимволов в PAT, или **apk** не смог добавить **`bash`** (сеть из контейнера). Обновите панель с **`main`**: helper целиком шлёт **stdout/stderr в лог**, токены передаются средой процесса (без интерполяции в аргументе `-e`), prelude разделён **`;`**; перед **`install.sh`** скрипт сообщает если **нет bash/curl** (**выход по коду ~126**). Если **apk недоступен** — свой **`COMMUNITY_PRO_INSTALL_HELPER_IMAGE`** с **`bash` и `curl`**, либо в приватном `install.sh` перейти на **`#!/bin/sh`** и **`wget`**. Отключить подготовку: **`COMMUNITY_HELPER_SKIP_PREPARE_TOOLS=1`**.
### Установка «зависла» на сообщении **`→ Клонирование релиза …`** и долго без вывода ### Установка «зависла» на сообщении **`→ Клонирование релиза …`** и долго без вывода

View File

@@ -1,6 +1,6 @@
{ {
"name": "amnezia-admin", "name": "amnezia-admin",
"version": "1.2.7", "version": "1.2.8",
"private": true, "private": true,
"description": "amnezia_web — базовая панель AmneziaWG (FREE: просмотр и удаление клиентов; полная версия — PRO).", "description": "amnezia_web — базовая панель AmneziaWG (FREE: просмотр и удаление клиентов; полная версия — PRO).",
"license": "MIT", "license": "MIT",

View File

@@ -389,10 +389,10 @@ function dockerCliHelperEnsureFetchToolsScript() {
# bash + curl для приватного install.sh (#!/usr/bin/env bash у большинства install.sh из репозиториев GitHub). # bash + curl для приватного install.sh (#!/usr/bin/env bash у большинства install.sh из репозиториев GitHub).
if ! command -v bash >/dev/null 2>&1 || ! command -v curl >/dev/null 2>&1; then if ! command -v bash >/dev/null 2>&1 || ! command -v curl >/dev/null 2>&1; then
if command -v apk >/dev/null 2>&1; then if command -v apk >/dev/null 2>&1; then
apk add --no-cache bash curl ca-certificates || echo "⚠ helper: apk add bash/curl failed — install.sh может не запуститься" >> /mnt/data/community-install-last.log apk add --no-cache bash curl ca-certificates || echo "⚠ helper: apk add bash/curl failed — install.sh может не запуститься"
elif command -v apt-get >/dev/null 2>&1; then elif command -v apt-get >/dev/null 2>&1; then
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
apt-get update -qq >/dev/null && apt-get install -y -qq bash curl ca-certificates || echo "⚠ helper: apt bash/curl failed — install.sh может не запуститься" >> /mnt/data/community-install-last.log apt-get update -qq >/dev/null && apt-get install -y -qq bash curl ca-certificates || echo "⚠ helper: apt bash/curl failed — install.sh может не запуститься"
fi fi
fi fi
`.trim(); `.trim();
@@ -1567,15 +1567,20 @@ app.post("/api/community/run-private-install", requireAuth, async (req, res) =>
const prelude = COMMUNITY_SKIP_REMOVE_FREE_BEFORE_PRIVATE_PRO const prelude = COMMUNITY_SKIP_REMOVE_FREE_BEFORE_PRIVATE_PRO
? "sleep 2" ? "sleep 2"
: [ : [
`sleep 3; docker rm -f ${freePanelName} ${freeLandingName} 2>/dev/null || true`, "sleep 3",
`docker rm -f ${freePanelName} ${freeLandingName} 2>/dev/null || true`,
`docker rm -f ${staleProName} 2>/dev/null || true`, `docker rm -f ${staleProName} 2>/dev/null || true`,
'for __amz_hp in $(docker ps -aq --filter name=amnezia-admin-pro 2>/dev/null || true); do docker rm -f "$__amz_hp" 2>/dev/null || true; done', 'for __amz_hp in $(docker ps -aq --filter name=amnezia-admin-pro 2>/dev/null); do docker rm -f "$__amz_hp" 2>/dev/null || true; done',
].join(" "); ].join("; ");
const fetchTools = dockerCliHelperEnsureFetchToolsScript(); const fetchTools = dockerCliHelperEnsureFetchToolsScript();
const sh = ` const sh = `
exec >>"/mnt/data/community-install-last.log" 2>&1
set -eu set -eu
echo "→ helper (docker cli): prelude + bash/curl..."
${prelude} ${prelude}
${fetchTools ? `${fetchTools}\n` : ""}cd /mnt/stage && exec bash ./install.sh >> /mnt/data/community-install-last.log 2>&1 ${fetchTools ? `${fetchTools}\n` : ""}command -v bash >/dev/null 2>&1 || { echo "⚠ helper: нет bash после apk/apt — см. ошибки apk выше"; exit 126; }
command -v curl >/dev/null 2>&1 || { echo "⚠ helper: нет curl после apk/apt"; exit 126; }
cd /mnt/stage && exec bash ./install.sh
`.trim(); `.trim();
const dr = spawn( const dr = spawn(
@@ -1591,17 +1596,26 @@ ${fetchTools ? `${fetchTools}\n` : ""}cd /mnt/stage && exec bash ./install.sh >>
`-v`, `-v`,
`${dataAbs}:/mnt/data`, `${dataAbs}:/mnt/data`,
"-e", "-e",
`GITHUB_TOKEN=${token}`, "GITHUB_TOKEN",
"-e", "-e",
`GH_TOKEN=${token}`, "GH_TOKEN",
"-e", "-e",
"GIT_TERMINAL_PROMPT=0", "GIT_TERMINAL_PROMPT",
helperImage, helperImage,
"sh", "sh",
"-lc", "-lc",
sh, sh,
], ],
{ detached: true, stdio: "ignore" }, {
detached: true,
stdio: "ignore",
env: {
...process.env,
GITHUB_TOKEN: token,
GH_TOKEN: token,
GIT_TERMINAL_PROMPT: "0",
},
},
); );
dr.unref(); dr.unref();
dr.once("exit", (code, signal) => finalize(code, signal)); dr.once("exit", (code, signal) => finalize(code, signal));