Техническая документация
Описание
Система автоматического обновления MmoWeb Client реализует механизм безопасного развёртывания новых версий приложения через GitHub Releases API. Система поддерживает автоматическое резервное копирование, поэтапное применение изменений и отслеживание прогресса обновления в реальном времени.
Архитектура системы
Основные компоненты
UpdateService (
Class/Services/UpdateService.php)Центральный сервис управления обновлениями
Отвечает за скачивание, распаковку и применение релизов
Repository (
Class/GitHub/Repository.php)Абстракция работы с GitHub API
Обработка запросов к репозиторию и релизам
ApiController (
Controllers/ApiController.php)HTTP endpoints для удалённого управления обновлениями
Методы:
updater_check_connection,install_update,get_version,get_updater_process_progress
Cache система
Хранилище состояния процесса обновления
Кеширование прогресса выполнения
Процесс обновления
1. Инициализация
Вызов API endpoint
Валидация
Проверка версии PHP (только 7.4.33)
Проверка соединения с GitHub API
Проверка конфигурации версии
Проверка отсутствия активного процесса обновления
Генерация процесса
Создаётся уникальный
process_key(SHA256 хеш)Устанавливается статус
CREATEDВозвращается
process_keyклиенту
Файл: UpdateService.php:82-104
2. Создание директории процесса
Расположение: Files/update/{process_key}/
Структура директории:
Файл: UpdateService.php:106-127
3. Создание резервной копии
Параметры бекапа
Путь:
Files/update/{process_key}/backup.zipМетод: Рекурсивная архивация через
ZipArchiveИсключения:
Директория
Files/update/(любые процессы обновления)Архивы:
.zip,.rar,.7z,.tar,.gz,.bz2,.xz,.tgzСимволические ссылки
Нечитаемые файлы
Алгоритм
Сканирование всех файлов от
ROOT_DIRФильтрация по критериям исключения
Добавление файлов и директорий в ZIP с сохранением структуры
Проверка целостности (размер > 0 байт)
Время выполнения: зависит от размера проекта (обычно 5-30 секунд)
Файл: UpdateService.php:233-312
4. Загрузка релиза
Источник
URL:
{release.zipball_url}из GitHub APIТаймаут: 2100 секунд (35 минут)
Механизм загрузки
Путь сохранения
Files/update/{process_key}/{tag}.zip
Файл: UpdateService.php:129-179
5. Анализ изменений коммита
Получение списка файлов
Система запрашивает все файлы из коммита релиза через GitHub API:
Пагинация
Обрабатываются все страницы (max 50)
Паузы между запросами: 250ms (
usleep(250000))
Типы изменений файлов
added - новый файл
modified - изменённый файл
renamed - переименованный файл (обрабатывается как копирование)
removed - удалённый файл (логируется, но НЕ удаляется локально)
Файл: UpdateService.php:345-390
6. Применение изменений
Процесс обработки файлов
Метод извлечения файла
Атомарная операция:
Создание временного файла
{targetPath}.tmpКопирование потока из ZIP в временный файл
Установка прав
0644Атомарная замена через
rename()
Безопасность:
Автоматическое создание директорий с правами
0755Откат при ошибке (удаление
.tmp)
Файл: UpdateService.php:604-631
7. Завершение процесса
При успешном обновлении
Статус устанавливается в
COMPLETEDОбновляется конфигурация
version.json:Очистка кеша (если
DEBUG = false):update_progress_{process_key}update
Файл: UpdateService.php:548-563
При ошибке
Статус устанавливается в
FAILEDЗапись в лог с полным трейсом ошибки
Отправка ошибки в Global API
Бекап остаётся нетронутым в
Files/update/{process_key}/backup.zip
Файл: UpdateService.php:565-574
Логирование
Расположение логов
Директория: Files/logs/
Формат имени:
Пример:
Содержимое логов
Стандартная информация
Начало установки релиза
Создание директории процесса
Загрузка ZIP файла
SHA коммита релиза
Создание бекапа
Обработка каждого файла (статус и путь)
Прогресс обновления (% выполнения)
Окончание процесса
Debug информация (если DEBUG = true)
Системная информация:
Файл: UpdateService.php:633-639, 314-343
Критические ошибки
Обработчик Shutdown
Регистрируется на старте обновления и отлавливает фатальные ошибки:
E_ERRORE_PARSEE_CORE_ERRORE_COMPILE_ERRORE_USER_ERROR
При фатальной ошибке:
Пишется в лог с префиксом
FATAL ERROR:Кеш устанавливается в
FAILEDУведомление отправляется в Global API
Файл: UpdateService.php:182-231
Управление состоянием
Кеширование статуса
Ключ кеша: update
Структура:
TTL: 1800 секунд (30 минут)
Файл: UpdateService.php:92-104
Кеширование прогресса
Ключ кеша: update_progress_{process_key}
Значение: Float (0.00 - 100.00)
TTL: 600 секунд (10 минут)
Обновление: При обработке каждого файла
Пример файла: cache/update_progress_{hash}.txt
Файл: UpdateService.php:532-533
API Endpoints
1. Проверка соединения
Endpoint: POST /api/updater_check_connection
Проверки:
Валидность конфигурации версии
PHP = 7.4.33
Соединение с GitHub API
Ответы:
Файл: ApiController.php:432-475
2. Установка обновления
Endpoint: POST /api/install_update
Параметры:
tag(required) - тег релиза (например,v1.2.3)process_key(optional) - ключ процесса при продолжении
Двухэтапный процесс:
Этап 1: Создание процесса
Ответ:
Этап 2: Выполнение обновления
Ответ при успехе:
Ответ при ошибке:
Файл: ApiController.php:477-572
3. Получить текущую версию
Endpoint: POST /api/get_version
Ответ:
Файл: ApiController.php:574-590
4. Получить прогресс обновления
Endpoint: GET /api/get_updater_process_progress?process_key={key}
Ответ:
Файл: ApiController.php:592-630
Обработка ошибок и recovery
Типовые ошибки
1. Обновление уже запущено
Статус: 423 Locked
Решение: Дождаться завершения текущего процесса или проверить статус в кеше
2. Тег уже установлен
Exception: The specified tag is already installed.
Решение: Проверить текущую версию через /api/get_version
3. Проблемы с GitHub API
Возможные причины:
Неверный токен авторизации
Rate limiting
Таймаут соединения
Несуществующий релиз/тег
Диагностика:
Проверить логи
Debug/github.logПроверить конфигурацию
Library/configs/github.jsonТест соединения:
/api/updater_check_connection
Файл: Repository.php:53-115
4. Ошибка создания бекапа
Возможные причины:
Недостаточно места на диске
Нет прав на запись в
Files/update/Исчерпана память PHP (
memory_limit)
Решение:
Проверить свободное место:
df -hПроверить права:
ls -la Files/Увеличить
memory_limitв php.ini (по умолчанию устанавливается 256M)
Файл: UpdateService.php:233-312
5. Битый ZIP файл
Exception: Failed to open ZIP file... The file may be corrupted.
Решение:
Проверить файл вручную:
unzip -t Files/update/{process_key}/{tag}.zipУдалить процесс и повторить обновление
Проверить стабильность сетевого соединения
Файл: UpdateService.php:449-451
6. ZIP Slip атака
Exception: ZIP Slip detected: invalid path: ...
Причина: Попытка записи файла за пределы ROOT_DIR
Защита: Проверка на наличие .. или абсолютных путей в именах файлов
Файл: UpdateService.php:492-497
Восстановление из бекапа
Автоматическое восстановление
При ошибке процесс останавливается, но откат не производится автоматически.
Ручное восстановление
Найти директорию последнего обновления:
Проверить наличие бекапа:
Распаковать бекап:
Проверить права доступа:
Очистить кеш обновления:
Безопасность
Аутентификация API (клиентская часть)
Все API endpoints используют HMAC-SHA256 подпись:
Константа: API_KEY из Config.php
Файл: ApiController.php:14-44
Защита от атак
1. ZIP Slip Protection
Проверка всех путей файлов на наличие:
..(выход за пределы директории)Абсолютных путей (
/,\,C:)
2. Игнорирование пользовательского прерывания
3. Ограничения выполнения
Таймаут: 1800 секунд (30 минут)
Память: 256MB
Umask: 0022 (права по умолчанию)
Файл: UpdateService.php:395-400
Конфигурация GitHub
Файл: Library/configs/github.json
Файл: Repository.php:21-36
Производительность
Таймауты
Процесс обновления
1800 сек (30 мин)
PROCESS_EXECUTE_TIMEOUT
Загрузка ZIP с GitHub
2100 сек (35 мин)
CURLOPT_TIMEOUT
GitHub API запрос
15 сек
Repository->timeout
Пауза между запросами коммитов
250 мс
usleep(250000)
Оптимизация
1. Прогресс-репортинг с дебаунсом
Отправка прогресса в Global API происходит не чаще 1 раза в 3 секунды:
Файл: UpdateService.php:536-539
2. Потоковая обработка файлов
Использование stream_copy_to_stream() вместо загрузки в память:
Файл: UpdateService.php:607-617
Мониторинг
Проверка статуса обновления
Проверка логов
Конфигурационные файлы
version.json
Расположение: Library/configs/version.json
github.json
Расположение: Library/configs/github.json
Troubleshooting
Проблема: Обновление зависло
Диагностика:
Проверить статус процесса:
Проверить PHP процессы:
Проверить последний лог:
Решение:
Если процесс завис > 30 минут - очистить кеш вручную
Проверить доступность GitHub API
Повторить обновление
Проблема: Недостаточно прав доступа
Симптомы:
Решение:
Проблема: GitHub API rate limit
Симптомы:
Решение:
Используйте Personal Access Token
Authenticated requests: 5000 req/hour
Unauthenticated: 60 req/hour
Рекомендации для специалистов
Pre-deployment checklist
Post-deployment checklist
Last updated