From 0213003ff942943fb82cb9440d6343ceaef4ba70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=91=D0=BE=D0=B1?= =?UTF-8?q?=D1=8B=D1=80=D0=B5=D0=B2?= Date: Fri, 15 May 2026 01:44:17 +0300 Subject: [PATCH] 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 --- README.md | 2 +- package.json | 2 +- server.js | 34 ++++++++++++++++++++++++---------- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index e593fb0..c6f6b7a 100644 --- a/README.md +++ b/README.md @@ -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 -Образ **`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`**. ### Установка «зависла» на сообщении **`→ Клонирование релиза …`** и долго без вывода diff --git a/package.json b/package.json index be62340..cd0d1de 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "amnezia-admin", - "version": "1.2.7", + "version": "1.2.8", "private": true, "description": "amnezia_web — базовая панель AmneziaWG (FREE: просмотр и удаление клиентов; полная версия — PRO).", "license": "MIT", diff --git a/server.js b/server.js index 40e4fc3..d8f5cd8 100644 --- a/server.js +++ b/server.js @@ -389,10 +389,10 @@ function dockerCliHelperEnsureFetchToolsScript() { # 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 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 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 `.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 ? "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`, - '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', - ].join(" "); + '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("; "); const fetchTools = dockerCliHelperEnsureFetchToolsScript(); const sh = ` +exec >>"/mnt/data/community-install-last.log" 2>&1 set -eu +echo "→ helper (docker cli): prelude + bash/curl..." ${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(); const dr = spawn( @@ -1591,17 +1596,26 @@ ${fetchTools ? `${fetchTools}\n` : ""}cd /mnt/stage && exec bash ./install.sh >> `-v`, `${dataAbs}:/mnt/data`, "-e", - `GITHUB_TOKEN=${token}`, + "GITHUB_TOKEN", "-e", - `GH_TOKEN=${token}`, + "GH_TOKEN", "-e", - "GIT_TERMINAL_PROMPT=0", + "GIT_TERMINAL_PROMPT", helperImage, "sh", "-lc", 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.once("exit", (code, signal) => finalize(code, signal));