mirror of
https://github.com/andrey271192/amnezia_web-PRO.git
synced 2026-09-20 14:42:00 +00:00
fix: auto-detect awg profiles on install
This commit is contained in:
@@ -6,8 +6,8 @@ RUN mkdir -p /data && chmod 700 /data
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY package.json ./
|
COPY package.json package-lock.json ./
|
||||||
RUN npm install --omit=dev
|
RUN npm ci --omit=dev
|
||||||
|
|
||||||
COPY server.js ./server.js
|
COPY server.js ./server.js
|
||||||
COPY scripts ./scripts
|
COPY scripts ./scripts
|
||||||
|
|||||||
20
README.md
20
README.md
@@ -37,6 +37,20 @@ curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/s
|
|||||||
|
|
||||||
Панель после установки открывается по **`http://IP:HOST_PORT`** (по умолчанию `:8080`). Первый вход: **логин `admin`, пароль `admin`**. Смените пароль сразу после входа.
|
Панель после установки открывается по **`http://IP:HOST_PORT`** (по умолчанию `:8080`). Первый вход: **логин `admin`, пароль `admin`**. Смените пароль сразу после входа.
|
||||||
|
|
||||||
|
### Обновить/переустановить панель с GitHub
|
||||||
|
|
||||||
|
Если `/opt/amnezia-admin` не git-репозиторий, это нормально: установщик скачивает свежий архив с GitHub, делает backup старой папки, сохраняет текущий порт и текущий Docker volume `/data`, затем пересобирает только контейнер панели **`amnezia-admin`**. Контейнеры AmneziaWG (`amnezia-awg`, `amnezia-awg2` и т.д.) не удаляются и не пересоздаются.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh | sudo bash
|
||||||
|
```
|
||||||
|
|
||||||
|
Если не нужен лендинг на порту 80:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh | sudo env SKIP_LANDING=1 bash
|
||||||
|
```
|
||||||
|
|
||||||
### Переменные окружения и `sudo`
|
### Переменные окружения и `sudo`
|
||||||
|
|
||||||
Частая ошибка: задали **`AWG_PROFILES`**, **`ADMIN_PASSWORD`** или другую переменную из таблицы «в одной строке» перед `curl`, а затем выполнили **`curl … | sudo bash`**. По умолчанию **`sudo` не передаёт** это окружение в `bash`, который читает установочный скрипт с stdin: установщик **не увидит** переменные, переключатель **«Инстанс»** не появится.
|
Частая ошибка: задали **`AWG_PROFILES`**, **`ADMIN_PASSWORD`** или другую переменную из таблицы «в одной строке» перед `curl`, а затем выполнили **`curl … | sudo bash`**. По умолчанию **`sudo` не передаёт** это окружение в `bash`, который читает установочный скрипт с stdin: установщик **не увидит** переменные, переключатель **«Инстанс»** не появится.
|
||||||
@@ -80,7 +94,7 @@ cd /opt/amnezia-admin && chmod +x scripts/install.sh && sudo SKIP_DOWNLOAD=1 bas
|
|||||||
| `DATA_DIR` | `/opt/amnezia-admin-data` | Том с `password.hash` и сессией |
|
| `DATA_DIR` | `/opt/amnezia-admin-data` | Том с `password.hash` и сессией |
|
||||||
| `HOST_PORT` | `8080` | Порт HTTP панели на хосте |
|
| `HOST_PORT` | `8080` | Порт HTTP панели на хосте |
|
||||||
| `AWG_CONTAINER` | `amnezia-awg` | Имя контейнера Amnezia WG |
|
| `AWG_CONTAINER` | `amnezia-awg` | Имя контейнера Amnezia WG |
|
||||||
| `AWG_PROFILES` | _(нет)_ | JSON-массив профилей: несколько контейнеров/путей (см. ниже). Если задан — переключатель «Инстанс» в вебе. При однострочной установке с переменной в окружении нужен **`sudo -E bash`** или файл **`/root/amnezia-admin.awg-profiles.json`** — см. раздел **«Переменные окружения и sudo»** выше. В каждом объекте можно задать `warpDir`, `warpConf`, `warpClientsList`, `startScript` — см. раздел **Cloudflare WARP** |
|
| `AWG_PROFILES` | auto | JSON-массив профилей: несколько контейнеров/путей (см. ниже). Если не задан и на VPS уже есть несколько контейнеров `amnezia-awg*`, установщик сам соберёт профили и сохранит их в `/root/amnezia-admin.awg-profiles.json`. Если задан вручную — переключатель «Инстанс» в вебе. При однострочной установке с переменной в окружении нужен **`sudo -E bash`** или файл **`/root/amnezia-admin.awg-profiles.json`** — см. раздел **«Переменные окружения и sudo»** выше. В каждом объекте можно задать `warpDir`, `warpConf`, `warpClientsList`, `startScript` — см. раздел **Cloudflare WARP** |
|
||||||
| `WARP_DIR` | `/opt/warp` | В контейнере AWG: каталог для `warp.conf` и `clients.list` |
|
| `WARP_DIR` | `/opt/warp` | В контейнере AWG: каталог для `warp.conf` и `clients.list` |
|
||||||
| `WARP_CONF_PATH` | `{WARP_DIR}/warp.conf` | Нестандартный путь к конфигу WARP |
|
| `WARP_CONF_PATH` | `{WARP_DIR}/warp.conf` | Нестандартный путь к конфигу WARP |
|
||||||
| `WARP_CLIENTS_LIST` | `{WARP_DIR}/clients.list` | Список строк `10.8.x.x/32` — кому маршрутизировать трафик через интерфейс `warp` |
|
| `WARP_CLIENTS_LIST` | `{WARP_DIR}/clients.list` | Список строк `10.8.x.x/32` — кому маршрутизировать трафик через интерфейс `warp` |
|
||||||
@@ -112,7 +126,7 @@ cd /opt/amnezia-admin && chmod +x scripts/install.sh && sudo SKIP_DOWNLOAD=1 bas
|
|||||||
| `MTPRO_PUBLISH_BIND` | `0.0.0.0` | Адрес bind на хосте для `-p` |
|
| `MTPRO_PUBLISH_BIND` | `0.0.0.0` | Адрес bind на хосте для `-p` |
|
||||||
| `MTPRO_PUBLIC_HOST` | _(нет)_ | Публичный IP/DNS для ссылки **`tg://proxy`**; можно вместо этого задать **`CLIENT_CONFIG_ENDPOINT`** |
|
| `MTPRO_PUBLIC_HOST` | _(нет)_ | Публичный IP/DNS для ссылки **`tg://proxy`**; можно вместо этого задать **`CLIENT_CONFIG_ENDPOINT`** |
|
||||||
|
|
||||||
Переменная **`AWG_PROFILES`** при установке автоматически сохраняется в **`/root/amnezia-admin.awg-profiles.json`** на VPS; при следующем запуске `install.sh` без `AWG_PROFILES` значение подставляется из этого файла или из **старого контейнера** `amnezia-admin` перед его удалением — так переключатель «Инстанс» не пропадает после обновления панели.
|
Переменная **`AWG_PROFILES`** при установке автоматически сохраняется в **`/root/amnezia-admin.awg-profiles.json`** на VPS; при следующем запуске `install.sh` без `AWG_PROFILES` значение подставляется из этого файла или из **старого контейнера** `amnezia-admin` перед его удалением — так переключатель «Инстанс» не пропадает после обновления панели. Если файла и переменной нет, но на VPS запущено несколько контейнеров **`amnezia-awg*`**, установщик сам создаёт профили по контейнерам.
|
||||||
|
|
||||||
#### Несколько инстансов (AmneziaWG + Legacy и т.д.)
|
#### Несколько инстансов (AmneziaWG + Legacy и т.д.)
|
||||||
|
|
||||||
@@ -136,7 +150,7 @@ curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/s
|
|||||||
|
|
||||||
Если в вебе пропал список **«Инстанс»**, смотрите раздел «Если пропал список Инстанс» в **[docs/panel-guide.md](docs/panel-guide.md)**.
|
Если в вебе пропал список **«Инстанс»**, смотрите раздел «Если пропал список Инстанс» в **[docs/panel-guide.md](docs/panel-guide.md)**.
|
||||||
|
|
||||||
Если на хосте уже запущено **несколько** контейнеров с именами вида **`amnezia-awg*`**, а в панели по-прежнему один инстанс — задайте **`AWG_PROFILES`** (или файл **`/root/amnezia-admin.awg-profiles.json`**) и перезапустите установщик; при запуске **`install.sh`** без профилей в этом случае выводится предупреждение в консоль.
|
Если на хосте уже запущено **несколько** контейнеров с именами вида **`amnezia-awg*`**, а в панели по-прежнему один инстанс — перезапустите установщик из GitHub. Он автоматически создаст **`AWG_PROFILES`** и сохранит файл **`/root/amnezia-admin.awg-profiles.json`**. Ручной JSON нужен только при нестандартных путях внутри контейнеров.
|
||||||
|
|
||||||
### Telegram MTProto‑прокси
|
### Telegram MTProto‑прокси
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
| Блок в интерфейсе | Назначение |
|
| Блок в интерфейсе | Назначение |
|
||||||
|-------------------|------------|
|
|-------------------|------------|
|
||||||
| **Инстанс** | Переключение между профилями из `AWG_PROFILES` (разные контейнеры AmneziaWG / Legacy). Виден только если в контейнере панели задан JSON из **двух и более** профилей. |
|
| **Инстанс** | Переключение между профилями `AWG_PROFILES` (разные контейнеры AmneziaWG / Legacy). Виден, если панель получила **два и более** профиля. Установщик сам создаёт профили, когда на VPS уже запущено несколько контейнеров `amnezia-awg*`. |
|
||||||
| **Время** | Отображение часов контейнера и браузера; синхронизация времени хоста VPS по SSH (если доступно). |
|
| **Время** | Отображение часов контейнера и браузера; синхронизация времени хоста VPS по SSH (если доступно). |
|
||||||
| **Cloudflare WARP** | *Необязательно.* Вывод части клиентов в интернет через интерфейс `warp` в контейнере AWG. Если WARP не ставили — статус **«Не установлен»** нормален; панель и VPN без этого работают. Установка и удаление — скрипт `scripts/warp-amnezia.sh` на хосте (`install` / **`uninstall`**), подробности в основном [README](../README.md). |
|
| **Cloudflare WARP** | *Необязательно.* Вывод части клиентов в интернет через интерфейс `warp` в контейнере AWG. Если WARP не ставили — статус **«Не установлен»** нормален; панель и VPN без этого работают. Установка и удаление — скрипт `scripts/warp-amnezia.sh` на хосте (`install` / **`uninstall`**), подробности в основном [README](../README.md). |
|
||||||
| **Telegram MTProto‑прокси** | *Необязательно*, не часть AWG. Docker-контейнер официального образа **telegrammessenger/proxy**; установка из панели, ссылка **`tg://proxy`**, переменные **`MTPRO_*`** — см. основной [README](../README.md). |
|
| **Telegram MTProto‑прокси** | *Необязательно*, не часть AWG. Docker-контейнер официального образа **telegrammessenger/proxy**; установка из панели, ссылка **`tg://proxy`**, переменные **`MTPRO_*`** — см. основной [README](../README.md). |
|
||||||
@@ -19,8 +19,13 @@
|
|||||||
```bash
|
```bash
|
||||||
docker inspect amnezia-admin --format '{{range .Config.Env}}{{println .}}{{end}}' | grep '^AWG_PROFILES='
|
docker inspect amnezia-admin --format '{{range .Config.Env}}{{println .}}{{end}}' | grep '^AWG_PROFILES='
|
||||||
```
|
```
|
||||||
2. Если строки нет — один раз задайте JSON при установке (пример см. в основном [README](../README.md)) или восстановите файл **`/root/amnezia-admin.awg-profiles.json`** на VPS и снова запустите `install.sh` **без** своего `AWG_PROFILES` — установщик подставит значение из файла или из старого контейнера перед удалением.
|
2. Если строки нет, но `docker ps` показывает два контейнера вида `amnezia-awg*`, переустановите панель свежим установщиком из GitHub:
|
||||||
3. После правок обновите страницу с **жёстким сбросом кэша** (Ctrl+Shift+R).
|
```bash
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh | sudo env SKIP_LANDING=1 bash
|
||||||
|
```
|
||||||
|
Установщик сам создаст **`AWG_PROFILES`** и сохранит **`/root/amnezia-admin.awg-profiles.json`**.
|
||||||
|
3. Ручной JSON нужен только при нестандартных путях внутри AWG-контейнеров.
|
||||||
|
4. После правок обновите страницу с **жёстким сбросом кэша** (Ctrl+Shift+R).
|
||||||
|
|
||||||
## Лендинг не поднимается (порт 80 занят)
|
## Лендинг не поднимается (порт 80 занят)
|
||||||
|
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "amnezia-admin",
|
"name": "amnezia-admin",
|
||||||
"version": "1.2.28",
|
"version": "1.2.29",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "amnezia-admin",
|
"name": "amnezia-admin",
|
||||||
"version": "1.2.28",
|
"version": "1.2.29",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"express": "^4.21.2"
|
"express": "^4.21.2"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "amnezia-admin",
|
"name": "amnezia-admin",
|
||||||
"version": "1.2.28",
|
"version": "1.2.29",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "amnezia_web-PRO — веб-панель AmneziaWG: несколько инстансов, WARP, каскад/Endpoint, экспорт .conf (Docker)",
|
"description": "amnezia_web-PRO — веб-панель AmneziaWG: несколько инстансов, WARP, каскад/Endpoint, экспорт .conf (Docker)",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -40,6 +40,29 @@ cleanup() {
|
|||||||
}
|
}
|
||||||
trap cleanup EXIT
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
# Preserve current container settings before replacing source tree. This makes
|
||||||
|
# curl-based reinstall safe even when /opt/amnezia-admin is not a git checkout.
|
||||||
|
PREV_HOST_PORT=""
|
||||||
|
PREV_DATA_DIR=""
|
||||||
|
PREV_CONTAINER_ENV=""
|
||||||
|
if docker inspect "${CONTAINER_NAME}" >/dev/null 2>&1; then
|
||||||
|
__dock_port_out=""
|
||||||
|
__dock_port_out="$(docker port "${CONTAINER_NAME}" 3980/tcp 2>/dev/null)" || :
|
||||||
|
if [[ -n "${__dock_port_out}" ]]; then
|
||||||
|
PREV_HOST_PORT="$(printf '%s\n' "${__dock_port_out}" | head -n1 | awk -F: '{print $NF}')" || PREV_HOST_PORT=""
|
||||||
|
fi
|
||||||
|
PREV_DATA_DIR="$(docker inspect "${CONTAINER_NAME}" --format '{{range .Mounts}}{{if eq .Destination "/data"}}{{.Source}}{{end}}{{end}}' 2>/dev/null || true)"
|
||||||
|
PREV_CONTAINER_ENV="$(docker inspect "${CONTAINER_NAME}" --format '{{range .Config.Env}}{{println .}}{{end}}' 2>/dev/null || true)"
|
||||||
|
fi
|
||||||
|
if [[ -n "${PREV_HOST_PORT}" && "${HOST_PORT}" == "8080" ]]; then
|
||||||
|
HOST_PORT="${PREV_HOST_PORT}"
|
||||||
|
echo "→ Уже запущен ${CONTAINER_NAME}: сохраняю внешний порт ${HOST_PORT} (укажите HOST_PORT=… чтобы сменить)."
|
||||||
|
fi
|
||||||
|
if [[ -n "${PREV_DATA_DIR}" && "${DATA_DIR}" == "/opt/amnezia-admin-data" ]]; then
|
||||||
|
DATA_DIR="${PREV_DATA_DIR}"
|
||||||
|
echo "→ Уже запущен ${CONTAINER_NAME}: сохраняю DATA_DIR ${DATA_DIR}."
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ "${SKIP_DOWNLOAD:-}" != "1" ]]; then
|
if [[ "${SKIP_DOWNLOAD:-}" != "1" ]]; then
|
||||||
echo "→ Клонирование релиза ${GITHUB_REPO} (${BRANCH})..."
|
echo "→ Клонирование релиза ${GITHUB_REPO} (${BRANCH})..."
|
||||||
echo "→ Скачивание tar.gz с GitHub (вывода может не быть 1–10 мин.; при блокировках задайте зеркало GITHUB_REPO_URL_OVERRIDE или см. CURL_MAX_TIME ниже)."
|
echo "→ Скачивание tar.gz с GitHub (вывода может не быть 1–10 мин.; при блокировках задайте зеркало GITHUB_REPO_URL_OVERRIDE или см. CURL_MAX_TIME ниже)."
|
||||||
@@ -72,6 +95,11 @@ if [[ "${SKIP_DOWNLOAD:-}" != "1" ]]; then
|
|||||||
echo "Ошибка: распакованный архив пуст (${CURL_URL})."
|
echo "Ошибка: распакованный архив пуст (${CURL_URL})."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
if [[ -d "${INSTALL_DIR}" && "${AUTO_BACKUP_INSTALL:-1}" != "0" ]]; then
|
||||||
|
__install_backup="${INSTALL_DIR}.backup.$(date -u +%Y%m%dT%H%M%SZ)"
|
||||||
|
cp -a "${INSTALL_DIR}" "${__install_backup}" 2>/dev/null || true
|
||||||
|
echo "→ Backup старых исходников: ${__install_backup}"
|
||||||
|
fi
|
||||||
rm -rf "${INSTALL_DIR}"
|
rm -rf "${INSTALL_DIR}"
|
||||||
mkdir -p "$(dirname "${INSTALL_DIR}")"
|
mkdir -p "$(dirname "${INSTALL_DIR}")"
|
||||||
mv "${__extracted_dir}" "${INSTALL_DIR}"
|
mv "${__extracted_dir}" "${INSTALL_DIR}"
|
||||||
@@ -82,21 +110,6 @@ fi
|
|||||||
mkdir -p "${DATA_DIR}"
|
mkdir -p "${DATA_DIR}"
|
||||||
mkdir -p /opt/amnezia-instances
|
mkdir -p /opt/amnezia-instances
|
||||||
|
|
||||||
# При повторном запуске не менять внешний порт панели, если не указали HOST_PORT явно (по умолчанию 8080).
|
|
||||||
PREV_HOST_PORT=""
|
|
||||||
if docker inspect "${CONTAINER_NAME}" >/dev/null 2>&1; then
|
|
||||||
# Контейнер может быть остановлен — `docker port` тогда код ≠ 0; при pipefail без этого блока скрипт выходит молча.
|
|
||||||
__dock_port_out=""
|
|
||||||
__dock_port_out="$(docker port "${CONTAINER_NAME}" 3980/tcp 2>/dev/null)" || :
|
|
||||||
if [[ -n "${__dock_port_out}" ]]; then
|
|
||||||
PREV_HOST_PORT="$(printf '%s\n' "${__dock_port_out}" | head -n1 | awk -F: '{print $NF}')" || PREV_HOST_PORT=""
|
|
||||||
fi
|
|
||||||
if [[ -n "${PREV_HOST_PORT}" && "${HOST_PORT}" == "8080" ]]; then
|
|
||||||
HOST_PORT="${PREV_HOST_PORT}"
|
|
||||||
echo "→ Уже запущен ${CONTAINER_NAME}: сохраняю внешний порт ${HOST_PORT} (укажите HOST_PORT=… чтобы сменить)."
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
BOOT_PW=""
|
BOOT_PW=""
|
||||||
PASS_FILE="/root/amnezia-admin.initial-password"
|
PASS_FILE="/root/amnezia-admin.initial-password"
|
||||||
if [[ -n "${ADMIN_PASSWORD:-}" ]]; then
|
if [[ -n "${ADMIN_PASSWORD:-}" ]]; then
|
||||||
@@ -124,14 +137,14 @@ AWG_PROFILE_SNAPSHOT="/root/amnezia-admin.awg-profiles.json"
|
|||||||
if [[ -n "${AWG_PROFILES:-}" ]]; then
|
if [[ -n "${AWG_PROFILES:-}" ]]; then
|
||||||
umask 077
|
umask 077
|
||||||
printf '%s\n' "${AWG_PROFILES}" >"${AWG_PROFILE_SNAPSHOT}" 2>/dev/null || true
|
printf '%s\n' "${AWG_PROFILES}" >"${AWG_PROFILE_SNAPSHOT}" 2>/dev/null || true
|
||||||
elif docker inspect "${CONTAINER_NAME}" >/dev/null 2>&1; then
|
elif [[ -n "${PREV_CONTAINER_ENV}" ]]; then
|
||||||
PREV_AWG_PROFILES=""
|
PREV_AWG_PROFILES=""
|
||||||
while IFS= read -r __env_line; do
|
while IFS= read -r __env_line; do
|
||||||
if [[ "${__env_line}" == AWG_PROFILES=* ]]; then
|
if [[ "${__env_line}" == AWG_PROFILES=* ]]; then
|
||||||
PREV_AWG_PROFILES="${__env_line#AWG_PROFILES=}"
|
PREV_AWG_PROFILES="${__env_line#AWG_PROFILES=}"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
done < <(docker inspect "${CONTAINER_NAME}" --format '{{range .Config.Env}}{{println .}}{{end}}')
|
done <<<"${PREV_CONTAINER_ENV}"
|
||||||
if [[ -n "${PREV_AWG_PROFILES}" ]]; then
|
if [[ -n "${PREV_AWG_PROFILES}" ]]; then
|
||||||
AWG_PROFILES="${PREV_AWG_PROFILES}"
|
AWG_PROFILES="${PREV_AWG_PROFILES}"
|
||||||
echo "→ AWG_PROFILES восстановлен из предыдущего контейнера ${CONTAINER_NAME}."
|
echo "→ AWG_PROFILES восстановлен из предыдущего контейнера ${CONTAINER_NAME}."
|
||||||
@@ -158,20 +171,34 @@ if [[ -z "${AWG_CONTAINER:-}" ]] && [[ -z "${AWG_PROFILES:-}" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z "${AWG_PROFILES:-}" ]]; then
|
if [[ -z "${AWG_PROFILES:-}" ]]; then
|
||||||
__awg_multi_count="$(
|
__awg_names="$(docker ps --format '{{.Names}}' 2>/dev/null | awk '/^amnezia-awg/ { print }' | sort || true)"
|
||||||
docker ps --format '{{.Names}}' 2>/dev/null | awk '/^amnezia-awg/ { c++ } END { print c + 0 }' | tr -d '[:space:]'
|
__awg_multi_count="$(printf '%s\n' "${__awg_names}" | sed '/^$/d' | wc -l | tr -d '[:space:]')"
|
||||||
)"
|
if [[ "${__awg_multi_count:-0}" =~ ^[0-9]+$ ]] && [[ "${__awg_multi_count}" -eq 1 ]] && [[ -z "${AWG_CONTAINER:-}" ]]; then
|
||||||
if [[ "${__awg_multi_count:-0}" =~ ^[0-9]+$ ]] && [[ "${__awg_multi_count}" -gt 1 ]]; then
|
AWG_CONTAINER="$(printf '%s\n' "${__awg_names}" | sed '/^$/d' | head -n1)"
|
||||||
echo "⚠ Запущено ${__awg_multi_count} контейнеров с именами amnezia-awg*, но AWG_PROFILES не задан."
|
echo "→ AWG_CONTAINER авто-выбран: ${AWG_CONTAINER}"
|
||||||
echo " Переключатель «Инстанс» в панели не появится: см. README, раздел «Несколько инстансов» и «Переменные окружения и sudo»."
|
elif [[ "${__awg_multi_count:-0}" =~ ^[0-9]+$ ]] && [[ "${__awg_multi_count}" -gt 1 ]]; then
|
||||||
echo " Без sudo -E: запишите JSON одной строкой в ${AWG_PROFILE_SNAPSHOT} и снова запустите этот установщик."
|
__awg_profiles="["
|
||||||
|
__sep=""
|
||||||
|
while IFS= read -r __awg_name; do
|
||||||
|
[[ -z "${__awg_name}" ]] && continue
|
||||||
|
__id="${__awg_name#amnezia-}"
|
||||||
|
__label="AmneziaWG"
|
||||||
|
if [[ "${__awg_name}" == "amnezia-awg2" ]]; then
|
||||||
|
__label="AmneziaWG 2.0"
|
||||||
|
elif [[ "${__awg_name}" != "amnezia-awg" ]]; then
|
||||||
|
__label="AmneziaWG ${__id}"
|
||||||
|
fi
|
||||||
|
__awg_profiles+="${__sep}{\"id\":\"${__id}\",\"label\":\"${__label}\",\"container\":\"${__awg_name}\",\"confPath\":\"/opt/amnezia/awg/awg0.conf\",\"clientsPath\":\"/opt/amnezia/awg/clientsTable\",\"iface\":\"awg0\",\"wgBinary\":\"awg\",\"pskPath\":\"/opt/amnezia/awg/wireguard_psk.key\"}"
|
||||||
|
__sep=","
|
||||||
|
done <<<"${__awg_names}"
|
||||||
|
__awg_profiles+="]"
|
||||||
|
AWG_PROFILES="${__awg_profiles}"
|
||||||
|
umask 077
|
||||||
|
printf '%s\n' "${AWG_PROFILES}" >"${AWG_PROFILE_SNAPSHOT}" 2>/dev/null || true
|
||||||
|
echo "→ AWG_PROFILES авто-собран из контейнеров amnezia-awg*: ${AWG_PROFILE_SNAPSHOT}"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PREV_CONTAINER_ENV=""
|
|
||||||
if docker inspect "${CONTAINER_NAME}" >/dev/null 2>&1; then
|
|
||||||
PREV_CONTAINER_ENV="$(docker inspect "${CONTAINER_NAME}" --format '{{range .Config.Env}}{{println .}}{{end}}' 2>/dev/null || true)"
|
|
||||||
fi
|
|
||||||
for __ui_var in UI_HIDE_SECTIONS UI_HIDE_USERS UI_HIDE_WARP UI_HIDE_CASCADE UI_HIDE_MTPROTO WARP_SSH_INSTALL_DIR; do
|
for __ui_var in UI_HIDE_SECTIONS UI_HIDE_USERS UI_HIDE_WARP UI_HIDE_CASCADE UI_HIDE_MTPROTO WARP_SSH_INSTALL_DIR; do
|
||||||
if [[ -z "${!__ui_var:-}" ]] && [[ -n "${PREV_CONTAINER_ENV}" ]]; then
|
if [[ -z "${!__ui_var:-}" ]] && [[ -n "${PREV_CONTAINER_ENV}" ]]; then
|
||||||
PREV_VAL=""
|
PREV_VAL=""
|
||||||
|
|||||||
Reference in New Issue
Block a user