From 9e1144d310e064b4e73476aeeca5c550a44ddce1 Mon Sep 17 00:00:00 2001 From: phobos Date: Sat, 30 May 2026 14:29:50 +0300 Subject: [PATCH] Versioning: VERSION file, phobos-update (update/rollback), panel version+update UI --- VERSION | 1 + app.py | 41 ++++++++++++++++++++++++ install.sh | 2 ++ update.sh | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 138 insertions(+) create mode 100644 VERSION create mode 100755 update.sh diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..3eefcb9 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.0.0 diff --git a/app.py b/app.py index 805d15e..7b6f06f 100644 --- a/app.py +++ b/app.py @@ -403,6 +403,23 @@ def generate_failover_conf_for_client(client_id): return "\n".join(lines) + "\n" +def panel_version(): + try: + return open(os.path.join(PANEL_DIR, ".version")).read().strip() + except Exception: + return "unknown" + + +def run_update(arg): + import subprocess + try: + r = subprocess.run(["/opt/Phobos/server/update.sh", arg], + capture_output=True, text=True, timeout=150) + return (r.stdout + r.stderr)[-1200:] + except Exception as e: + return "update error: " + str(e) + + def build_phone_config(cid, mode="android"): """Assemble a phone client config from the client's files. android = WireGuard + [instance] obfuscator -> phobos:// link (PhobosWG app). @@ -1088,6 +1105,16 @@ def labels_page(): def settings_page(): s = load_settings() msg = "" + if request.method == "POST" and request.form.get("action") in ("update", "rollback"): + if request.form.get("action") == "update": + _out = run_update(request.form.get("target", "").strip() or "main") + else: + _out = run_update("--rollback") + s = load_settings() + return render(f'''
{nav("settings")}
+

{tr("Результат", "Result")}

+
{_out}
+ {tr("← к настройкам", "← back to settings")}
''') if request.method == "POST": new_pass = request.form.get("admin_pass", "").strip() if new_pass: @@ -1116,6 +1143,20 @@ def settings_page(): +
+

{tr("Версия и обновления","Version & updates")} {hlp("Скачивает свежие файлы PCA-слоя (панель + скрипты) с GitHub и перезапускает панель. Ключи WireGuard, server.env и клиенты НЕ трогаются. Пусто или main = последняя версия; можно указать тег (например v1.1.0). Откат восстанавливает предыдущую версию из автоматического бэкапа.", "Fetches the latest PCA files (panel + scripts) from GitHub and restarts the panel. WireGuard keys, server.env and clients are NOT touched. Empty or main = latest; you can pass a tag (e.g. v1.1.0). Rollback restores the previous version from an automatic backup.")}

+

{tr("Установленная версия","Installed version")}: {panel_version()}

+
+ + + +
+
+ + +
+
+

{tr("Информация о сервере","Server info")}

diff --git a/install.sh b/install.sh index b436aca..3cd789e 100755 --- a/install.sh +++ b/install.sh @@ -171,6 +171,8 @@ fetch overlay/phobos-pull.sh "$PHOBOS_DIR/repo/client/templat fetch server/phobos-health.sh "$PHOBOS_DIR/server/phobos-health.sh" && chmod +x "$PHOBOS_DIR/server/phobos-health.sh" fetch server/phobos-pull.sh "$PHOBOS_DIR/server/phobos-pull.sh" && chmod +x "$PHOBOS_DIR/server/phobos-pull.sh" fetch server/phobos-router-watchdog.py "$PHOBOS_DIR/server/phobos-router-watchdog.py" +fetch update.sh "$PHOBOS_DIR/server/update.sh" && chmod +x "$PHOBOS_DIR/server/update.sh" && ln -sf "$PHOBOS_DIR/server/update.sh" /usr/local/bin/phobos-update +mkdir -p "$PANEL_DIR"; fetch VERSION "$PANEL_DIR/.version" 2>/dev/null || true [ -f "$PHOBOS_DIR/tokens/tokens.json" ] || echo '[]' > "$PHOBOS_DIR/tokens/tokens.json" # ── 7. web panel ── diff --git a/update.sh b/update.sh new file mode 100755 index 0000000..17a2bbe --- /dev/null +++ b/update.sh @@ -0,0 +1,94 @@ +#!/bin/bash +# ============================================================ +# PCA Phobos — updater / rollback +# +# phobos-update # обновить до последней версии (main) +# phobos-update v1.1.0 # обновить до конкретной версии (git tag) +# phobos-update --rollback # откатить на предыдущую версию (из бэкапа) +# phobos-update --version # показать установленную и последнюю версию +# phobos-update --list # список бэкапов для отката +# +# Обновляет ТОЛЬКО PCA-слой (панель + скрипты онбординга/служебные). +# НЕ трогает ключи WireGuard, server.env, клиентов — они сохраняются. +# Перед каждым обновлением делает бэкап; откат восстанавливает его. +# ============================================================ +set -e +PHOBOS_DIR=/opt/Phobos +PANEL_DIR=/opt/phobos-panel +REPO=andrey271192/PCA_Phobos +RAW="https://raw.githubusercontent.com/$REPO" +BACKUPS="$PHOBOS_DIR/updates" +VERFILE="$PANEL_DIR/.version" +CUR=$(cat "$VERFILE" 2>/dev/null || echo "unknown") + +managed_files() { +cat </dev/null | tr -d ' \r\n'; } + +do_backup() { + local dir="$BACKUPS/${CUR}-$(date +%Y%m%d-%H%M%S)" + mkdir -p "$dir" + managed_files | while IFS='|' read -r lp rp; do + [ -f "$lp" ] && install -D "$lp" "$dir/$rp" 2>/dev/null || true + done + echo "$CUR" > "$dir/.fromversion" + echo "$dir" +} + +apply_ref() { + local ref="$1" + managed_files | while IFS='|' read -r lp rp; do + local tmp; tmp=$(mktemp) + if curl -fsSL -m25 "$RAW/$ref/$rp" -o "$tmp" && [ -s "$tmp" ]; then + mkdir -p "$(dirname "$lp")"; mv "$tmp" "$lp" + case "$lp" in *.sh|*.py) chmod +x "$lp" 2>/dev/null || true;; esac + else + rm -f "$tmp"; echo " WARN: не удалось скачать $rp (пропуск)" + fi + done +} + +case "${1:-}" in + --version|-v) + echo "Установлено: $CUR" + echo "Доступно: $(latest_version)" + ;; + --list) + echo "Бэкапы (для отката):" + ls -dt "$BACKUPS"/*/ 2>/dev/null | sed 's#.*/updates/##' || echo " нет" + ;; + --rollback) + last=$(ls -dt "$BACKUPS"/*/ 2>/dev/null | head -1) + [ -z "$last" ] && { echo "Нет бэкапа для отката."; exit 1; } + fromver=$(cat "$last/.fromversion" 2>/dev/null || echo "?") + echo "Откат на $fromver ($last)" + managed_files | while IFS='|' read -r lp rp; do + [ -f "$last/$rp" ] && { mkdir -p "$(dirname "$lp")"; cp "$last/$rp" "$lp"; chmod +x "$lp" 2>/dev/null || true; } + done + echo "$fromver" > "$VERFILE" + systemctl restart phobos-panel 2>/dev/null || true + echo "Откат выполнен -> $fromver" + ;; + *) + ref="${1:-main}"; [ "$ref" = "latest" ] && ref="main" + target=$(curl -fsSL -m10 "$RAW/$ref/VERSION" 2>/dev/null | tr -d ' \r\n'); [ -z "$target" ] && target="$ref" + echo "Текущая: $CUR -> целевая: $target ($ref)" + b=$(do_backup); echo "Бэкап: $b" + apply_ref "$ref" + echo "$target" > "$VERFILE" + systemctl restart phobos-panel 2>/dev/null || true + echo "Обновлено до $target. Откат: phobos-update --rollback" + ;; +esac