Files

13 KiB
Raw Permalink Blame History

База прошивок как в SETGUI

Это общий сервис базы файлов прошивок: получить список опубликованных образов, выбрать изделие/версию/транспорт, скачать файл, проверить SHA-256 и передать его загрузчику. Также можно опубликовать новый образ в эту же базу. Модуль не зависит от версии самого приложения и от c/firmware-info.

Состав

Файл Ответственность
firmware_database.py Готовый HTTPS-клиент, чтение базы, кэш скачанных образов, публикация в Gitea
firmware_catalog.py Общий формат записей базы, используемый SETGUI
firmware_publish.py Метаданные образа, SHA-256, объединение записей каталога
firmware_db.py Самостоятельный консольный запуск без SETGUI

Требования: Python 3.10+ и стандартная библиотека. Qt, Windows Credential Manager, установленный SETGUI и библиотеки МК не требуются. Это сервис и CLI; готовое Qt-окно остаётся в SETGUI, а другой GUI подключает сервис по API ниже.

Как устроена база

В текущей конфигурации SETGUI файлы находятся в Gitea Releases репозитория setcorp/SETRD12-Releases на https://git.rd12.ru. Список файлов лежит в firmware.releases файла update.json ветки main. Запись содержит изделие, версию, транспорт, адрес образа, имя файла, SHA-256, описание и необязательный адрес приложения во Flash. Это файловый каталог; SQL-сервер не нужен.

Новый сервис использует тот же JSON-контракт, поэтому выпуски видны клиентам SETGUI, поддерживающим указанный транспорт. В текущем SETGUI транспорт tms фильтруется; общий сервис его сохраняет. Публикация не добавляет новый загрузочный протокол в приложение или МК.

публикация .hex/.bin → Gitea release asset → скачать и проверить SHA-256
                                                 ↓
                                      обновить firmware.releases
                                                 ↓
GUI: «Обновить каталог» → выбрать запись → «Скачать и выбрать» → загрузчик МК

Для своего сервера задайте server, owner, repository, branch и manifest_path. Репозиторий, ветка и JSON-файл должны уже существовать. Для пустой базы достаточно файла {"firmware":{"catalogVersion":0,"releases":[]}}. Если update.json общий с обновлениями приложения, его другие разделы сохраняются при добавлении прошивки.

Консоль: проверить, опубликовать, посмотреть, скачать

Из корня templates в PowerShell (параметры сервера стоят перед командой):

$db = @('--server', 'https://git.rd12.ru', '--owner', 'setcorp', '--repo', 'SETRD12-Releases')

# Без сети: проверить файл и сформировать запись каталога.
python tools/firmware-publish/firmware_db.py @db preflight --file C:/build/device.hex --product MY_DEVICE --version 1.2.3 --version-code 0x010203 --transport can --base-address 0x08003000

# Публикация образа в базу (изменяет сервер).
python tools/firmware-publish/firmware_db.py @db publish --file C:/build/device.hex --product MY_DEVICE --version 1.2.3 --version-code 0x010203 --transport can --base-address 0x08003000

# Получить список записей и скачать конкретную.
python tools/firmware-publish/firmware_db.py @db list --product MY_DEVICE
python tools/firmware-publish/firmware_db.py @db download --product MY_DEVICE --version-code 0x010203 --transport can --cache C:/firmware-cache

MY_DEVICE, версия, транспорт и адрес — примеры, замените их данными изделия. SCI8 для TMS публикуйте как .bin с --transport tms, без --base-address. Инструмент не конвертирует .axf/.out и не проверяет пригодность образа для МК.

CLI читает логин и пароль/токен из переменных окружения FIRMWARE_DB_LOGIN и FIRMWARE_DB_PASSWORD. Задавайте их средствами своего секрет-хранилища/CI, а не в файлах проекта и не в аргументах командной строки. Для интерактивного ввода в PowerShell можно использовать:

$fwCredential = Get-Credential -Message 'Gitea: логин и пароль либо токен вместо пароля'
$env:FIRMWARE_DB_LOGIN = $fwCredential.UserName
$env:FIRMWARE_DB_PASSWORD = $fwCredential.GetNetworkCredential().Password
# Выполнить нужные команды; после работы убрать переменные из текущего процесса.
Remove-Item Env:FIRMWARE_DB_LOGIN, Env:FIRMWARE_DB_PASSWORD

Публичный каталог можно читать без входа. Публикация через CLI требует обе переменные. Сервис не извлекает сохранённый пароль SETGUI автоматически. Команда publish явно разрешает запись и не запрашивает дополнительного подтверждения; preflight ничего не загружает. Старый BAT и конфигурации firmware-release.cmd продолжают использовать прежний путь через SETGUI.

Портирование в другое Python-приложение

Подключите templates/python в import path приложения; переносите зависимость целиком, не одну копию файла. Сеть и кэш реализованы в сервисе, UI и хранение учётных данных задаёт приложение:

from pathlib import Path
from setprotocol.firmware_database import (
    Credentials, FirmwareDatabase, GiteaRepository, GiteaFirmwarePublisher,
)
from setprotocol.firmware_publish import FirmwarePublication

repo = GiteaRepository('https://git.rd12.ru', 'setcorp', 'SETRD12-Releases')
# login и password получает ваше приложение из формы/хранилища.
credentials = Credentials(login, password)
database = FirmwareDatabase(repo.manifest_url, Path('firmware'), credentials=credentials)

# «Обновить каталог»: результат заполнит список в вашем UI.
releases = database.read_catalog(product='MY_DEVICE', transport='can')
# После выбора пользователем строки списка:
selected = releases[selected_index]
path = database.download(selected, progress=lambda percent: print(percent))
# Передайте path, selected.transport и selected.base_address своему загрузчику.

# Публикация нового образа: отдельное действие оператора.
publisher = GiteaFirmwarePublisher(repo, credentials)
publication = FirmwarePublication(
    Path('build/device.hex'), 'MY_DEVICE', '1.2.3', 0x010203, 'can', 0x08003000,
    'Описание выпуска',
)
preview = publisher.preflight(publication)  # можно показать перед выпуском
entry = publisher.publish(publication)

Для публичного каталога передайте credentials=None. Для чтения каталога, расположенного вне стандартного Gitea URL, передайте его HTTPS-адрес прямо в FirmwareDatabase; GiteaRepository нужен сетевому публикатору.

В Qt выполняйте read_catalog, download, publish в worker/QThread, передавайте прогресс сигналами в главный поток. По аналогии с SETGUI:

  1. Кнопка «Обновить каталог» вызывает read_catalog, заполняет combo/table.
  2. В строке показываются product, version, transport; в деталях — file_name, notes, base_address.
  3. «Скачать и выбрать» вызывает download, возвращает проверенный путь.
  4. Сигнал в основное окно передаёт путь и выбранную FirmwareRelease; окно выставляет файл и транспорт на вкладке прошивки.

Скачивание не запускает прошивку устройства автоматически. Для C++/Android можно использовать CLI как отдельный процесс на ПК или реализовать клиент этого JSON-контракта на языке платформы; Python-модуль не является C-библиотекой.

Поведение и ошибки

  • Кэш: <cache>/<sha256>/<fileName>. Одинаковые имена разных образов не конфликтуют. Проверенный кэш используется повторно; незавершённые временные файлы удаляются. Результат появляется только после совпадения SHA-256.
  • Только HTTPS. Учётные данные отправляются лишь исходному origin (схема, хост, порт); на сторонний CDN и при смене origin в redirect не передаются. Redirect для запросов записи отклоняется.
  • Публикация использует asset с SHA-256 в имени: новые байты не заменяют файл, на который ещё ссылается старый каталог. fileName в каталоге остаётся исходным именем. В этом деталь реализации отличается от старого публикатора SETGUI, но формат каталога совместим.
  • Каталог меняется только после обратного скачивания образа. Запись проверяет ревизию файла (sha). При конфликте операция завершается ошибкой: повторите выпуск после проверки причины. Загруженный asset может остаться без записи каталога; повторный запуск использует его и снова проверит скачивание.
  • Повтор той же записи не увеличивает catalogVersion. Обновление одного product + versionCode + transport заменяет запись. Полный rollback и автоматическая очистка старых assets не выполняются.
  • Текущий upload держит образ в памяти (лимит 128 MiB), чтобы параллельная пересборка не подменила байты между вычислением хэша и отправкой.

Проверка

Из templates:

$env:PYTHONPATH = "$PWD/python"
python -m unittest discover -s python/tests -p test_firmware_database.py -v
python -m unittest discover -s python/tests -p test_firmware_publish.py -v

Тесты используют сервер в памяти: каталог → публикация → скачивание, повторный выпуск, сохранение других разделов, ошибки SHA-256 и конфликты ревизии, изоляцию авторизации при redirect. Проверка реальной Gitea и загрузка на МК в эти тесты не входят. Перед производственным подключением проверьте выпуск в тестовом репозитории вашей Gitea и чтение каталога целевым GUI.