Система обновления XC_VM реализована как многоуровневый процесс, от веб-интерфейса до сценариев системного уровня. Такой подход обеспечивает надежность, автоматизацию и целостность данных при обновлении панели.
> 💡 После завершения обновления Python программа вызывает `console.php update post-update`, что запускает [миграцию базы данных](../guides/database-migrations.md) и очистку после обновления.
> ℹ️ Один и тот же архив используется как для установки, так и для обновления. Фильтрация выполняется на сервере во время обновления — список исключений определяется непосредственно в `src/update`.
1. Если включено значение **Автоматическое обновление LB** и был обновлен главный узел (`MAIN`), → создайте сигналы `update` для всех подсистем балансировки нагрузки.
2. Обновите значение **панельная версия** в базе данных.
Сервер также можно откатить до версии **ранее**. Это повторяет описанный выше процесс обновления, но нацелен на выбранную версию, а не на последнюю — повторно используется тот же конвейер signal → CRON → PHP → Python и тот же инструмент `src/update` applier'а. Откат выполняется для каждого сервера, поэтому `MAIN` и каждый `LB` могут быть понижены независимо друг от друга.
1. **Инициация.** В **Серверы → Управление серверами** меню "Действия для каждого сервера" содержит пункт **Версия для отката**. Открывается диалоговое окно со списком более ранних версий (предварительные версии помечены как `(beta)`), выбранных с помощью действия `rollback_versions` API (`GitHubReleases::getPreviousVersions()`). При выборе версии вводится сигнал — `{"action":"rollback","version":"X.Y.Z"}` - для этого сервера.
- Проверьте целевую версию (`X.Y.Z`, строго более старую, чем текущая версия).
- Только для **главный**: выполните автоматическое резервное копирование базы данных в `backups/pre_rollback_<from>_to_<to>_<timestamp>.sql`, прервав его в случае сбоя. Узлы LB не имеют базы данных и пропустите это.
- Откройте архив версии **точный** с помощью `GitHubReleases::getVersionFile()` (MAIN → `xc_vm.tar.gz`, LB → `loadbalancer.tar.gz`), загрузите его и проверьте MD5.
- Передайте в тот же Python updater (`src/update`).
4. **Система + завершение.** Аналогично обновлению: скрипт на Python останавливает панель, заменяет дерево (сохраняя двоичные файлы/конфигурацию/данные) и `post-update` устанавливает версию в базе данных на откатную версию и перезапускает панель.
> ⚠️ Понижение версии **не отменяет перенос базы данных** (они доступны только в прямом режиме). Схема поддерживается с обратной совместимостью, а автоматическое ОСНОВНОЕ резервное копирование является способом восстановления. Программа Python выполняет копирование по дереву (`cp -a`) без удаления файлов, поэтому файлы, добавленные в более новой версии, сохраняются до следующего обновления.