Руководство по обновлению
С 1.4.2 на 1.4.3
Заголовок раздела «С 1.4.2 на 1.4.3»1.4.3 читает хранилище 1.4.2 как есть, и на локальном диске, и в S3, а 1.4.2 читает то, что сохранила 1.4.3. 1.4.3 закрывает уязвимости из GHSA-54qr-w49h-mgfq.
До обновления
Заголовок раздела «До обновления»OIDC-провайдер в [[auth.oidc.providers]] без audience на 1.4.3 останавливает запуск (код выхода 78: systemd-юниты из пакетов после него сервис не перезапускают) с ошибкой, называющей провайдера; перезагрузку по SIGHUP, которая его добавляет, NORA отклоняет. Задайте каждому включённому провайдеру audience, который запрашивают задания CI (core.getIDToken('nora'), в GitLab id_tokens: … aud:), или any_audience = true, если назвать aud нельзя: тогда принимается любой aud, с предупреждением при каждом запуске.
Что изменилось
Заголовок раздела «Что изменилось»| Изменение | Влияние | Что сделать |
|---|---|---|
OIDC-провайдер без audience | Отклоняется при запуске и при перезагрузке (см. выше) | Задать audience или any_audience = true |
nora import для PyPI и NuGet | Импортируются как hosted: индекс, версии и даты строятся из того, что хранит NORA, upstream об имени не спрашивается. Импортированный проект PyPI отдаёт только импортированные или загруженные в него файлы | Запустить импорт ещё раз: репозиторий PyPI или NuGet, который 1.4.2 и старше отметили завершённым, обходится заново. Файл, загруженный под именем импортированного проекта версией 1.4.2 и старше, загрузить снова |
/health | 503 с failing_task, когда фоновая задача паникует раз за разом или цикл обслуживания не завершает ни одного прохода за server.maintenance_stall_secs (300 с). Паника обработчика отвечает 500, сервер продолжает работать; паника записи аудита завершает процесс с кодом 70 | Kubernetes перезапускает по liveness-пробе. Под Docker без Swarm или под systemd 503 сам ничего не перезапускает: добавьте autoheal или таймер с nora healthcheck || systemctl restart nora |
/ready | 503, когда хранилище не ответило к сроку прохода обслуживания, без перезапуска | Ничего |
Пределы соединений: server.header_read_timeout (30 с), server.keep_alive_timeout (120 с), server.max_connections (4096) | Соединения без заголовков запроса и простаивающие закрываются; HTTP/2 закрывается с GOAWAY | Держите keep_alive_timeout больше idle-таймаута reverse proxy перед NORA (90 с и меньше — предупреждение при старте), а max_connections — больше числа keep-alive соединений, которые этот прокси держит открытыми |
| Сроки токенов | Не больше 3650 дней на любом пути выпуска; токен, выпущенный OIDC-идентичностью, живёт не дольше max_token_lifetime_secs провайдера и остатка своего JWT. В ответе есть expires_in_secs | Ничего |
| Блокировка по паролю | Считается по имени пользователя на адресе; адрес по-прежнему блокируется для всех имён после неверных паролей к десяти учётным записям | Ничего |
Адрес клиента при NORA_HOST=:: (дефолт образа) | IPv4-клиент читается как IPv4, поэтому его видят trusted_proxies и ограничение частоты | Ничего |
| Tarball npm | Загружается только для версии из пакумента upstream, по его ссылке. Редирект на другой origin выполняется без учётных данных upstream; метаданные записи proxies, привязанной к scope, берутся только с её origin | Ничего |
| Попадания в кэш | Дороже по CPU: p95 большого пакумента npm вроде react около 16 мс (было около 10 мс) | Ничего |
Остановите 1.4.3 и запустите 1.4.2 на том же хранилище. 1.4.2 не знает server.header_read_timeout, server.keep_alive_timeout, server.max_connections, server.maintenance_stall_secs и any_audience: она предупреждает и игнорирует их, но с NORA_CONFIG_STRICT=true не стартует (код выхода 78). Перед откатом уберите их из config.toml или задайте ключи [server] переменными окружения (NORA_HEADER_READ_TIMEOUT и остальные) — их 1.4.2 не читает.
С 1.3.6 на 1.4.0
Заголовок раздела «С 1.3.6 на 1.4.0»1.4.0 читает хранилище 1.3.6 как есть, и на локальном диске, и в S3. Она добавляет свои ключи, которые 1.3.6 не читает: записи написаний Cargo в cargo/_names/, индекс upstream Cargo под отдельным ключом и копии upstream npm в npm/<name>/upstream/. 1.4.0 закрывает уязвимости из GHSA-5pr2-xx8w-79jc и GHSA-pg2g-wvgf-cxpp.
До обновления
Заголовок раздела «До обновления»Некоторые конфигурации, с которыми 1.3.6 стартует, на 1.4.0 останавливают запуск; сообщение называет ключ:
min_release_ageдля rpm, deb или cpan — у этих загрузок нет ни проверки имени, ни даты релиза, которую можно выдержать;min_release_ageотдельного proxy-реестра без карантина этого реестра (curation.<registry>.quarantineили глобальногоcuration.quarantine);- глобальный
min_release_ageбез карантина, когда набор включённых реестров монтирует proxy-реестры с выключенными собственными флагами, или монтирует Hugging Face черезall,hf; curation.require_integrityбезcuration.allowlist_path;- любые настройки
[curation.hf]и переменныеNORA_CURATION_HF_*— модели Hugging Face удерживаются по репозиторию и коммиту в allowlist и blocklist.
Что изменилось
Заголовок раздела «Что изменилось»| Изменение | Влияние | Что сделать |
|---|---|---|
| Cargo: крейт, опубликованный в NORA, отдаётся только из своих записей | Upstream о нём не спрашивается; скачивание версии, которой у него нет, — 404, ничего не запрашивается и не сохраняется | Первый cargo publish поверх индекса, который старый релиз оставил без записей по версиям, отклоняется с 409 и именем ключа: удалите ключ, если это кэш upstream, или задайте NORA_CARGO_IMPORT_EMBEDDED=<имя>, если это ваш крейт |
Cargo: - и _ — одно имя крейта, как на crates.io | Другое написание опубликованного крейта — 404 (с опубликованным написанием в ответе), у upstream не запрашивается; публикация — 409 | Ничего. Первый запуск до приёма запросов записывает написания для крейтов, опубликованных до 1.4.0 (один листинг опубликованных записей) |
| Cargo: копии неизвестных версий, которые старый релиз сохранил рядом с опубликованным крейтом | Для имён с - или _ не отдаются; по-прежнему видны в UI и учитываются keep_last | Удалите вручную (#1163) |
| Retention и GC Cargo | Записи индекса по версиям и .crate крейтов с именами из одной-двух букв больше не удаляются | Ничего |
| Docker: запушенный тег | Отвечает только запушенный манифест, в том числе после pull через прокси; курация датирует его по push | Тег, запушенный до 1.4.0 поверх уже проксированного, остаётся за проксированной копией, пока его не запушат снова |
| Docker: манифест по дайджесту | Ответ upstream с другим дайджестом считается сбоем upstream; push по дайджесту с другими байтами — 400 DIGEST_INVALID | Ничего |
Docker: теги, оканчивающиеся на .meta или .stats | 400 на всех маршрутах манифестов | Переименуйте такие теги |
| Docker: удаление, которое не может прочитать метаданные манифеста | 500, ничего не удаляется (было 202) | Ничего |
| Docker: отказ курации | docker pull и skopeo печатают denied: blocked by policy: … | Ничего |
| npm: пакет, опубликованный в NORA | Packument, манифесты версий и dist-tags отдаются из его ключей, upstream не спрашивается | Публикация поверх packument неизвестного происхождения у пакета без опубликованных версий — 409 с именем ключа: удалите его, если это кэш, или задайте NORA_NPM_IMPORT_EMBEDDED=<имя>, если это ваш пакет |
npm: npm search и другие пути метаданных | Отвечает upstream, без кэша | Ничего |
| Пустая настройка upstream у gems, NuGet, Conan, Terraform, Ansible, CPAN | Формат отвечает только из хранилища (было: публичный upstream по умолчанию) | Ничего, если вы имели в виду «без upstream» |
| PyPI: учётные данные upstream | Уходят только этому upstream, а не хостам файлов, на которые он ссылается | Ничего |
curation.mode по умолчанию при включённых proxy-реестрах | Предупреждение при каждом запуске и nora_config_deprecated{reason="curation_mode_implicit"} 1; 1.5.0 будет останавливать запуск | Задайте curation.mode (NORA_CURATION_MODE): off, audit или enforce |
| Адрес клиента за обратным прокси | Берётся справа в X-Forwarded-For, за доверенными прокси | Проверьте NORA_AUTH_TRUSTED_PROXIES, если перед NORA больше одного прокси |
| Прокси Hugging Face Hub | Новое, включается явно (NORA_HF_ENABLED=true) | Ничего |
Остановите 1.4.0 и запустите 1.3.6 на том же хранилище. Опубликованные крейты Cargo, пакеты npm и образы Docker продолжают работать. 1.3.6 не читает записи написаний и копии upstream, которые 1.4.0 хранит под своими ключами, поэтому снова запрашивает эти пакеты у upstream. Packument неопубликованного пакета, который закэшировал старый релиз, 1.4.0 не перезаписывает, и 1.3.6 его находит.
С 1.3.3 на 1.3.4
Заголовок раздела «С 1.3.3 на 1.3.4»1.3.4 читает хранилище 1.3.3 как есть, и на локальном диске, и в S3. Миграция не нужна.
Что изменилось
Заголовок раздела «Что изменилось»| Изменение | Влияние | Что сделать |
|---|---|---|
npm: несколько upstream по scope (npm.proxies) | Новое, включается явно | Ничего. См. npm |
| npm: недоступный upstream при первом запросе пакета | 502 вместо 404 | Ничего. Клиент сообщает об ошибке шлюза, а не об отсутствии пакета |
| npm audit при scope с владельцами или внутреннем пространстве имён | Запрос, из которого NORA не может вырезать эти имена, получает 4xx с причиной, а не пересылается | Используйте npm 7+ (bulk-аудит) или yarn npm audit |
| Circuit breaker для Docker, PyPI, npm | Свой breaker на каждый upstream; метка метрик registry="<формат>:<url>" | Дашборды и алерты с registry="pypi" и т. п. переведите на registry=~"pypi(:.*)?" |
circuit_breaker.overrides.docker | Теперь применяется (раньше игнорировался) | Проверьте заданные значения |
| Неизвестные ключи в config.toml | Записываются в лог предупреждением с именами | При желании задайте NORA_CONFIG_STRICT=true, чтобы такие ключи отклонялись |
| Запись в локальное хранилище | Идёт через .nora-staging/ в корне хранилища; перезапуск удаляет то, что оставил упавший экземпляр | Ничего |
| Логи | Учётные данные в URL (user:pass@) маскируются | Ничего |
Остановите 1.3.4 и запустите 1.3.3 на том же хранилище. 1.3.3 отдаёт всё, что сохранила 1.3.4, а её retention и GC не видят записи, которые 1.3.4 хранит в .nora-origins/ и .nora-staging/.
С v0.8 на v0.9
Заголовок раздела «С v0.8 на v0.9»v0.9 обратно совместима по всем возможностям и хранилищу. Единственное необходимое действие — обновить переименованные переменные окружения, если вы используете какие-либо из переименованных имён, перечисленных ниже.
Что изменилось
Заголовок раздела «Что изменилось»| Возможность | Влияние | Требуемое действие |
|---|---|---|
| Изоляция пространств имён Docker | В структуру хранилища добавляется префикс пространства имён | Нет — ленивая миграция выполняется автоматически |
| Circuit breaker | Новая возможность, отключена по умолчанию | Нет |
| TTL метаданных Docker + stale-while-error | Новая возможность, включается вручную | Нет |
| Потоковый read_timeout | Новая возможность, включается вручную | Нет |
| Горячая перезагрузка курирования по SIGHUP | Новая возможность | Нет |
| Бинарный файл linux/arm64 | Новая платформа | Нет |
Миграция пространств имён Docker
Заголовок раздела «Миграция пространств имён Docker»В v0.9 вводятся префиксы пространств имён для каждого вышестоящего источника в ключах хранилища Docker, чтобы изолировать данные из разных вышестоящих реестров.
Старая структура (v0.8):
docker/{name}/blobs/{digest}docker/{name}/manifests/{ref}.jsonНовая структура (v0.9):
docker/{namespace}/{name}/blobs/{digest}docker/{namespace}/{name}/manifests/{ref}.jsonПространство имён определяется по URL вышестоящего источника (например, registry-1.docker.io превращается в docker.io) или задаётся явно через поле namespace в [[docker.upstreams]].
Миграция автоматическая и ленивая:
- При обработке запроса NORA сначала проверяет путь с пространством имён.
- Если он не найден, происходит откат к устаревшему плоскому пути.
- Никакой фоновой миграции при запуске не выполняется.
- Существующие закэшированные данные продолжают отдаваться без перебоев.
Шаги обновления
Заголовок раздела «Шаги обновления»- Остановите работающий экземпляр NORA.
- Замените бинарный файл или обновите образ контейнера до v0.9.
- Запустите NORA с вашей существующей конфигурацией.
# Binary upgradecurl -fsSL https://github.com/getnora-io/nora/releases/latest/download/nora-linux-amd64 -o norachmod +x nora./noraСкрипты миграции данных не требуются.
Чтобы откатиться с v0.9 на v0.8:
- Остановите экземпляр v0.9.
- Замените бинарный файл или образ на v0.8.
- Запустите NORA.
Новые переменные окружения
Заголовок раздела «Новые переменные окружения»В v0.9 добавлены следующие необязательные переменные (все отключены или неактивны по умолчанию):
| Переменная | По умолчанию | Описание |
|---|---|---|
NORA_CB_ENABLED | false | Включить circuit breaker |
NORA_CB_THRESHOLD | 5 | Число сбоев до размыкания |
NORA_CB_RESET_TIMEOUT | 30 | Секунд до пробного запроса |
NORA_DOCKER_READ_TIMEOUT | 60 | Таймаут чтения одного фрагмента (секунды) |
NORA_DOCKER_METADATA_TTL | -1 | TTL кэша метаданных в секундах |
NORA_DOCKER_SERVE_STALE | true | Отдавать закэшированные манифесты, когда вышестоящий источник недоступен |
Полный справочник см. в Справочнике по конфигурации.
Переименованные переменные окружения
Заголовок раздела «Переименованные переменные окружения»В v0.9 несколько имён переменных сокращены в соответствии с соглашением NORA_{SECTION}_{FIELD} (менее 30 символов):
| Старое имя | Новое имя |
|---|---|
NORA_TF_ENABLED | NORA_TF_ENABLED |
NORA_TF_PROXY | NORA_TF_PROXY |
NORA_TF_PROXY_TIMEOUT | NORA_TF_PROXY_TIMEOUT |
NORA_TF_METADATA_TTL | NORA_TF_METADATA_TTL |
NORA_TF_PROXY_TIMEOUT_DL | NORA_TF_PROXY_TIMEOUT_DL |
NORA_CONAN_PROXY_TIMEOUT_DL | NORA_CONAN_PROXY_TIMEOUT_DL |
NORA_CURATION_INTERNAL_NS | NORA_CURATION_INTERNAL_NS |
Старые имена больше не распознаются. Обновите свою конфигурацию, если вы используете какие-либо из них.
Смотрите также
Заголовок раздела «Смотрите также»- Справочник по конфигурации — полный справочник по переменным окружения
- Circuit Breaker — новое в v0.9
- Проксирование Docker — подробности об изоляции пространств имён