13 KiB
База прошивок как в 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:
- Кнопка «Обновить каталог» вызывает
read_catalog, заполняет combo/table. - В строке показываются
product,version,transport; в деталях —file_name,notes,base_address. - «Скачать и выбрать» вызывает
download, возвращает проверенный путь. - Сигнал в основное окно передаёт путь и выбранную
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.