from package_updater import PackageUpdater
result = PackageUpdater.check(
package="nkl-manager",
repository="nkl-private",
channel="stable",
smoke_import="nkl_manager",
)
print(result.status, result.installed_version)
Самообновление пакетов.
Только подписанные wheel, только HTTPS.
Минимальный, не зависящий от ddp_utils self-update runtime: HTTPS-only проверка обновлений, Ed25519 + SHA-256 подпись артефактов, атомарные транзакции с обязательным rollback-комплектом, изолированный worker-процесс и re-exec после успешной установки.
Быстрый старт
Прямой вызов или через встроенный дескриптор — оба варианта поддерживаются контрактом.
# nkl_manager/__init__.py
from package_updater import PackageUpdater
PackageUpdater.check_declared(package="nkl-manager")
# Только после bootstrap:
from .manager import NklManager
repository.
Сценарий обновления
Один вызов check() проходит все шаги последовательно;
любой шаг может завершиться безопасным возвратом текущей версии.
- Recovery check
- Memory cache
- TTL check
- HTTPS check-update
- Channel + policy
- Выбор версии
- Скачать + проверить wheel
- Dependency plan
- Prepare transaction
- Worker install
- Post-install validation
- Restart marker + re-exec
Идемпотентность в процессе
Повторный вызов check() для того же пакета в одном
Python-процессе не повторяет сетевую проверку — возвращается
закешированный результат (ключ: identity интерпретатора + путь
установки + имя пакета).
Ошибка сети не блокирует запуск
UPDATE_CHECK_FAILED просто означает "текущая версия
продолжает работать"; следующая попытка — через 10 минут вместо
обычного часового TTL.
Архитектура
BootstrapRuntime — минимальный слой без импорта
ddp_utils, безопасный для работы даже во время
обновления самого себя.
Каналы и версии
PEP 440 (packaging.version); строковое сравнение версий запрещено контрактом.
| Configured channel | Видит offers из |
|---|---|
stable | stable |
beta | stable + beta |
dev | stable + beta + dev |
| Bump | Policy по умолчанию | Поведение |
|---|---|---|
| patch | auto | Устанавливается автоматически |
| minor | auto | Устанавливается автоматически |
| major | warn | MAJOR_UPDATE_AVAILABLE, без авто-установки |
| dependency downgrade/remove | prompt | Требует confirm-callback, иначе UPDATE_DEPENDENCIES_REQUIRED |
Проверка артефактов
Перед тем как wheel попадёт worker'у, он обязан пройти всю цепочку.
Транзакции и rollback
До изменения окружения обязаны существовать проверенные rollback-wheel для каждого затрагиваемого пакета.
Подготовка (до install)
Скачать и проверить новый wheel → построить dependency plan из METADATA → скачать и проверить rollback wheel текущей версии → снапшот окружения → записать transaction journal. Если rollback-комплект неполный — установка не начинается.
Rollback (после сбоя)
Зависимости откатываются в обратном порядке, затем сам пакет.
Успех — UPDATE_FAILED_ROLLED_BACK; неуспех —
UPDATE_FAILED_ROLLBACK_FAILED, пакет блокируется.
Locks и recovery
Lock защищает всё окружение целиком, а не только один пакет — зависимости общие.
heartbeat истёк и owner_pid больше не существует. Возраст сам по себе не признак stale.
Следующий вызов находит незавершённую транзакцию и выполняет rollback к snapshot — никогда не продолжает install вслепую.
Restart marker + os.execv, чтобы не остались смешанные версии модулей в памяти процесса.
Конфигурация репозитория
Trust-конфигурация живёт вне wheel и никогда не сканируется/угадывается.
[repositories.nkl-private]
check-url = "https://packages.example.com/api/v1/updates/check"
version-fetch-url-template = "https://packages.example.com/api/v1/versions/{package}/{version}"
allowed-packages = ["nkl-manager"]
auth-token-env = "NKL_PACKAGES_TOKEN"
[repositories.nkl-private.trusted-keys]
nkl-release-key-1 = "<base64 Ed25519 public key>"
Статусы результата
UpdateResult.status — единственное поле, которое определяет, что произошло.
Ошибки и диагностика
Каждая ошибка типизирована и имеет стабильный code; секреты в сообщениях не встречаются.
UpdateRepositoryNotConfiguredError
Repository id не найден в trust-конфигурации.
UpdateRepositoryNotTrustedError
HTTPS нарушен или пакет не в allowed-packages.
ArtifactUntrustedError
Filename/identity/size/path-traversal проверка не прошла.
SignatureVerifyFailedError
Ed25519 подпись не совпала с доверенным ключом.
RollbackFailedError
Не удалось собрать или применить rollback-комплект.
UpdateLockTimeoutError
Environment lock занят другим процессом дольше таймаута.
UpdateRecoveryFailedError
Восстановление после краха не удалось — пакет заблокирован.
Полный API reference
Все классы, методы и функции библиотеки — с сигнатурами, аргументами, типами и примерами использования.