For the complete documentation index, see llms.txt. This page is also available as Markdown.

Техническая документация

Описание

Система автоматического обновления MmoWeb Client реализует механизм безопасного развёртывания новых версий приложения через GitHub Releases API. Система поддерживает автоматическое резервное копирование, поэтапное применение изменений и отслеживание прогресса обновления в реальном времени.


Архитектура системы

Основные компоненты

  1. UpdateService (Class/Services/UpdateService.php)

    • Центральный сервис управления обновлениями

    • Отвечает за скачивание, распаковку и применение релизов

  2. Repository (Class/GitHub/Repository.php)

    • Абстракция работы с GitHub API

    • Обработка запросов к репозиторию и релизам

  3. ApiController (Controllers/ApiController.php)

    • HTTP endpoints для удалённого управления обновлениями

    • Методы: updater_check_connection, install_update, get_version, get_updater_process_progress

  4. 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

    • Символические ссылки

    • Нечитаемые файлы

Алгоритм

  1. Сканирование всех файлов от ROOT_DIR

  2. Фильтрация по критериям исключения

  3. Добавление файлов и директорий в ZIP с сохранением структуры

  4. Проверка целостности (размер > 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. Применение изменений

Процесс обработки файлов

Метод извлечения файла

Атомарная операция:

  1. Создание временного файла {targetPath}.tmp

  2. Копирование потока из ZIP в временный файл

  3. Установка прав 0644

  4. Атомарная замена через rename()

Безопасность:

  • Автоматическое создание директорий с правами 0755

  • Откат при ошибке (удаление .tmp)

Файл: UpdateService.php:604-631


7. Завершение процесса

При успешном обновлении

  1. Статус устанавливается в COMPLETED

  2. Обновляется конфигурация version.json:

  3. Очистка кеша (если DEBUG = false):

    • update_progress_{process_key}

    • update

Файл: UpdateService.php:548-563

При ошибке

  1. Статус устанавливается в FAILED

  2. Запись в лог с полным трейсом ошибки

  3. Отправка ошибки в Global API

  4. Бекап остаётся нетронутым в 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_ERROR

  • E_PARSE

  • E_CORE_ERROR

  • E_COMPILE_ERROR

  • E_USER_ERROR

При фатальной ошибке:

  1. Пишется в лог с префиксом FATAL ERROR:

  2. Кеш устанавливается в FAILED

  3. Уведомление отправляется в 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)

Решение:

  1. Проверить свободное место: df -h

  2. Проверить права: ls -la Files/

  3. Увеличить memory_limit в php.ini (по умолчанию устанавливается 256M)

Файл: UpdateService.php:233-312


5. Битый ZIP файл

Exception: Failed to open ZIP file... The file may be corrupted.

Решение:

  1. Проверить файл вручную: unzip -t Files/update/{process_key}/{tag}.zip

  2. Удалить процесс и повторить обновление

  3. Проверить стабильность сетевого соединения

Файл: UpdateService.php:449-451


6. ZIP Slip атака

Exception: ZIP Slip detected: invalid path: ...

Причина: Попытка записи файла за пределы ROOT_DIR

Защита: Проверка на наличие .. или абсолютных путей в именах файлов

Файл: UpdateService.php:492-497


Восстановление из бекапа

Автоматическое восстановление

При ошибке процесс останавливается, но откат не производится автоматически.

Ручное восстановление

  1. Найти директорию последнего обновления:

  2. Проверить наличие бекапа:

  3. Распаковать бекап:

  4. Проверить права доступа:

  5. Очистить кеш обновления:


Безопасность

Аутентификация 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

Проблема: Обновление зависло

Диагностика:

  1. Проверить статус процесса:

  2. Проверить PHP процессы:

  3. Проверить последний лог:

Решение:

  • Если процесс завис > 30 минут - очистить кеш вручную

  • Проверить доступность GitHub API

  • Повторить обновление


Проблема: Недостаточно прав доступа

Симптомы:

Решение:


Проблема: GitHub API rate limit

Симптомы:

Решение:

  • Authenticated requests: 5000 req/hour

  • Unauthenticated: 60 req/hour


Рекомендации для специалистов

Pre-deployment checklist


Post-deployment checklist

Last updated

Was this helpful?