Работа с Debian / APT

CodeScoring.Save реализует APT-совместимый репозиторий с префиксом /deb/<project>/<repository>/. Совместим со стандартными клиентами apt, apt-get и aptitude на Debian, Ubuntu и производных дистрибутивах.

Proxy-репозиторий

curl -X POST https://save.example.com/api/v1/repos \
  -H "Content-Type: application/json" \
  -u "<username>:<password>" \
  -d '{
    "project": "infra",
    "name": "debian-proxy",
    "format": "deb",
    "repository_type": "proxy",
    "remote_url": "https://deb.debian.org/debian",
    "cache_ttl": 3600
  }'
Proxy отдаёт индексы upstream как есть

Proxy-репозиторий не генерирует собственные индексы — файлы InRelease, Release, Release.gpg и Packages* проксируются с upstream побайтно, чтобы подписи и контрольные суммы оставались валидными. Пакеты из pool/ кэшируются как неизменяемые артефакты; метаданные ревалидируются по истечении cache_ttl. Если upstream недоступен, Save отдаёт последнюю закэшированную копию метаданных. Загрузка пакетов в proxy-репозиторий запрещена — он read-only.

Hosted-репозиторий

curl -X POST https://save.example.com/api/v1/repos \
  -H "Content-Type: application/json" \
  -u "<username>:<password>" \
  -d '{
    "project": "infra",
    "name": "deb-hosted",
    "format": "deb",
    "repository_type": "hosted"
  }'

При создании hosted-репозитория Save сразу публикует пустой suite stable (компонент main), поэтому apt-get update работает ещё до загрузки первого пакета. Индексы (Packages, Packages.gz, Release) перегенерируются автоматически после каждой загрузки или удаления пакета.

URL-схема

https://save.example.com/cs-save/deb/<project>/<repository>/dists/<suite>/...   # индексы
https://save.example.com/cs-save/deb/<project>/<repository>/pool/<component>/...  # пакеты
https://save.example.com/cs-save/deb/<project>/<repository>/repository.key      # публичный GPG-ключ

Настройка клиента

apt (подписанный репозиторий)

Если на сервере включена подпись метаданных (METADATA_SIGNING_ENABLED), Save публикует InRelease и Release.gpg, а публичный ключ доступен по адресу <repo>/repository.key:

# Установка публичного ключа репозитория
curl -u "<username>:<password>" \
  -o /etc/apt/keyrings/save.asc \
  https://save.example.com/deb/<project>/deb-hosted/repository.key

# Источник APT c проверкой подписи
echo 'deb [signed-by=/etc/apt/keyrings/save.asc] https://save.example.com/cs-save/deb/<project>/deb-hosted stable main' \
  > /etc/apt/sources.list.d/save.list

# Credentials — через auth.conf.d (формат netrc)
cat > /etc/apt/auth.conf.d/save.conf << EOF
machine save.example.com
login <username>
password <password>
EOF
chmod 600 /etc/apt/auth.conf.d/save.conf

apt-get update
apt-get install <package>

apt (без подписи)

Если подпись метаданных не включена, используйте [trusted=yes]:

echo 'deb [trusted=yes] https://save.example.com/cs-save/deb/<project>/deb-hosted stable main' \
  > /etc/apt/sources.list.d/save.list
apt и порядок запросов

apt сначала запрашивает InRelease и при 404 откатывается на пару Release + Release.gpg. Это штатное поведение: 404 на InRelease у неподписанного репозитория — не ошибка.

Robot-аккаунты в CI

Для CI/CD используйте robot-аккаунт: login = sa$<robot-name>, password = <api-key> в /etc/apt/auth.conf.d/save.conf. Подробнее — в общем разделе Аутентификация.

Публикация пакетов (hosted)

Загрузка выполняется PUT-запросом в канонический pool-путь. Suite и компонент передаются query-параметрами (по умолчанию — stable и main):

curl -u "<username>:<password>" \
  -T mypackage_1.0.0_amd64.deb \
  "https://save.example.com/cs-save/deb/<project>/deb-hosted/pool/main/m/mypackage/mypackage_1.0.0_amd64.deb?suite=stable&component=main"

Имя файла должно соответствовать схеме <name>_<version>_<arch>.deb. Save валидирует контрольную структуру пакета и приводит путь к каноническому виду pool/<component>/<первая-буква>/<имя>/<имя>_<версия>_<арх>.deb — фактический путь возвращается в ответе.

Альтернатива — multipart POST на корень репозитория:

curl -u "<username>:<password>" \
  -F "file=@mypackage_1.0.0_amd64.deb" \
  -F "suite=stable" \
  -F "component=main" \
  https://save.example.com/cs-save/deb/<project>/deb-hosted

Пакеты с архитектурой all автоматически публикуются во все конкретные архитектуры suite (fan-out); псевдоархитектура all не публикуется в Release отдельной строкой.

Принудительная перегенерация индексов

curl -u "<username>:<password>" \
  -X POST https://save.example.com/cs-save/deb/<project>/deb-hosted/rebuild-index

Миграция URL репозитория

Сценарий использования: миграция APT-репозитория с Nexus / Artifactory на CodeScoring.Save.

ИсточникСтрока sources.list до миграцииСтрока sources.list после миграции
Nexusdeb https://nexus.host.ru/repository/apt-hosted stable maindeb https://save.example.com/cs-save/deb/<project>/deb-hosted stable main
Artifactorydeb https://jfrog.host.ru/artifactory/deb-local stable maindeb https://save.example.com/cs-save/deb/<project>/deb-hosted stable main
Официальный репозиторийdeb https://deb.debian.org/debian bookworm maindeb https://save.example.com/cs-save/deb/<project>/debian-proxy bookworm main

Suite и компоненты сохраняются без изменений; для proxy-репозитория Save отдаёт подписи upstream как есть, поэтому существующие signed-by-ключи (например, ключ Debian) продолжают работать.

Устранение неполадок

Проверка Release

curl -u "<username>:<password>" \
  https://save.example.com/cs-save/deb/<project>/deb-hosted/dists/stable/Release

В ответе — поля Suite, Components, Architectures и секция SHA256 со ссылками на Packages-индексы.

Проверка индекса Packages

curl -u "<username>:<password>" \
  https://save.example.com/cs-save/deb/<project>/deb-hosted/dists/stable/main/binary-amd64/Packages

Если пакет загружен, но отсутствует в индексе — подождите несколько секунд (индексация асинхронная) либо выполните rebuild-index.

Проверка публичного ключа

curl -u "<username>:<password>" \
  https://save.example.com/cs-save/deb/<project>/deb-hosted/repository.key
# Ожидается: -----BEGIN PGP PUBLIC KEY BLOCK-----
# 404 означает, что подпись метаданных не включена на сервере

Состояние сервиса

curl https://save.example.com/health

Аудит по репозиторию

curl -u "<username>:<password>" \
  "https://save.example.com/api/v1/admin/audit?resource_type=repository&q=deb-hosted&limit=50"
Страница была полезна?