Files
pvemanager/CHANGELOG.ru.md
Dilshod Rasulov dc53c415db
Some checks failed
Deploy to Production / Trigger production update (push) Failing after 10s
SonarCloud / SonarCloud Analysis (push) Failing after 2m40s
docs: changelog entry for the LXC console fix and removed endpoint
Flags the removal of GET /api/{server_id}/container/{vmid}/terminal as a
breaking change and documents the termproxy task failures and the black
console screen it came with.
2026-08-21 21:13:15 +05:00

79 KiB
Raw Blame History

История изменений

Все заметные изменения в PVEmanager документируются в этом файле.


[Unreleased]

🖥️ Консоль LXC — ошибки termproxy и чёрный экран

  • ⚠️ Ломающее изменение: эндпоинт GET /api/{server_id}/container/{vmid}/terminal удалён. WebSocket-эндпоинт /proxmox/ws/terminal/{server_id}/{node}/{vmid} создаёт termproxy-сессию сам, поэтому REST-вызов не использовался панелью и при каждом вызове оставлял на ноде висячую сессию. Внешним клиентам следует открывать WebSocket напрямую
  • Открытие консоли LXC больше не оставляет на ноде задачу с ошибкой — failed waiting for client: timed out / TASK ERROR: command '/usr/bin/termproxy 5900 ... vzctlconsole<id>' failed. Страница консоли создавала termproxy-сессию через REST (используя из ответа только поле node и выбрасывая порт и тикет), затем вторую через WebSocket-эндпоинт и подключалась ко второй. К первой не подключался никто — Proxmox ждал клиента ~10 секунд и завершал задачу ошибкой
  • Консоль больше не показывает чёрный экран при статусе «connected» в dev-режиме — React StrictMode монтирует эффект дважды, а connect-функции асинхронны, поэтому cleanup эффекта срабатывал до того, как они записывали wsRef/termRef, и ничего не чистил. В одном контейнере оказывалось два xterm: видимый был осиротевшим, а живой уходил за границу области с overflow-hidden. Теперь у сессии есть флаг отмены, а монтирование и кнопка «Переподключиться» идут через единую точку входа, которая сначала гасит предыдущую сессию. Тот же флаг применён к странице shell ноды

🔍 Диалог NFS-хранилища — поиск доступных экспортов

  • Добавлена кнопка поиска экспортов рядом с полем «Сервер» при добавлении NFS-хранилища — вызывает GET /nodes/{node}/scan/nfs Proxmox и превращает поле пути экспорта из текстового ввода в выпадающий список с реальными экспортами, найденными на целевом сервере, вместо ручного набора пути наугад
  • Новый эндпоинт GET /api/backups/scan-nfs/{server_id}?server=<ip> на бэкенде — сканирование выполняется через первую доступную ноду сервера

[v1.17.0] - 2026-08-20

💾 Перенос дисков LXC-контейнера на другое хранилище

  • Перенос диска теперь работает для LXC, а не только для QEMU-ВМ — раньше действие было жёстко привязано к VM-эндпоинту move_disk и было недостижимо для контейнеров (нет вкладки «Оборудование», а детектор строк диска распознавал только имена устройств ВМ). rootfs/mp\d+ теперь распознаются как дисковые устройства LXC, на вкладку «Настройки» для LXC-инстансов добавлена карточка «Перенести диск»
  • Новый эндпоинт POST /api/{server_id}/container/{vmid}/disk/move вызывает lxc/{vmid}/move_volume Proxmox; список целевых хранилищ теперь фильтруется по поддерживаемому типу содержимого (rootdir для LXC, images для ВМ) вместо показа всех хранилищ подряд
  • Перенос заблокирован на запущенных контейнерах — с пошаговым сценарием вместо ошибки — Proxmox отклоняет move_volume на работающем LXC (move_disk у QEMU работает «на живую», move_volume у LXC — нет). Теперь такая попытка открывает диалог подтверждения, который останавливает контейнер, переносит диск и запускает его обратно, показывая прогресс на каждом шаге; контейнер перезапускается в любом случае, даже если сам перенос завершился ошибкой. Для ВМ и уже остановленных контейнеров показывается обычный диалог подтверждения

📊 Список инстансов — сворачиваемая панель метрик

  • CPU/RAM/Диск/Сеть/Диск I/O/Аптайм убраны из всегда видимых колонок таблицы в раскрывающуюся панель под строкой, которая открывается кликом по имени инстанса — по образцу дисклоужер-паттерна из VMmanager. В панели появилась ссылка «Параметры», ведущая прямо на вкладку настроек инстанса, и более понятные карточки для скорости сети/диска
  • Полосы vCPU/RAM расширены и увеличены (ширина полосы и размер шрифта подписи/деталей) для более быстрого визуального восприятия в свёрнутой панели

✨ Страница «Топология сети»

  • Новая страница /topology — интерактивная карта инфраструктуры: панель → кластер → нода Proxmox → VM/LXC на базе React Flow. На карточках нод — живые индикаторы CPU/RAM, у гостей видны статус, IP, bridge/VLAN и теги
  • Фильтры — сужение графа до одного подключения, фильтр гостей по статусу (все / запущенные / остановленные) и схлопывание гостей ноды в один узел при превышении настраиваемого порога (запоминается в браузере); свернувшуюся ноду можно раскрыть по отдельности
  • Инструменты холста — зум, панорама, вписать в экран, полноэкранный режим, миникарта, легенда и экспорт всего графа в PNG/SVG
  • Новый API GET /proxmox/api/network/topology — один агрегированный запрос вместо обхода серверов/нод/SDN/VM; требует право network:view, учитывает рабочие области и изоляцию VM по владельцу. Недоступное подключение отдаёт данные из кэша с предупреждением, а не ломает страницу
  • Парсер netN — строки сетевых карт гостей теперь разбираются (bridge, VLAN-тег, MAC, модель, firewall, rate, MTU) для обоих диалектов, QEMU и LXC; доступно через include_nics=true

[v1.16.1] - 2026-08-17

🎨 Интерфейс

  • Шрифт Inter Variable — фронтенд переведён на вариативный шрифт Inter с увеличенной шкалой размеров для более чёткой и единообразной типографики по всей панели

🔧 Исправления деплоя

  • CLI pve устанавливается без root — deploy.sh теперь пробует sudo для установки CLI в /usr/local/bin, а при недоступности root откатывается на ~/.local/bin (с автоматической настройкой PATH); ранее авто-установка молча пропускалась, и команда pve оставалась недоступной после деплоя
  • Права файла CLI pve — установленный скрипт теперь явно получает права 755 вместо зависимости от umask; ранее sudo cp мог оставить файл без права на чтение для не-root пользователей, вызывая «Permission denied» при каждом запуске
  • SSL больше не откатывается при деплое — verify_nginx_running теперь использует docker compose ps --format '{{.State}}' (возвращает "running" мгновенно) вместо grep по человекочитаемому столбцу STATUS (который показывает "Up Xs (health: starting)" первые 30 секунд до первого healthcheck); со старым таймаутом 20 секунд функция всегда завершалась по таймауту и откатывала конфиг на HTTP, хотя SSL-сертификат был успешно получен

[v1.16.0] - 2026-08-14

🌍 i18n — Полный проход по переводам

Масштабная зачистка оставшихся захардкоженных и непереведённых строк интерфейса:

  • Дашборд и инстансы — диалоги действий, карточки ресурсов, метки статусов и описания массовых операций полностью переведены (EN + RU)
  • Страница «Образы» — браузер образов, диалоги загрузки/импорта, менеджер зеркал — полный перевод
  • App Store — добавлены недостающие ключи для мастера установки, состояний операций и меток страницы приложения
  • Ноды — метки силовых действий (Запуск, Перезагрузка, Выключение) и общие строки администрирования нод переведены
  • Скрипты и сертификаты — разделы каталога скриптов и TLS-сертификатов добавлены в оба локейла
  • Роли — метки всех RBAC-разрешений, включая remote_migrate, переведены на русский
  • Графики, мастер, хранилища — ранее захардкоженные русские строки вынесены в файлы локали и переведены на оба языка
  • Массовая миграция и Access realm — добавлены ключи для действий массовой миграции и меток реалмов Proxmox
  • Критические исправления — несколько строк, молча откатывавшихся на английский в русском интерфейсе, теперь корректно отображаются на русском

🔑 SSH-ключи

  • Смена SSH-ключей при смене владельца — когда администратор переназначает VM/LXC другому пользователю, инстанс автоматически получает SSH-ключ нового владельца (ключ предыдущего при этом удаляется), так что учётные данные для доступа всегда соответствуют текущему владельцу

📦 Облачные образы

  • patch-cloud-images.sh — новый вспомогательный скрипт, который патчит официальные облачные образы, добавляя qemu-guest-agent, и публикует их в GitHub-зеркало; позволяет получить живые метрики и функции гостевого агента без установки агента после деплоя
  • Каталог образов amd64 — записи образов amd64 по умолчанию теперь указывают на GitHub-зеркало (с предустановленным qemu-guest-agent) и включают контрольные суммы sha256 для проверки целостности

🐛 Исправления

  • Обзор дисков VM — loop-устройства (/dev/loop*) и системные разделы (/dev/sr*, /boot, /snap) включались в карточки использования диска; теперь они отфильтровываются и отображаются только диски с данными
  • Повторная загрузка облачных образов — закешированные импортированные образы раздавались с диска даже при наличии контрольной суммы и изменении файла на удалённом источнике; теперь кеш инвалидируется при несовпадении суммы
  • Иконка видимости пароля — значок глаза во всех полях пароля (вход, смена пароля, парольная фраза SSH-ключа, диалоги API-ключей) был инвертирован: открытый глаз отображался, когда значение было скрыто, и наоборот; теперь состояние иконки корректно отражает видимость значения

[v1.15.0] - 2026-08-13

🚀 Установка одной командой

  • bootstrap.sh — устанавливает панель одной командой как на обычном хосте Debian/Ubuntu, так и напрямую на хосте Proxmox VE. На хосте PVE скрипт создаёт LXC на Debian 12, устанавливает панель внутри через существующий deploy.sh, создаёт локальный API-токен root@pam и регистрирует этот хост как первую ноду панели — пароль от Proxmox никуда не передаётся
  • Скрипт переживает сбой apt-get update из-за недоступного enterprise-репозитория на неподписанном хосте PVE вместо того, чтобы прерывать весь bootstrap ещё до установки git/curl
  • Регистрация хоста теперь идёт по правильному пути /proxmox/api/servers (раньше использовался /api/servers, отвечавший 404, — роутер Proxmox подключён под префиксом /proxmox)
  • Убран небезопасный дефолт pvemanager_secure_password для POSTGRES_PASSWORD в compose.yml — на любом пути установки .env с реальным паролем уже создаётся до запуска стека

💿 Образы и инстансы

  • Переработка извлечения/монтирования ISO — страница «Образы» теперь показывает реальные ISO-файлы, уже лежащие в хранилище ноды (включая те, что появились там до подключения ноды к панели); «Отсоединить» переименовано в «Извлечь», текущий смонтированный образ отображается прямо в списке выбора, а новый чекбокс «загрузка с диска» / «загрузка с этого ISO» управляет порядком загрузки при извлечении/монтировании
  • Применение нового порядка загрузки перезагружает гостевую систему через гибридный рестарт — штатное ACPI-выключение с откатом на принудительную остановку, затем запуск — что убирает таймаут ping гостя на свежеустановленной ОС, где ещё нет QEMU Guest Agent

🔒 RBAC и доступ

  • /profile отделён от /settings — настройки аккаунта (профиль, пароль, 2FA, SSH-ключи) переехали на собственную страницу /profile, не требующую никакого разрешения, и открываются из меню пользователя и Ctrl+K. Теперь отзыв setting:view, чтобы не пускать пользователя в настройки панели, больше не блокирует доступ к его собственному аккаунту. /settings по-прежнему скрывает общепанельные вкладки за setting:view, сохранение — за setting:update, безопасность — за setting:manage, а SMTP/Telegram — только для админов
  • Маршруты теперь защищены по правам, а не просто скрыты из сайдбара — раньше /users, /logs и /settings (и их вкладки) открывались по прямому переходу на URL кому угодно, а бэкенд лишь отвечал 403 на конкретные запросы; теперь пользователь без доступа перенаправляется на первую доступную ему страницу
  • Миграция 42 снимает setting:view с ролей, у которых нет также setting:update/setting:manage, — этот доступ раньше выдавался только ради общей страницы настроек, включавшей профиль

👤 Владение инстансами и квоты

  • Исправлено назначение владельца при создании — новые VM/LXC оставались с owner_id = NULL, потому что задача синхронизации, регистрирующая ещё клонирующуюся VM, опережала флоу деплоя и первой создавала запись в БД; теперь владелец проставляется и на этом пути обновления записи. VM, созданная админом от имени пользователя, теперь получает SSH-ключ именно этого пользователя, а не админа
  • Миграция для бэкфилла владельца у инстансов, созданных до исправления выше: владелец восстанавливается из deploy_tasks и audit_logs и проставляется только тогда, когда все доступные данные указывают на одного и того же существующего пользователя; неоднозначные случаи остаются без владельца — для них нужен ручной запуск assign_instances_owner.py
  • Кнопка «Создать инстанс» отключается, когда по какой-то квоте совсем не осталось свободного места, а не только отказывает внутри мастера — подсказка называет, какие именно лимиты исчерпаны (проверка пропускается для админов, чья личная квота не имеет отношения к инстансам, создаваемым для других)
  • Блокировка перед открытием мастера теперь отделена от блокировки внутри него: полностью исчерпанная квота не даёт открыть мастер вовсе; квота, которую превысит именно выбранная конфигурация, открывает мастер, но блокирует «Далее»/«Развернуть» с указанием превышенного показателя

🐛 Исправления

  • Продакшн-деплой не отключал открытые порты — ports: [] в compose.prod.yml на деле ничего не убирал (Compose при слиянии нескольких -f файлов не заменяет списковые поля, а объединяет их), поэтому SSL-деплой продолжал отвечать без шифрования на портах 8000/3001 параллельно с HTTPS. Исправлено через тег !reset
  • SSL-деплой сообщал о неудаче даже после успешного выпуска сертификата — проверка успеха не могла прочитать директорию certbot, принадлежащую root и имеющую права 0700, если деплой запускался не от root; теперь сертификат проверяется изнутри контейнера, а откат на HTTP выполняется только если nginx реально не поднялся с новым конфигом
  • Первая загрузка фронтенда могла показать пустую страницу — общий лимит частоты запросов (10r/s) применялся и к статике, отклоняя часть из ~86 подгружаемых чанков SPA с 503; после исправления этого проявился второй лимитер — limit_conn addr 10 ограничивал всю страницу 10 одновременными HTTP/2-потоками (браузер мультиплексирует всю загрузку страницы через одно соединение), давая тот же эффект пустой страницы. Теперь у статики отдельная зона лимита частоты, а оба лимита limit_conn подняты
  • Воркеры nginx не могли открыть достаточно файловых дескрипторов под worker_connections 2048 — дефолтный RLIMIT_NOFILE Docker в 1024 незаметно урезал реальный потолок вдвое; поднят до 8192
  • Убраны listen 443 ssl http2 (устарела с nginx 1.25.1) и ssl_stapling (у текущих сертификатов Let's Encrypt нет OCSP-респондера) — обе директивы выдавали предупреждения при периодическом reload nginx
  • Аптайм ноды показывался неверно в мультинодовых кластерах — карточка сервера брала Math.max по аптайму всех нод кластера вместо аптайма именно текущей, поэтому перезагрузка одной ноды могла по-прежнему показывать более высокий аптайм другой
  • Тост о завершении сессий никогда не переводился — сообщение собиралось на бэкенде на Python и возвращалось как есть, поэтому в русском интерфейсе показывалось "Terminated 0 sessions"; теперь количество возвращается отдельным полем, а фраза собирается на клиенте (для русского нужно четыре формы множественного числа против двух в английском)

[v1.14.0] - 2026-07-24

🐛 Исправления

  • Смена рабочей области не сбрасывала фильтры инстансов — фильтры по серверу, узлу и столбцам на странице «Инстансы» сохраняли значения, выбранные ещё в предыдущей рабочей области, из-за чего список VM новой области мог отфильтроваться до пустоты. Теперь при переключении рабочей области все эти фильтры сбрасываются
  • Фильтр по колонке «Узел» не обновлялся после первого рендера — список доступных узлов в нём был замемоизирован на объекте Column из TanStack, а этот объект сохраняет свою идентичность при обновлении данных таблицы, поэтому список замирал на тех узлах, что были видны при первом открытии — включая узлы серверов из уже покинутой рабочей области. Теперь значение читается напрямую из faceted-данных таблицы при каждом рендере

[v1.13.0] - 2026-07-24

🛒 App Store

  • Выбор хранилищ в golden-шаблоне — в диалоге «Золотой LXC-шаблон» текстовые поля для хранилища шаблона (vztmpl) и rootfs (rootdir) заменены на выпадающие списки, заполняемые реальными хранилищами выбранного сервера/ноды. По умолчанию подставляются local/local-lvm, если они есть, иначе — первое доступное хранилище

📜 Scripts

  • Поиск по названию в каталоге скриптов — фильтрация ручных, Git и Community-Scripts записей прямо на странице Scripts

[v1.12.0] - 2026-07-24

🔗 Кластер

  • Импорт существующего кластера — ноды, уже объединённые в кластер Proxmox в обход панели (через pvecm или веб-интерфейс Proxmox), теперь можно привязать прямо на странице «Кластер», а не только через собственный флоу панели «Создать»/«Присоединить». Обнаружение читает cluster/config/join на выбранной ноде, сопоставляет её nodelist с уже известными серверами панели по IP/hostname и привязывает совпавшие записи к этой группе кластера — никакая pvecm-операция не выполняется, меняется только учёт внутри панели

[v1.11.0] - 2026-07-24

🔌 Серверы и подключение

  • Автосоздание API-токенов — сервер можно подключить по логину и паролю: панель один раз аутентифицируется, создаёт на ноде собственный API-токен (privsep=0) и дальше работает по нему. Токен отзывается из UI Proxmox, не даёт SSH- и веб-логина и виден в аудите PVE под своим именем. Уже подключённые по паролю серверы переводятся на токен без переподключения кнопкой «Перевести на API-токен»
  • Отклонённые учётные данные vs. недоступная нода — раньше офлайн-сервер показывал единое «Не удалось подключиться»; теперь протухший/отклонённый токен (401, обычно остаётся после того, как вступление ноды в кластер заменяет user.cfg/token.cfg) получает собственное состояние auth_error с подсказкой о причине
  • Доступность storage по нодам — storage может быть объявлен на весь кластер, но отсутствовать на конкретной ноде (нет volume group или пула); теперь это видно, а не скрыто
  • Единые бейджи статуса — все списки серверов (включая топологию кластера и назначение пользователей) рендерят один ServerStatusBadge вместо повторяющегося тернарника online/offline
  • Списки в рамках рабочего пространства — /api/cluster/topology и /api/resources/all теперь учитывают активное рабочее пространство, а не отдают все серверы панели; живые метрики собираются параллельно, а не последовательно, поэтому один недоступный кластер больше не тормозит весь запрос

📊 Мониторинг

  • Вкладка «Графики» у ноды — CPU, IO delay, память, load average, сеть, swap и корневая ФС на странице ноды, с пресетами 1h/24h/7d/30d/1y

💿 Образы и создание инстансов

  • Загрузка локального файла — ISO или vztmpl можно загрузить прямо со своего компьютера в storage ноды, в дополнение к загрузке по URL
  • Пустая VM для установки с ISO — новый тип инстанса в мастере создания: VM с пустым диском и смонтированным первым по порядку загрузки ISO, гость сразу попадает в установщик через noVNC; выбор Windows задаёт OVMF, SATA-диск и сетевую карту e1000
  • Загрузка ISO — ISO можно скачать на ноду по URL со страницы «Образы» или из сохранённого зеркала (зеркала теперь принимают kind=iso)

🔄 Реалтайм и UX

  • Списки инстансов и рабочих пространств обновляются сразу после назначения серверов/пользователей, деплоя или удаления VM/контейнера — без ручного обновления
  • Обзор ноды больше не мигает «нет данных», пока список инстансов ещё загружается

🛠 Надёжность

  • Самообновление панели восстанавливается после зависшей пересборки вместо вечного «restarting — 80%»; по таймауту показывается понятное состояние «failed» со ссылкой на логи update-сервиса хоста

🎨 Тема

  • Поверхности тёмной темы (фон, карточки, popover, сайдбар, границы) сдвинуты с нейтрального оттенка на сине-графитовый

📖 Документация

  • Расширен раздел RBAC/Security (формат прав, порядок проверки, полный каталог прав, карта прав по страницам), добавлен полный русский перевод — WIKI.ru.md

[v1.10.2] - 2026-07-23

🐛 Исправления

  • Шаблоны — после авто-импорта показывается понятное сообщение вместо undefined

[v1.10.0] - 2026-07-22

🧭 Навигация и инстансы

  • Командная палитра (Ctrl+K) — палитра с поиском поверх общего реестра пунктов навигации (со своим store), позволяет перейти на любую страницу с клавиатуры
  • Единая навигация — боковое меню и командная палитра работают от одного общего реестра nav-элементов
  • Расширенное меню инстанса — в меню строки инстанса добавлены Параметры, Мигрировать, Изменить ресурсы, Создать резервную копию (новый BackupDialog) и Удалить; меню больше не закрывается при каждом живом обновлении списка (стабильные columns + getRowId)
  • Реорганизация вкладок инстанса — для VM «Вычислительные ресурсы», «Опции CPU», «Управление дисками» и «Изменение размера диска» перенесены со вкладки Настройки на Оборудование; у LXC (где вкладки «Оборудование» нет) они остаются в Настройках. Общие карточки вынесены в ResourceCards.tsx
  • Новые общие UI-примитивы — alert, breadcrumb, checkbox, progress, switch, textarea; ключи локализации RU/EN для новых пунктов меню и бэкапа

🛒 App Store

  • Глобальный трей свёрнутых операций — свёрнутые долгие операции (установка приложения, сборка золотого шаблона) теперь живут в глобальном zustand-сторе (persist в localStorage) и рендерятся треем MinimizedOpsTray в layout приложения, а не самим диалогом:
    • плашка переживает навигацию между страницами и перезагрузку вкладки; трей опрашивает прогресс сам (REST, каждые 3 с) независимо от диалога
    • клик по плашке возвращает на страницу операции и разворачивает диалог — установка продолжается в InstallWizard (resume-режим через navigation state), шаблон открывает диалог золотого шаблона с предвыбранным сервером
    • «Свернуть» добавляет операцию в трей и закрывает диалог; крестик на плашке только убирает плашку (операция продолжается на сервере); плашки несуществующих операций (404 после перезагрузки) трей убирает сам
  • Файлы данных приложения — файлы, поставляемые вместе с приложением каталога (data_files), доставляются до compose up; учитываются APP_PASSWORD / default_credentials для Umbrel
  • Сворачиваемые диалоги установки/сборки — долгие операции можно свернуть через MinimizableDialog
  • Надёжность установки/удаления:
    • teardown — отсутствующий в Proxmox CT считается удалённым, поэтому orphaned-приложение теперь можно удалить из БД
    • install — поиск VMID сдвигается мимо занятых записей (nextid не резервирует номер, из-за чего retry мог подхватить чужой контейнер)
    • retry — параметры установки (cores/memory/disk/storage/bridge/ip_config/port) сохраняются в installed_apps.install_params (JSONB, новая миграция) и переиспользуются при повторе вместо жёстких дефолтов
    • reconcile — недоступный сервер больше не помечает все свои приложения orphaned
    • update — реально опубликованный порт фиксируется в БД (url/health)
    • .env — значения с # кавычатся (dotenv-парсер обрезал их как inline-комментарий)
    • порт 80, выбранный явно в мастере, публикуется как есть
    • useCatalog — available_only включён в query key (устранена коллизия кэша)

🔒 Изоляция по владельцу

  • Живые ресурсы Proxmox теперь фильтруются по владельцу — список инстансов (/api/virtual-machines) уже фильтровался по owner_id, но эндпоинты живых ресурсов /api/resources/all (дашборд) и /api/{server_id}/resources (страница ноды/сервера) отдавали все VM/LXC. Обычный пользователь (proxmox.view) через страницу ноды видел чужие инстансы. Оба эндпоинта теперь фильтруют VM/LXC по владельцу для непривилегированных (сверка vmid с кэшем vm_instances); админы и роли с vm:manage по-прежнему видят всё
  • assign_instances_owner.py — скрипт массового назначения владельца существующим инстансам с owner_id = NULL (синхронизированным из Proxmox до появления владения)

🐛 Исправления

  • Очистка кэша React Query при login/logout — при входе под другим пользователем в той же вкладке React Query больше не отдаёт закэшированные данные предыдущего пользователя (список инстансов и др.) до жёсткой перезагрузки. queryClient вынесен из App.tsx в lib/query-client.ts (доступен вне React), а auth-store вызывает queryClient.clear() при успешном входе и при выходе

[v1.9.1] - 2026-07-17

🛒 App Store

  • Золотой шаблон отдельно на каждый сервер — золотой vztmpl теперь хранится и разрешается по server_id Proxmox, а не одним глобальным указателем; сборка на одном сервере больше не перезаписывает/ломает шаблон, настроенный для другого. APPSTORE_GOLDEN_TEMPLATE теперь только последний запасной вариант для серверов без собственной сборки. Миграция 37 добавляет app_operations.server_id
  • Исправление сборки золотого шаблона — автоматическая сборка (App Store → золотой шаблон) больше не падает на финальном шаге экспорта vzdump (unable to parse directory volume name 'vztmpl/probe')
  • Надёжность DNS — LXC приложений App Store (и CT сборки золотого шаблона) теперь получают явный nameserver (APPSTORE_NAMESERVER, по умолчанию 1.1.1.1 8.8.8.8) вместо наследования резолвера ноды — это устранило таймауты при загрузке образов на нодах, чей DNS доступен только с хоста (например, через Tailscale)
  • Права bind-mount — директории данных из volumes: приложения (${APP_DATA_DIR}/... или относительные пути) заранее создаются перед up, что устраняет Permission denied для контейнеров, пишущих под non-root пользователем (например, MariaDB)
  • Устранена гонка удаления/переустановки — удаление приложения теперь ждёт фактического подтверждения Proxmox, что контейнер удалён (до 30 мин, покрывает медленную очистку диска), прежде чем освободить VMID, вместо предположения об успехе после короткого таймаута
  • Retry блокировки pct create — временные ошибки «can't lock file ... got lock» сразу после удаления теперь повторяются несколько раз, а не роняют установку
  • Полный вывод ошибки — упавшие шаги пайплайна теперь показывают последние 4000 символов вывода команды (раньше первые 2000), так что реальная причина не теряется под шумом прогресса docker compose pull
  • UI ошибки установки — блок ошибки в диалоге установки теперь переносит длинный неразрывный текст (дайджесты образов, пути) и скроллится в своих границах вместо растягивания диалога

[v1.9.0] - 2026-07-09

🌐 IPAM

  • Сети привязаны к серверу/ноде и рабочему пространству — сеть IPAM теперь можно привязать к конкретному серверу/ноде Proxmox и к рабочему пространству; каждое пространство использует одну подсеть, а сеть автоматически выбирается активным пространством в мастерах создания инстанса и установки App Store, так что в типичном случае пользователю больше не нужно выбирать сеть вручную
  • Автовыбор в мастерах — мастера развёртывания определяют целевую сеть/пул из текущего контекста и подставляют их; отсутствие привязки откатывается к ручному выбору
  • Миграция: столбцы привязки сети IPAM к рабочему пространству + флаг «по умолчанию» через backend/migrations/migrations.py

🔧 Ноды

  • Домен/FQDN в поле хоста Proxmox — форма добавления/редактирования сервера Proxmox теперь принимает доменное имя или FQDN (не только IP), которое резолвится при подключении

[v1.8.1] - 2026-07-09

🛒 App Store

  • Umbrel как второй источник каталога — каталог теперь мультиисточниковый: наряду с runtipi/runtipi-appstore можно включить getumbrel/umbrel-apps (~380 приложений). Источники настраиваются через APPSTORE_SOURCES (через запятую, по умолчанию runtipi); id приложений Umbrel неймспейсятся (umbrel-<id>), чтобы каталоги не конфликтовали
  • Compose-адаптер Umbrel — установка понимает манифесты Umbrel: порт контейнера берётся из сервиса app_proxy (APP_PORT), runtime-сервисы Umbrel (app_proxy, tor) вырезаются, повисшие depends_on очищаются, а порт основного сервиса публикуется на хосте LXC, чтобы health-check прошёл; поведение Runtipi не меняется
  • Иконки Umbrel — иконки берутся из отдельного репозитория getumbrel/umbrel-apps-gallery (<app-id>/icon.svg) при синке и кэшируются как логотипы Runtipi; сбой загрузки галереи никогда не роняет синк каталога
  • Мультиисточниковый синк — каждый источник синкается независимо (сетевой сбой одного не отменяет другие), а проход исчез → недоступен ограничен своим источником, так что синк Runtipi никогда не трогает строки Umbrel
  • Фильтр источника и бейдж (UI) — App Store получает фильтр по источнику и бейдж источника на карточке, показываемые только когда включено больше одного источника; метаданные каталога теперь отдают доступные sources
  • Кастомный порт установки — мастер установки принимает произвольный порт хоста (валидация 1..65535), переопределяющий дефолт каталога
  • Мгновенная чистка инстанса — удаление приложения сразу мягко удаляет связанный VM-инстанс для отзывчивости UI
  • Модель данных и настройки — столбец catalog_apps.source (миграция 34); новые env-настройки APPSTORE_SOURCES, UMBREL_APPSTORE_REPO, UMBREL_APPSTORE_REF, UMBREL_APPSTORE_GALLERY_REPO

[v1.8.0] - 2026-07-07

🛒 App Store

  • Каталог self-hosted приложений с установкой в один клик — новый модуль App Store: каждое приложение разворачивается в собственном unprivileged LXC-контейнере с Docker Compose (1 приложение = 1 LXC). Каталог импортируется из репозитория runtipi/runtipi-appstore (~265 приложений проходят фильтр)
  • Catalog Service — импорт метаданных, логотипов, описаний и compose-файлов в новую таблицу catalog_apps; идемпотентная синхронизация (кнопка Обновить каталог + автоматически раз в 24 ч через APScheduler); битый config.json пропускается, не роняя весь синк; флаг update_available вычисляется по tipi_version
  • Пайплайн установки — клон золотого LXC-шаблона → pct push compose/.env → docker compose up -d → HTTP health-check, с живым журналом шагов по WebSocket, динамическим рендером form_fields (text/password/email/number/boolean/fqdn), автогенерацией random-секретов и хранением env в зашифрованном виде (Fernet); сгенерированные учётные данные показываются один раз
  • Управление жизненным циклом — start / stop / restart / логи (docker compose logs) / удаление, плюс фоновая реконсиляция состояния каждые 60 с (контейнеры, удалённые мимо PVEmanager, помечаются orphaned)
  • Обновление и откат — при обновлении создаётся pre-update снапшот Proxmox, затем docker compose pull && up -d с health-check; откат восстанавливает снапшот (вместе с данными); хранится только последний pre-update снапшот
  • UI — сетка каталога (поиск, категории), страница приложения с дисклеймером об источнике и превью compose, мастер установки с расширенными параметрами LXC и живым прогрессом, экран управления Мои приложения; локали RU/EN; атрибуция Powered by Runtipi appstore
  • Безопасность — только unprivileged LXC; pct exec / pct push через SSH с доставкой файлов через base64 и экранированием значений .env (без shell-инъекций); новые права RBAC app:view / app:install / app:manage
  • Модель данных и настройки — таблицы catalog_apps, installed_apps, app_operations (миграции 31–32); новые env-настройки APPSTORE_GOLDEN_TEMPLATE, RUNTIPI_APPSTORE_REF, APPSTORE_DATA_DIR, CATALOG_SYNC_INTERVAL_HOURS, APPSTORE_HOST_ARCH
  • Документация — docs/golden-template.md (подготовка золотого LXC-шаблона) и docs/appstore-poc.md / appstore-catalog.md / appstore-engine.md

[v1.7.0] - 2026-06-26

🎯 Квоты

  • Квоты ресурсов на пользователя — ограничение количества инстансов и суммарных vCPU, RAM и диска по всем VM/LXC пользователя. Отсутствие записи квоты или значение NULL в столбце означает безлимит по этой метрике, поэтому администраторы и пользователи без ограничений никогда не блокируются
    • Бэкенд: новая модель UserQuota (таблица user_quotas) и quota_service (get_user_usage / check_quota); использование вычисляется из кэша vm_instances (owner_id) — учитываются только не удалённые и не шаблонные инстансы; при превышении лимита развёртывание VM/LXC прерывается с HTTP 429
    • Права: новые RBAC-разрешения quota:view и quota:manage (категория Управление пользователями, оба требуют user:view)
    • API: GET/PUT /api/users/{id}/quota (админ) возвращает лимиты вместе с текущим использованием; GET /api/quota (self-service) возвращает собственные лимиты и использование текущего пользователя
    • Фронтенд: диалог квот с полосами использования на странице Пользователей (админ); карточка собственных лимитов на странице Настроек; подсказка об остатке квоты на шаге конфигурации в мастере создания инстанса; хуки useUserQuota / useSetUserQuota / useMyQuota; локали RU/EN
    • Миграция: таблица user_quotas добавлена через backend/migrations/migrations.py

[v1.6.0] - 2026-06-23

✨ Images

  • Каталог облачных образов — просмотр и скачивание образов ОС из нескольких источников (стандартное зеркало Proxmox и кастомные зеркала); образы загружаются на хранилище Proxmox
  • Автоматическая конвертация в шаблон VM — опция автоматической конвертации загруженного .qcow2 образа в шаблон VM Proxmox после завершения скачивания
  • Кастомные зеркала для администраторов — интерфейс, доступный только администраторам, для добавления, редактирования, просмотра и удаления источников-зеркал для поиска образов
  • Фильтрация образов по архитектуре — образы фильтруются по архитектуре платформы узла (x86-64, aarch64); дефолт-архитектура соответствует платформе выбранного узла
  • Загрузка образов с прогрессом — диалог загрузки с отслеживанием прогресса в реальном времени и опциональным переключателем конвертации в шаблон

🐛 Исправления

  • Нормализация расширения файла при импорте образа — расширение .img автоматически нормализуется в .qcow2 при импорте
  • Санитизация имени VM при импорте образа — имена VM санитизируются при импорте образа для предотвращения ошибок создания; улучшенные сообщения об ошибках для прозрачной обратной связи с пользователем

[v1.5.2-1] - 2026-06-20

🖥️ Интерфейс

  • Стилизованные диалоги подтверждения — все нативные браузерные confirm() заменены единым тематическим модальным окном (ConfirmDialog). Добавлен глобальный ConfirmDialogProvider + хук useConfirm (Promise-based API). Затронуто: обновление панели, удаление шаблона/сервера/хранилища/SSH-ключа/HA-ресурса/SDN-зоны/VNet/подсети/IPAM-пула/аллокации, применение/откат сетевых изменений, очистка IPAM-сирот (16 мест в 11 файлах).

[v1.5.2] - 2026-06-20

📊 Метрики

  • Реальное время: заполнение дисков VM, IOPS и сетевой I/O — живые данные по каждому диску, скорости чтения/записи и сетевого ввода/вывода добавлены на вкладку Overview инстанса, в список инстансов и виджет топ-нагруженных на дашборде
    • Backend: get_vm_fsinfo() запрашивает данные файловых систем через QEMU guest agent; metrics_broadcaster вычисляет скорости I/O (байт/с) из накопленных счётчиков; цикл обновления списка инстансов теперь опрашивает каждую запущенную VM через status/current (гранулярность 1 с) вместо cluster/resources (10 с от pvestatd), с ограниченным параллелизмом и ритмом 1 с
    • Frontend: карточки по каждому диску, карточки Network I/O и I/O-rate на OverviewTab через WebSocket; колонки Net и Disk I/O в InstancesPage; Disk% отображается только для LXC; метрики в реальном времени на виджете топ-нагруженных на DashboardPage

⚙️ Настройки

  • Язык интерфейса для каждого пользователя — у каждого аккаунта теперь есть собственная колонка language (миграция 26); переключатель языка перенесён с вкладки «Панель» на вкладку «Профиль»; язык сохраняется в БД и применяется через i18n.changeLanguage() сразу при сохранении
  • Улучшения вкладки «Панель» — поле panel_name только для чтения (берётся из env PANEL_NAME); поле log_retention_days доступно в UI; API панели принимает panel_name в PUT, что позволяет переопределить значение через БД без правки env

🐛 Исправления

  • Поля настроек SMTP/безопасности — переименованы поля запроса/ответа SMTP (host, port, username, password, from_email, tls); хук настроек безопасности переведён на /admin/api/security/settings с типизированным SecuritySettings; добавлены i18n-ключи minutes / security_saved
  • UX формы уведомлений — добавлены тосты успеха/ошибки для кнопок сохранения SMTP и Telegram; переключатель языка в «Профиле» подключён; поля смены пароля очищаются только при успешном сохранении
  • Telegram — раздел администратора — убрано поле Chat ID из глобальных настроек Telegram (оно никогда не сохранялось в БД); проверка теперь выполняется через личный раздел «Мои уведомления → Отправить тест»
  • Поле Webhook URL — убрано нереализованное поле Webhook URL из настроек уведомлений, чтобы не вводить пользователей в заблуждение

[v1.5.1] - 2026-06-04

🐛 Исправления

  • Сборка фронта: отсутствует компонент LogsPage — в src/router.tsx есть ссылка на ./features/logs/LogsPage.tsx, но сам файл был пропущен, из-за чего Vite 8.0.5 / rolldown не мог разрешить dynamic import. Добавлен frontend/src/features/logs/LogsPage.tsx со stat-карточками (всего за 24ч, ошибки, неудачные логины, записей на странице), фильтром по уровню, поиском, пагинацией и строками i18n. Использует уже существующие хуки useLogs / useLogStats / useLogLevels.
  • Сборка фронта: коллизия в .gitignore — в frontend/.gitignore правило logs без якоря матчило и корневой logs/, и src/features/logs/, скрывая новую страницу из VCS. Правило ограничено корнем — /logs.

📚 Документация

  • WIKI: версия поднята до v1.5.1, добавлен раздел Logs & Audit с описанием страницы, цветами уровней логов, ссылками на API (/logs/api/logs, /logs/api/stats, /logs/api/levels, /logs/api/categories), параметрами запросов, форматом ответа и заметками по правам доступа
  • README: обновлён бейдж версии на 1.5.1

[v1.5.0] - 2026-05-07

🐧 LXC — развёртывание из CT-шаблонов

  • Создание LXC из CT-шаблонов — полный рабочий процесс создания LXC-контейнеров напрямую из CT-файлов Proxmox (.tar.zst, .tar.gz); выбор узла/хранилища, интеграция с IPAM, поддержка SSH-ключей
  • Единый мастер создания инстансов — переработанный мастер (CreateInstanceWizard) поддерживает как VM-шаблоны (QEMU), так и CT-шаблоны (LXC) в едином многошаговом потоке: выбор типа, браузер шаблонов, конфигурация, подтверждение
  • Переустановка LXC из CT-шаблона — поддержка переустановки контейнеров, созданных из CT-шаблонов; имя хоста, пароль, SSH-ключи и IP-адрес сохраняются при переустановке
  • Сохранение учётных данных и IP при переустановке LXC — пароль root, SSH-ключи, IP-конфигурация и шлюз переносятся автоматически при переустановке контейнера
  • nesting=1 по умолчанию — все новые LXC-контейнеры создаются с включённым nesting=1 для обеспечения совместимости с systemd 255+ (cgroup v2)
  • Исправлено: двойное URL-кодирование SSH-ключей — SSH-ключи, передаваемые в API Proxmox при создании LXC, больше не кодируются дважды

🔑 Управление SSH-ключами

  • API SSH-ключей — полный CRUD для библиотеки SSH-ключей пользователя: GET /api/ssh-keys, POST /api/ssh-keys, PUT /api/ssh-keys/{id}, DELETE /api/ssh-keys/{id}
  • Управление ключами администратором — GET /api/ssh-keys/user/{user_id} — администраторы могут просматривать и управлять SSH-ключами любого пользователя
  • Отпечаток ключа — SHA-256 отпечаток вычисляется и сохраняется автоматически при создании/обновлении ключа
  • Хранение приватного ключа — опциональное зашифрованное хранение приватного ключа рядом с публичным
  • UI управления SSH-ключами — новая вкладка на странице настроек для добавления, редактирования и удаления SSH-ключей; отображает имя, отпечаток, комментарий и дату создания
  • Выбор ключа в мастере — при развёртывании VM или LXC можно выбрать SSH-ключи из личной библиотеки; администраторы, создающие инстанс от имени другого пользователя, могут выбирать из ключей этого пользователя
  • Изоляция по пользователю — обычные пользователи управляют только своими ключами; пользователи с разрешением users.manage могут управлять ключами любого аккаунта

🗑️ Операции с VM/LXC

  • Автоматическая остановка перед удалением — если VM или LXC-контейнер запущен в момент запроса удаления, он автоматически останавливается; предотвращает ошибку Proxmox can't lock file при уничтожении

🖥️ Улучшения фронтенда

  • InstancesPage — обновлённый макет, улучшенные бейджи статусов и меню действий
  • NodesPage — обновлённые карточки узлов с более чистым отображением метрик
  • TemplatesPage — улучшенный список шаблонов с лучшей фильтрацией и управлением группами
  • BackupsPage — исправлены граничные случаи в списке резервных копий, диалоге восстановления и UI планировщика заданий
  • UsersPage — улучшенная таблица пользователей с лучшим отображением ролей и индикаторами назначения серверов
  • SettingsPage — добавлен раздел SSH Keys Manager; общая полировка UX
  • api-client.ts — добавлены методы API SSH-ключей и эндпоинты CT-шаблонов
  • websocket.ts — улучшение стабильности соединения
  • types/index.ts — добавлены типы SSHKey, LXCTemplate, LXCDeployRequest

🛠️ Режим разработки

  • Dev mode — новый оверрайд compose.dev.yml для Vite HMR (горячая замена модулей); использовать pve dev или docker compose -f compose.yml -f compose.dev.yml up -d frontend; исходные файлы монтируются как тома, изменения применяются мгновенно без пересборки
  • Маркер .dev-mode — сигнализирует CLI pve о том, что фронтенд запущен в режиме разработки

[v1.4.0] - 2026-04-06

🌐 Сети — управление SDN и интерфейсы узлов

  • Страница сетей — новая объединённая страница (/proxmox/networks) для управления зонами SDN, VNet, подсетями и сетевыми интерфейсами на уровне узла; добавлена в боковую навигацию с специальной иконкой
  • Редактирование зоны SDN — PUT /api/servers/{server_id}/sdn/zones/{zone} — обновление свойств зоны (mtu, dns, reversedns, ipam и т.д.)
  • Редактирование VNet SDN — PUT /api/servers/{server_id}/sdn/vnets/{vnet} — обновление alias, VLAN tag, vlanaware и т.д.
  • Удаление подсети SDN — DELETE /api/servers/{server_id}/sdn/vnets/{vnet}/subnets/{subnet_cidr} — удаление подсети; опционально удаление связанной сети IPAM (?delete_ipam_network=true)
  • Автоматическое создание сети IPAM при создании подсети — POST .../subnets теперь поддерживает create_ipam_network: true; создаёт соответствующую IPAMNetwork, связанную с сервером и VNet, или возвращает существующую
  • Сетевые интерфейсы узлов — полный CRUD для интерфейсов на уровне узла (мосты, связки, VLAN, ethernet): список, получение, создание, обновление, удаление через proxmox_client.py
  • Применение / Откат конфигурации сети узла — PUT и DELETE на /nodes/{node}/network для активации или отката ожидающих изменений
  • API получения списка узлов — GET /api/servers/{server_id}/nodes — возвращает узлы для сервера Proxmox (используется селекторами страницы сетей)

🧹 Очистка кода

  • Очистка импортов модуля SDN — удалены неиспользуемые импорты (ssl, asyncio, httpx, websockets, func, List и т.д.) из sdn.py
  • Маршрутизатор сетей — новый модуль networks.py под api/proxmox/ с маршрутом HTML страницы и API для узлов; зарегистрирован в proxmox/__init__.py

🌍 i18n

  • 49 новых ключей переводов (EN + RU) для страницы сетей: типы интерфейсов, поля bridge/bond/VLAN, применение/откат конфигурации, метки интеграции IPAM, редактирование зоны/vnet, удаление подсети и многое другое

[v1.3.1] - 2026-04-05

🔍 Список ВМ — фильтрация по узлам и адаптивная панель инструментов

  • Фильтр по серверу — новое выпадающее меню для фильтрации списка ВМ по серверу/кластеру Proxmox; заполняется динамически из загруженных ВМ
  • Фильтр по узлу — новое выпадающее меню для фильтрации по узлу Proxmox; автоматически сужает список узлов, принадлежащих выбранному серверу
  • Оба фильтра сохраняются в параметры URL (?server=...&node=...) и восстанавливаются при перезагрузке страницы
  • Панель инструментов переделана в 2 строки — строка 1: все фильтры (тип / статус / сервер / узел / поиск с иконкой + статистика); строка 2: чекбокс выбрать все, пагинация, кнопки действий
  • Адаптивные точки разрыва — при ≤900px метки кнопок скрыты; при ≤768px фильтры переносятся 2 в строку; при ≤480px каждый фильтр во всю ширину; счётчик статистики скрыт на мобильных
  • Вспомогательные функции populateServerFilter() и populateNodeFilter() заполняют выпадающие меню из загруженных данных ВМ
  • Панель инструментов снимков мигрирована с устаревших классов .vm-toolbar-left/.vm-toolbar-right на inline flex, не затронута переделкой панели инструментов

[v1.3.0] - 2026-03-27

🖥️ Консоль — исправления VNC и терминала

  • VNC «Connection closed» исправлено — RFBClass (noVNC) теперь получает строку URL WebSocket непосредственно вместо предварительно открытого объекта WebSocket; хак onFirstMessage, нарушавший квитирование RFB перед первым фреймом, полностью удалён из virtual_machines.html и instance_detail.html
  • VNCAuth исправлено для QEMU — vncproxy теперь вызывается с "generate-password": 1; возвращаемый 8-символьный DES ключ передаётся в noVNC как пароль VNC; возвращается к ticket при отсутствии password (режим NoAuth Proxmox 9.x)
  • LXC vncproxy 500 исправлено — LXC API vncproxy не принимает generate-password; параметр пропускается для LXC, который использует ticket как пароль VNC
  • Контекстное меню LXC открывает терминал xterm.js — правый клик в списке ВМ теперь показывает Терминал для типа lxc (вызывает openTerminalConsole()) и Консоль VNC для типа qemu; ранее все типы использовали openVNCConsole()
  • Модальное окно терминала добавлено на страницу списка ВМ — #terminalModal с полным xterm.js (FitAddon, WebLinksAddon, тема Dracula) добавлено в virtual_machines.html; переиспользует существующие API endpoints GET /api/{server_id}/container/{vmid}/terminal и WebSocket /proxmox/ws/terminal/{server_id}/{node}/{vmid}

[v1.2.0] - 2026-03-16

🐛 Исправление ошибки — конфликт блокировки при изменении размера диска

  • Основная причина исправлена — resize.put() в API Proxmox асинхронна и возвращает задачу UPID; старый код не ждал завершения этой задачи перед запуском ВМ, что заставляло Proxmox сообщать can't lock file '/var/lock/qemu-server/lock-xxx.conf' — got timeout и command '/usr/bin/qemu-img resize' failed: got timeout
  • configure_vm (создание ВМ из шаблона) — теперь захватывает UPID изменения размера и вызывает wait_for_task(120 s) перед возвратом; ВМ может быть запущена только после полного изменения размера диска
  • resize_vm_disk — то же исправление применено; задача изменения размера завершается перед возвратом функции
  • resize_container_disk (оба метода LXC) — то же исправление; перезапуск контейнера выполняется только после подтверждения завершения задачи изменения размера
  • Удалено ненужное перезагрузка ВМ после изменения размера — изменение размера диска QEMU происходит на уровне хранилища и не требует перезагрузки ВМ; автоматический вызов restart_vm() после ручного изменения размера удалён, чтобы предотвратить второй конфликт блокировки

[v1.1.8] - 2026-03-16

👤 Назначение пользователю серверов

  • Таблица user_servers (миграция 20) — новая таблица связей User ↔ ProxmoxServer; позволяет напрямую назначать конкретные серверы пользователям
  • API GET /api/users/{id}/servers — список серверов, назначенных пользователю
  • API GET /api/users/{id}/server-assignments — расширенный список всех серверов с флагами assigned и compatible (совместимость по рабочим областям)
  • API PUT /api/users/{id}/servers — установка набора серверов для пользователя; проверяет пересечение рабочих областей — если сервер и пользователь не состоят ни в одной общей рабочей области, возвращает 409 workspace_conflict
  • Фильтрация серверов для обычных пользователей — пользователь видит только серверы, которые ему назначены и входят в его рабочую область

🖥️ Владелец ВМ / LXC

  • API GET /api/{server_id}/vm/{vmid}/owner — получить текущего владельца ВМ/LXC и список доступных пользователей
  • API PUT /api/{server_id}/vm/{vmid}/owner — назначить или снять владельца (только для админ); действие логируется в аудит

🔐 RBAC и роли

  • Миграция 21 — dashboard:view принудительно выставлен в false для роли user (новый формат ключей)
  • Миграция 22 — ключ proxmox.cluster.manage → cluster:manage в роли admin; старый dot-формат удаляется, чтобы не сбрасывать весь карту разрешений
  • user_count в ответе GET /api/roles — для каждой роли возвращается количество активных пользователей

🚀 Умное перенаправление после входа

  • После успешного входа производится запрос GET /api/auth/me — пользователь автоматически перенаправляется на первую страницу, к которой у него есть доступ (/dashboard → /virtual-machines → /vms → /backups → /ipam → /logs → /settings)
  • Поддержка параметра ?returnUrl= — возврат на запрошенную страницу после входа

🔧 Прочие улучшения

  • GET /api/servers для непривилегированного пользователя объединяет фильтры assigned_servers и WorkspaceServer — пользователь видит только серверы из своей рабочей области, которые ему назначены
  • node_uptime добавлен в ответ детального API сервера
  • Удалена лишняя проверка PermissionChecker на GET-маршруте страницы /users (HTML)

Для истории более ранних версий см. английскую версию CHANGELOG.md