Работа с RPM (dnf / yum)
CodeScoring.Save работает как обычный rpm-md-репозиторий — тот, у которого в корне лежит repodata/repomd.xml. Его понимают dnf и yum на RHEL, Rocky Linux, AlmaLinux, Fedora, CentOS и других дистрибутивах семейства. Можно создать:
- proxy-репозиторий — кэширующее зеркало репозитория дистрибутива или стороннего репозитория (EPEL, репозитории вендоров, Nexus, Artifactory, другой Save);
- hosted-репозиторий — хранилище для собственных пакетов компании.
createrepoзапускать не нужно: метаданные Save собирает сам после каждой загрузки.
Создание репозитория в веб-интерфейсе
- В боковом меню выберите Projects и откройте проект.
- Нажмите Create repository.
- Заполните общие поля (подробнее — в разделе Управление репозиториями):
- Name — название репозитория, например
Rocky 9 BaseOS. Если в названии есть формат и тип (например,my RPM proxy), ссылка Click here to automatically fill the format (rpm) and type (proxy) based on the name под полем сама заполнит Format, Type и Proxy URL; - Key — идентификатор в URL, например
rocky9-baseos. Если оставить пустым, сгенерируется из названия. Изменить после создания нельзя; - Description и Color — по желанию.
- Name — название репозитория, например
- В поле Format выберите RPM.
- В поле Type выберите Proxy или Hosted.
Поля proxy-репозитория
-
Proxy URL —
baseurlрепозитория, который нужно проксировать: каталог, внутри которого лежитrepodata/repomd.xml. Ссылка автозаполнения под Name подставляет сюда пример — BaseOS для Rocky Linux 9; иначе поле пустое.Готовый адрес удобно взять с машины, где этот репозиторий уже подключён:
dnf repolist -vпоказывает его в строкеRepo-baseurl. Учтите:- в
Proxy URLпеременные$releaseverи$basearchне подставляются. Для каждого сочетания версии и архитектуры (и для каждого репозитория: BaseOS, AppStream, EPEL…) создайте отдельный proxy-репозиторий; - нужен конкретный
baseurl: адресаmirrorlistиmetalinkне подойдут; - репозитории, которые требуют клиентский TLS-сертификат (например, CDN Red Hat по подписке), проксировать нельзя.
- в
-
Cache TTL, seconds — как часто Save перепроверяет метаданные (
repomd.xml) у upstream. Пакеты не меняются и кэшируются навсегда. Для репозиториев дистрибутивов подойдёт3600(час). -
Authentication — как Save авторизуется в upstream. Для публичных зеркал оставьте
none.Пароль и токен после сохранения не показываются ни в интерфейсе, ни в API: на форме редактирования сохранённое значение отображается как
********— оставьте его, чтобы не менять. Учётные данные Save отправляет только на хост из Proxy URL (подробнее — Доступ proxy-репозиториев к upstream).
Поля hosted-репозитория
- RPM metadata folder depth — глубина корня индексации. Оставьте пустым (или
0), если нужен одинrepodata/на весь репозиторий — так подходит в большинстве случаев. Если в одном репозитории будут пакеты для нескольких дистрибутивов, см. Несколько корней индексации.
- При необходимости привяжите политики очистки в блоке Cleanup policy: перенесите нужные из списка Available в Applied.
- Нажмите Create repository.
На странице созданного репозитория кнопка со значком «звено цепи» показывает готовый .repo-файл и команды именно для этого репозитория.
Те же репозитории можно создать запросом к API. В format указывается rpm, учётные данные upstream передаются в блоке auth, глубина корня — в settings.rpm_root_depth:
Для proxy с авторизацией добавьте "auth": {"auth_type": "basic", "username": "<upstream-user>", "password": "<upstream-password>"}. Для hosted с несколькими корнями — "settings": {"rpm_root_depth": 2}.
Подключение dnf / yum
Адрес репозитория в Save имеет вид https://save.example.com/cs-save/rpm/<project>/<repository> — это и есть baseurl для клиента. Создайте файл /etc/yum.repos.d/codescoring.repo:
Чтобы все пакеты шли через Save, отключите исходные репозитории дистрибутива (enabled=0 в их .repo-файлах) или замените в них baseurl / mirrorlist на адрес Save. Описание всех опций .repo-файла — в документации dnf.
Для CI/CD можно использовать robot-аккаунт: username = sa$<robot-login>, password = <api-key> в .repo-файле. Структура файла не меняется — отличаются только значения. Подробнее — в общем разделе Аутентификация.
Проверка подписей
-
Proxy. Save отдаёт пакеты и метаданные upstream без изменений, включая
repomd.xml.asc. Поэтому ключи дистрибутива продолжают работать как раньше:gpgcheck=1сgpgkeyдистрибутива, а если upstream подписывает метаданные — иrepo_gpgcheck=1. -
Hosted. Save не подписывает и не изменяет пакеты. Чтобы использовать
gpgcheck=1, подпишите пакеты до загрузки (rpmsign --addsign) и раздайте свой публичный ключ клиентам. -
Подпись метаданных hosted-репозитория. Если на сервере включена подпись метаданных (
METADATA_SIGNING_ENABLED), Save подписываетrepomd.xmlсвоим ключом (repodata/repomd.xml.asc). Публичный ключ доступен по адресу<baseurl>/repository.key. Включите проверку так:repo_gpgcheckпроверяет подпись метаданных,gpgcheck— подпись самих пакетов. Это разные ключи: если пакеты подписаны вашим ключом, перечислите вgpgkeyоба через пробел.
Публикация пакетов в hosted-репозиторий
У dnf нет команды публикации: как и в Nexus или Artifactory, пакет загружается обычным HTTP-запросом PUT на путь, где он будет лежать в репозитории. Параметр -T (--upload-file) в curl отправляет файл именно так:
После загрузки Save в течение нескольких секунд пересобирает repodata/ — createrepo_c запускать не нужно. На клиенте выполните dnf makecache --refresh, чтобы получить новые метаданные сразу.
Что проверяет Save при загрузке:
- имя файла — в формате NVRA
<name>-<version>-<release>.<arch>.rpm, и оно должно совпадать с заголовком пакета. Правильное имя для файла можно получить так:rpm -qp --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}.rpm\n' <file>.rpm; - путь
Packages/...(как в примере выше) или просто имя файла в корне Save приводит к стандартному видуPackages/<первая буква>/<файл>. Любой другой каталог сохраняется как есть — это нужно для нескольких корней индексации; - повторная загрузка того же пакета вернёт
409.
Удалить пакет можно в веб-интерфейсе (Delete artifact на странице репозитория) — метаданные пересоберутся автоматически.
Если метаданные нужно пересобрать вручную (например, после восстановления из резервной копии):
Пересборка также удаляет старые файлы repodata/, на которые больше не ссылается repomd.xml.
Несколько корней индексации
По умолчанию у hosted-репозитория один repodata/ в корне. Если в одном репозитории хранятся пакеты для разных дистрибутивов или версий, удобнее, чтобы у каждого был свой repodata/. Для этого задайте RPM metadata folder depth — аналог yumRootDepth в Artifactory и Repodata Depth в Nexus.
Глубина — это число первых каталогов в пути пакета, которые образуют корень. Например, при глубине 2:
У каждого корня свой независимый repodata/: пакеты из centos/7 не попадают в индекс centos/8.
0(по умолчанию) — одинrepodata/на весь репозиторий.1–10— отдельныйrepodata/для каждого корня этой глубины.- Настройка есть только у hosted-репозиториев: proxy отдаёт метаданные upstream как есть.
Пакет загружается в каталог своего корня:
Если глубина больше 0, путь пакета должен содержать не меньше каталогов, чем задано глубиной, и не должен начинаться с Packages/. Иначе Save вернёт 400 с подсказкой, куда загрузить пакет. Artifactory в таком случае сохраняет пакет без индексации, а Save отклоняет загрузку специально: иначе пакет «загружен», но dnf его не видит. Один и тот же пакет можно загрузить в разные корни.
Глубину можно изменить и у существующего репозитория на форме Edit repository. Save переиндексирует репозиторий в фоне: создаст repodata/ для новых корней и удалит метаданные старой схемы. Пока переиндексация не завершилась, новые repomd.xml могут быть ещё недоступны.
Если включена подпись метаданных, repomd.xml.asc публикуется в каждом корне, а ключ один на весь репозиторий: он доступен и по адресу <repo>/repository.key, и по адресу <корень>/repository.key. rebuild-index пересобирает метаданные всех корней.
Миграция URL репозитория
Сценарий использования: миграция RPM-репозитория с Nexus / Artifactory на CodeScoring.Save.
Параметры аутентификации (username / password) в .repo-файле сохраняются без изменений. Если в Nexus или Artifactory использовалась глубина repodata (Repodata Depth / yumRootDepth), задайте такое же значение в RPM metadata folder depth и загрузите пакеты по тем же путям — baseurl корней сохранятся.
Устранение неполадок
Что делает dnf
С ключом -v dnf показывает адреса, к которым обращается, и причину ошибки. 401 означает, что не подошли username / password в .repo-файле.
Проверка repomd.xml
В ответе — XML с разделами primary, filelists, other. 404 у hosted-репозитория с глубиной больше 0 — ожидаемо: метаданные лежат в каталогах корней (<корень>/repodata/repomd.xml).
Пакет загружен, но dnf его не видит
Подождите несколько секунд (метаданные собираются асинхронно), выполните dnf makecache --refresh или rebuild-index. Проверить, есть ли пакет в индексе:
